import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/auth/model/project_model.dart';
import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart';
import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/device_report_model.dart';
import 'package:syncrow_app/features/devices/model/four_scene_model.dart';
import 'package:syncrow_app/features/devices/model/four_scene_switch_model.dart';
import 'package:syncrow_app/features/devices/model/device_info_model.dart';
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
import 'package:syncrow_app/features/scene/model/scenes_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/services/api/scene_api.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';

class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> {
  final String fourSceneId;
  FourSceneBloc({
    required this.fourSceneId,
  }) : super(const FourSceneState()) {
    on<FourSceneInitial>(_fetchDeviceStatus);
    on<FourSceneInitialInfo>(fetchDeviceInfo);
    on<ToggleNotificationEvent>(_toggleNotification);
    on<ChangeSwitchStatusEvent>(changeSwitchStatus);
    on<LoadScenes>(_onLoadScenes);
    on<SearchScenesEvent>(searchScene);
    on<SelectOptionEvent>(_onOptionSelected);
    on<FetchDeviceScene>(_fetchDeviceScene);
    on<FourSceneSwitchInitial>(_fetchFourSceneSwitches);
    on<AssignDeviceScene>(assignScene);
    on<GetSceneBySwitchName>(getSceneByName);
    on<SelectSceneEvent>(_selectScene);
    on<ToggleEnableAlarmEvent>(_toggleLowBattery);
  }

  final TextEditingController nameController =
      TextEditingController(text: deviceName);
  bool isSaving = false;
  bool editName = false;
  final FocusNode focusNode = FocusNode();
  bool closingReminder = false;
  bool waterAlarm = false;
  static String deviceName = '';
  static String selectedRoomId = '';
  bool selecedScene = false;
  bool enableAlarm = false;
  List<FourSceneSwitchModel> fourScene = [];

  String _selectedOption = '';
  bool _hasSelectionChanged = false;

  FourSceneModelState deviceStatus = FourSceneModelState(
      scene_1: '',
      scene_2: '',
      scene_3: '',
      scene_4: '',
      scene_id_group_id: '',
      switch_backlight: false);

  DeviceInfoModel deviceInfo = DeviceInfoModel(
    activeTime: 0,
    category: "",
    categoryName: "",
    createTime: 0,
    gatewayId: "",
    icon: "",
    ip: "",
    lat: "",
    localKey: "",
    lon: "",
    model: "",
    name: "",
    nodeId: "",
    online: false,
    ownerId: "",
    productName: "",
    sub: false,
    timeZone: "",
    updateTime: 0,
    uuid: "",
    productUuid: "",
    productType: "",
    permissionType: "",
    macAddress: "",
    subspace: Subspace(
      uuid: "",
      createdAt: "",
      updatedAt: "",
      subspaceName: "",
    ),
  );

//============================ get Scene and assign scene =======================
  String selectedFormApiSceneId = '';
  String selectedSceneId = '';

  _selectScene(SelectSceneEvent event, Emitter<FourSceneState> emit) {
    emit(FourSceneLoadingState());
    if (event.isSelected == false) {
      selectedSceneId = '';
      selectedFormApiSceneId = '';
      emit(SceneSelectionUpdatedState(selectedSceneId: selectedSceneId));
    } else {
      selectedSceneId = event.selectedSceneId;
    }
    emit(SceneSelectionUpdatedState(selectedSceneId: selectedSceneId));
  }

  void getSceneByName(
      GetSceneBySwitchName event, Emitter<FourSceneState> emit) async {
    // emit(FourSceneLoadingState());
    try {
      final response = await DevicesAPI.getSceneBySwitchName(
          deviceId: fourSceneId, switchName: event.switchName);
      selectedFormApiSceneId = response['scene']['uuid'];
      emit(UpdateState(device: deviceStatus));
    } catch (e) {
      emit(FourSceneFailedState(errorMessage: e.toString()));
    }
  }

  void _onOptionSelected(
      SelectOptionEvent event, Emitter<FourSceneState> emit) {
    emit(FourSceneLoadingState());
    _selectedOption = event.selectedOption;
    _hasSelectionChanged = true;
    emit(OptionSelectedState(
        selectedOption: _selectedOption,
        hasSelectionChanged: _hasSelectionChanged));
  }

