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/6_scene_switch_bloc/6_scene_event.dart';
import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_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/device_info_model.dart';
import 'package:syncrow_app/features/devices/model/six_scene_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/home_management_api.dart';
import 'package:syncrow_app/services/api/scene_api.dart';
import 'package:syncrow_app/services/api/spaces_api.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';

class SixSceneBloc extends Bloc<SixSceneEvent, SixSceneState> {
  final String sixSceneId;
  SixSceneBloc({
    required this.sixSceneId,
  }) : super(const SixSceneState()) {
    on<SixSceneInitial>(_fetchDeviceStatus);
    on<ChangeSwitchStatusEvent>(changeSwitchStatus);
    on<LoadScenes>(_onLoadScenes);
    on<SearchScenesEvent>(searchScene);
    on<SaveSelectionEvent>(_onSaveSelection);
    on<SelectOptionEvent>(_onOptionSelected);
    on<SexSceneSwitchInitial>(_fetchFourSceneSwitches);
    on<AssignDeviceScene>(assignScene);
    on<GetSceneBySwitchName>(getSceneByName);
    on<SelectSceneEvent>(_selectScene);
    on<SixSceneInitialInfo>(fetchDeviceInfo);
    on<AssignRoomEvent>(_assignDevice);
    on<FetchRoomsEvent>(_fetchRoomsAndDevices);
    on<DeleteDeviceEvent>(deleteDevice);
    on<ToggleEnableAlarmEvent>(_toggleLowBattery);
    on<UnAssignSceneEvent>(_unAssignScene);
  }

  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 = '';

  SixSceneModel deviceStatus = SixSceneModel(
      scene_1: '',
      scene_2: '',
      scene_3: '',
      scene_4: '',
      scene_5: '',
      scene_6: '',
      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: "",
    ),
  );

  bool enableAlarm = false;

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

  List<SubSpaceModel> roomsList = [];

  void _fetchRoomsAndDevices(
      FetchRoomsEvent event, Emitter<SixSceneState> emit) async {
    try {
      emit(SixSceneLoadingState());
      Project? project = HomeCubit.getInstance().project;
      roomsList = await SpacesAPI.getSubSpaceBySpaceId(
          event.unit.community.uuid, event.unit.id, project?.uuid ?? TempConst.projectIdDev);
      emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
    } catch (e) {
      emit(SixSceneFailedState(errorMessage: e.toString()));
      return;
    }
  }

  void _assignDevice(AssignRoomEvent event, Emitter<SixSceneState> emit) async {
    try {
      emit(SixSceneLoadingState());
      if (_hasSelectionChanged) {
        Project? project = HomeCubit.getInstance().project;
        await HomeManagementAPI.assignDeviceToRoom(
            event.unit.community.uuid, event.unit.id, event.roomId, sixSceneId, project?.uuid ?? TempConst.projectIdDev);
        final devicesList = await DevicesAPI.getDevicesByRoomId(
            communityUuid: event.unit.community.uuid,
            spaceUuid: event.unit.id,
            roomId: event.roomId,
            projectId: project?.uuid ?? TempConst.projectIdDev);
        List<String> allDevicesIds = [];
        allDevices.forEach((element) {
          allDevicesIds.add(element.uuid!);
        });
        await HomeCubit.getInstance().fetchUnitsByUserId();
        CustomSnackBar.displaySnackBar('Save Successfully');
        emit(SaveSelectionSuccessState());
      }
    } catch (e) {
      emit(SixSceneFailedState(errorMessage: e.toString()));
      return;
    }
  }

  void _unAssignScene(
      UnAssignSceneEvent event, Emitter<SixSceneState> emit) async {
    try {
      emit(SixSceneLoadingState());
      if (_hasSelectionChanged) {
        var response = await DevicesAPI.unAssignScenesDevice(
            deviceUuid: event.switchSceneUuid);
        CustomSnackBar.displaySnackBar('Save Successfully');
        emit(SaveSelectionSuccessState());
      }
    } catch (e) {
      emit(SixSceneFailedState(errorMessage: e.toString()));
      return;
    }
  }

  deleteDevice(DeleteDeviceEvent event, Emitter<SixSceneState> emit) async {
    try {
      emit(SixSceneLoadingState());
      var response = await DevicesAPI.resetDevise(devicesUuid: sixSceneId);
      add(const SixSceneInitialInfo());
      CustomSnackBar.displaySnackBar('Reset Successfully');
    } catch (e) {
      emit(SixSceneFailedState(errorMessage: e.toString()));
    }
  }