  void _fetchFourSceneSwitches(
      FourSceneSwitchInitial event, Emitter<FourSceneState> emit) async {
    emit(FourSceneLoadingState());
    try {
      var response = await DevicesAPI.getDeviceSceneInfo(fourSceneId);
      Map<String, String> sceneTitles = {
        "scene_1": '',
        "scene_2": '',
        "scene_3": '',
        "scene_4": '',
      };
      for (var item in response) {
        if (item["switchName"] != null) {
          sceneTitles[item["switchName"]] = item["scene"]["name"] ?? '';
        }
      }
      FourSceneModelState deviceStatus = FourSceneModelState(
        scene_1: sceneTitles["scene_1"] ?? '',
        scene_2: sceneTitles["scene_2"] ?? '',
        scene_3: sceneTitles["scene_3"] ?? '',
        scene_4: sceneTitles["scene_4"] ?? '',
        scene_id_group_id: '',
        switch_backlight: '',
      );
      emit(UpdateState(device: deviceStatus));
    } catch (e) {
      emit(FourSceneFailedState(errorMessage: e.toString()));
      return;
    }
  }

  void assignScene(
      AssignDeviceScene event, Emitter<FourSceneState> emit) async {
    emit(FourSceneLoadingState());
    try {
      if (event.sceneUuid == '') {
        final response = await DevicesAPI.unAssignScenesDevice(
            deviceUuid: fourSceneId, switchName: event.switchName);
      } else {
        final response = await DevicesAPI.postDeviceSceneInfo(
            deviceId: fourSceneId,
            sceneUuid: event.sceneUuid,
            spaceUuid: event.unit!.id,
            switchName: event.switchName);
      }

      emit(SaveSelectionSuccessState());
      CustomSnackBar.displaySnackBar('Save Successfully');
    } catch (e) {
      emit(FourSceneFailedState(errorMessage: e.toString()));
    }
  }

  void _fetchDeviceScene(
      FetchDeviceScene event, Emitter<FourSceneState> emit) async {
    emit(FourSceneLoadingState());
    try {
      var response = await DevicesAPI.getDeviceStatus(fourSceneId);
      List<StatusModel> statusModelList = [];
      for (var status in response['status']) {
        statusModelList.add(StatusModel.fromJson(status));
      }
      deviceStatus = FourSceneModelState.fromJson(
        statusModelList,
      );
      emit(UpdateState(device: deviceStatus));
      Future.delayed(const Duration(milliseconds: 500));
    } catch (e) {
      emit(FourSceneFailedState(errorMessage: e.toString()));
      return;
    }
  }

//=====================  fetch Device Status and info =======================

  void _toggleLowBattery(
      ToggleEnableAlarmEvent event, Emitter<FourSceneState> emit) async {
    emit(LoadingNewSate(device: deviceStatus));
    try {
      enableAlarm = event.isLowBatteryEnabled;
      emit(UpdateState(device: deviceStatus));
    } catch (e) {
      emit(FourSceneFailedState(errorMessage: e.toString()));
    }
  }

  void _fetchDeviceStatus(
      FourSceneInitial event, Emitter<FourSceneState> emit) async {
    emit(FourSceneLoadingState());
    try {
      var response = await DevicesAPI.getDeviceStatus(fourSceneId);
      List<StatusModel> statusModelList = [];
      for (var status in response['status']) {
        statusModelList.add(StatusModel.fromJson(status));
      }
      deviceStatus = FourSceneModelState.fromJson(
        statusModelList,
      );
      // _listenToChanges();
      add(const FourSceneSwitchInitial());
    } catch (e) {
      emit(FourSceneFailedState(errorMessage: e.toString()));
      return;
    }
  }

  Future fetchDeviceInfo(
      FourSceneInitialInfo event, Emitter<FourSceneState> emit) async {
    try {
      emit(FourSceneLoadingState());
      var response = await DevicesAPI.getDeviceInfo(fourSceneId);
      deviceInfo = DeviceInfoModel.fromJson(response);
      deviceName = deviceInfo.name;
      emit(LoadingDeviceInfo(deviceInfo: deviceInfo));
    } catch (e) {
      emit(FourSceneFailedState(errorMessage: e.toString()));
    }
  }

//============================ assign Device  ==================================
//////////////////////////////////////////////////////////////////////////////

  void _toggleNotification(
      ToggleNotificationEvent event, Emitter<FourSceneState> emit) async {
    emit(LoadingNewSate(device: deviceStatus));
    try {
      enableAlarm = event.isClosingEnabled;
      emit(UpdateState(device: deviceStatus));
    } catch (e) {
      emit(FourSceneFailedState(errorMessage: e.toString()));
    }
  }

  DeviceReport recordGroups =
      DeviceReport(startTime: '0', endTime: '0', data: []);

  List<DeviceModel> allDevices = [];
  List<SubSpaceModel> roomsList = [];
  bool switchStatus = true;
  Future<void> changeSwitchStatus(
      ChangeSwitchStatusEvent event, Emitter<FourSceneState> emit) async {
    try {
      emit(FourSceneLoadingState());
      switchStatus = deviceStatus.switch_backlight;
      switchStatus = !switchStatus;
      final response = await DevicesAPI.controlDevice(
          DeviceControlModel(
              deviceId: fourSceneId,
              code: 'switch_backlight',
              value: switchStatus),
          fourSceneId);
      deviceStatus.switch_backlight = switchStatus;
      Future.delayed(const Duration(milliseconds: 200), () {
        add(const FourSceneSwitchInitial());
      });
      Future.delayed(const Duration(milliseconds: 200), () {
        emit(ChangeSwitchState(isEnable: switchStatus));
        emit(UpdateState(device: deviceStatus));
      });
    } catch (_) {
      add(const FourSceneInitial());
    }
  }

  Future<void> _onLoadScenes(
      LoadScenes event, Emitter<FourSceneState> emit) async {
    emit(FourSceneLoadingState());
    try {
      Project? project = HomeCubit.getInstance().project;

      if (event.unitId.isNotEmpty) {
        allScenes = await SceneApi.getScenesByUnitId(
            event.unitId, event.unit.community.uuid, project?.uuid ?? TempConst.projectIdDev,
            showInDevice: event.showInDevice);

        filteredScenes = allScenes;
        emit(SceneLoaded(allScenes));
      } else {
        emit(const FourSceneFailedState(errorMessage: 'Unit ID is empty'));
      }
    } catch (e) {
      emit(const FourSceneFailedState(errorMessage: 'Something went wrong'));
    }
  }

  List<ScenesModel> allScenes = [];
  List<ScenesModel> filteredScenes = [];

  void searchScene(SearchScenesEvent event, Emitter<FourSceneState> emit) {
    emit(FourSceneLoadingState());
    filteredScenes = event.query.isEmpty
        ? allScenes
        : allScenes.where((scene) {
            final sceneName = scene.name?.toLowerCase() ?? '';
            return sceneName.contains(event.query.toLowerCase());
          }).toList();
    emit(SearchResultsState());
  }
  // Real-time database
  // Timer? _timer;
  // _listenToChanges() {
  //   try {
  //     DatabaseReference ref =
  //         FirebaseDatabase.instance.ref('device-status/$fourSceneId');
  //     Stream<DatabaseEvent> stream = ref.onValue;

  //     stream.listen((DatabaseEvent event) async {
  //       if (_timer != null) {
  //         await Future.delayed(const Duration(seconds: 2));
  //       }
  //       Map<dynamic, dynamic> usersMap =
  //           event.snapshot.value as Map<dynamic, dynamic>;
  //       List<StatusModel> statusList = [];

  //       usersMap['status'].forEach((element) {
  //         statusList.add(StatusModel(code: element['code'], value: true));
  //       });

  //       deviceStatus = FourSceneModelState.fromJson(statusList);
  //       // if (!isClosed) {
  //       //   add(
  //       //     DoorSensorSwitch(switchD: deviceStatus.doorContactState),
  //       //   );
  //       // }
  //     });
  //   } catch (_) {}
  // }
}