//============================ fitch devise info and status  =======================
/////////////////////////////////////////////////////////////////////////////////////

  Future fetchDeviceInfo(
      SixSceneInitialInfo event, Emitter<SixSceneState> emit) async {
    try {
      emit(SixSceneLoadingState());
      var response = await DevicesAPI.getDeviceInfo(sixSceneId);
      deviceInfo = DeviceInfoModel.fromJson(response);
      deviceName = deviceInfo.name;
      emit(LoadingDeviceInfo(deviceInfo: deviceInfo));
    } catch (e) {
      emit(SixSceneFailedState(errorMessage: e.toString()));
    }
  }

  void _fetchDeviceStatus(
      SixSceneInitial event, Emitter<SixSceneState> emit) async {
    emit(SixSceneLoadingState());
    try {
      var response = await DevicesAPI.getDeviceStatus(sixSceneId);
      List<StatusModel> statusModelList = [];
      for (var status in response['status']) {
        statusModelList.add(StatusModel.fromJson(status));
      }
      deviceStatus = SixSceneModel.fromJson(
        statusModelList,
      );
      add(const SexSceneSwitchInitial());
      emit(UpdateState(device: deviceStatus));
    } catch (e) {
      emit(SixSceneFailedState(errorMessage: e.toString()));
      return;
    }
  }

  //============================ assign Scene   =======================
/////////////////////////////////////////////////////////////////////////////////////

  String selectedFormApiSceneId = '';

  void getSceneByName(
      GetSceneBySwitchName event, Emitter<SixSceneState> emit) async {
    try {
      // emit(SixSceneLoadingState());

      final response = await DevicesAPI.getSceneBySwitchName(
          deviceId: sixSceneId, switchName: event.switchName);
      selectedFormApiSceneId = response['scene']['uuid'];
      emit(SuccessState());

      emit(UpdateState(device: deviceStatus));
    } catch (e) {
      emit(SixSceneFailedState(errorMessage: e.toString()));
    }
  }

  String selectedSceneId = '';


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

  List<SixSceneModel> fourScene = [];

  void _fetchFourSceneSwitches(
      SexSceneSwitchInitial event, Emitter<SixSceneState> emit) async {
    emit(SixSceneLoadingState());
    try {
      var response = await DevicesAPI.getDeviceSceneInfo(sixSceneId);

      Map<String, String> sceneTitles = {
        "scene_1": '',
        "scene_2": '',
        "scene_3": '',
        "scene_4": '',
        "scene_5": '',
        "scene_6": '',
      };
      for (var item in response) {
        if (item["switchName"] != null) {
          sceneTitles[item["switchName"]] = item["scene"]["name"] ?? '';
        }
      }
      SixSceneModel deviceStatus = SixSceneModel(
        scene_1: sceneTitles["scene_1"] ?? '',
        scene_2: sceneTitles["scene_2"] ?? '',
        scene_3: sceneTitles["scene_3"] ?? '',
        scene_4: sceneTitles["scene_4"] ?? '',
        scene_5: sceneTitles["scene_5"] ?? '',
        scene_6: sceneTitles["scene_6"] ?? '',
        scene_id_group_id: '',
        switch_backlight: '',
      );
      emit(UpdateState(device: deviceStatus));
    } catch (e) {
      emit(SixSceneFailedState(errorMessage: e.toString()));
      return;
    }
  }

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

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

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

  List<DeviceModel> allDevices = [];

  bool switchStatus = true;
  Future<void> changeSwitchStatus(
      ChangeSwitchStatusEvent event, Emitter<SixSceneState> emit) async {
    try {
      emit(SixSceneLoadingState());
      switchStatus = deviceStatus.switch_backlight;
      switchStatus = !switchStatus;
      final response = await DevicesAPI.controlDevice(
          DeviceControlModel(
              deviceId: sixSceneId,
              code: 'switch_backlight',
              value: switchStatus),
          sixSceneId);
      deviceStatus.switch_backlight = switchStatus;

      Future.delayed(const Duration(milliseconds: 250), () {
        add(const SexSceneSwitchInitial());
      });

      Future.delayed(const Duration(milliseconds: 250), () {
        emit(ChangeSwitchState(isEnable: switchStatus));
        emit(UpdateState(device: deviceStatus));
      });
    } catch (_) {
      emit(const SixSceneFailedState(errorMessage: 'Something went wrong'));
    }
  }

  Future<void> _onLoadScenes(
      LoadScenes event, Emitter<SixSceneState> emit) async {
    emit(SixSceneLoadingState());

    try {
            Project? project = HomeCubit.getInstance().project;

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

      filteredScenes = allScenes;

      emit(SceneLoaded(allScenes));
      emit(UpdateState(device: deviceStatus));
    } catch (e) {
      emit(const SixSceneFailedState(errorMessage: 'Something went wrong'));
    }

    emit(SuccessState());
  }

  bool selecedScene = false;

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

  void searchScene(SearchScenesEvent event, Emitter<SixSceneState> emit) {
    emit(SixSceneLoadingState());
    filteredScenes = event.query.isEmpty
        ? allScenes
        : allScenes.where((scene) {
            final sceneName = scene.name.toLowerCase();
            return sceneName.contains(event.query.toLowerCase());
          }).toList();
    emit(SearchResultsState());
  }

  String _selectedOption = '';
  bool _hasSelectionChanged = false;

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

  void _onSaveSelection(SaveSelectionEvent event, Emitter<SixSceneState> emit) {
    if (_hasSelectionChanged) {
      print('Save button clicked with selected option: $_selectedOption');
      _hasSelectionChanged = false;
      emit(SaveSelectionSuccessState());
    }
  }
}
