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/model/device_model.dart';
import 'package:syncrow_app/features/menu/bloc/manage_unit_bloc/manage_unit_event.dart';
import 'package:syncrow_app/features/menu/bloc/manage_unit_bloc/manage_unit_state.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/services/api/home_creation_api.dart';
import 'package:syncrow_app/services/api/home_management_api.dart';
import 'package:syncrow_app/services/api/spaces_api.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';

class ManageUnitBloc extends Bloc<ManageUnitEvent, ManageUnitState> {
  List<DeviceModel> allDevices = [];
  String unitName = '';

  ManageUnitBloc() : super(InitialState()) {
    on<FetchRoomsEvent>(_fetchRoomsAndDevices);
    on<FetchDevicesByRoomIdEvent>(_fetchDevicesByRoomId);
    on<AssignRoomEvent>(_assignDevice);
    on<AddNewRoom>(_addNewRoom);
    on<UnassignRoomEvent>(_unassignDevice);
  }

  void _fetchRoomsAndDevices(
      FetchRoomsEvent event, Emitter<ManageUnitState> emit) async {
    try {
      emit(LoadingState());
      Project? project = HomeCubit.getInstance().project;

      final roomsList = await SpacesAPI.getSubSpaceBySpaceId(
          event.unit.community.uuid,
          event.unit.id,
          project?.uuid ?? TempConst.projectIdDev);
      emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
    } catch (e) {
      emit(const ErrorState(message: 'Something went wrong'));
      return;
    }
  }

  void _fetchDevicesByRoomId(
      FetchDevicesByRoomIdEvent event, Emitter<ManageUnitState> emit) async {
    try {
      Map<String, bool> roomDevicesId = {};
      Project? project = HomeCubit.getInstance().project;

      emit(LoadingState());
      final devicesList = await DevicesAPI.getDevicesByRoomId(
          communityUuid: event.unit.community.uuid,
          spaceUuid: event.unit.id,
          roomId: event.roomId,
          projectId: project?.uuid ?? TempConst.projectIdDev);
      allDevices = await HomeManagementAPI.fetchDevices(
          project?.uuid ?? TempConst.projectIdDev);

      List<String> allDevicesIds = [];

      allDevices.forEach((element) {
        allDevicesIds.add(element.uuid!);
      });

      devicesList.forEach((e) {
        if (allDevicesIds.contains(e.uuid!)) {
          roomDevicesId[e.uuid!] = true;
        } else {
          roomDevicesId[e.uuid!] = false;
        }
      });
      emit(FetchDeviceByRoomIdState(
          roomDevices: devicesList,
          allDevices: allDevices,
          roomDevicesId: roomDevicesId,
          roomId: event.roomId));
    } catch (e) {
      emit(const ErrorState(message: 'Something went wrong'));
      return;
    }
  }

  void _assignDevice(
      AssignRoomEvent event, Emitter<ManageUnitState> emit) async {
    try {
      Map<String, bool> roomDevicesId = {};
      Project? project = HomeCubit.getInstance().project;

      emit(LoadingState());

      await HomeManagementAPI.assignDeviceToRoom(
          event.unit.community.uuid,
          event.unit.id,
          event.roomId,
          event.deviceId,
          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!);
      });

      devicesList.forEach((e) {
        if (allDevicesIds.contains(e.uuid!)) {
          roomDevicesId[e.uuid!] = true;
        } else {
          roomDevicesId[e.uuid!] = false;
        }
      });
      emit(FetchDeviceByRoomIdState(
          roomDevices: devicesList,
          allDevices: allDevices,
          roomDevicesId: roomDevicesId,
          roomId: event.roomId));
    } catch (e) {
      emit(const ErrorState(message: 'Something went wrong'));
      return;
    }
  }

  void _unassignDevice(
      UnassignRoomEvent event, Emitter<ManageUnitState> emit) async {
    try {
      Map<String, bool> roomDevicesId = {};
      Project? project = HomeCubit.getInstance().project;

      emit(LoadingState());

      await HomeManagementAPI.unAssignDeviceToRoom(
          event.unit.community.uuid,
          event.unit.id,
          event.roomId,
          event.deviceId,
          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!);
      });

      devicesList.forEach((e) {
        if (allDevicesIds.contains(e.uuid!)) {
          roomDevicesId[e.uuid!] = true;
        } else {
          roomDevicesId[e.uuid!] = false;
        }
      });
      emit(FetchDeviceByRoomIdState(
          roomDevices: devicesList,
          allDevices: allDevices,
          roomDevicesId: roomDevicesId,
          roomId: event.roomId));
    } catch (e) {
      emit(const ErrorState(message: 'Something went wrong'));
      return;
    }
  }

  _addNewRoom(AddNewRoom event, Emitter<ManageUnitState> emit) async {
    Map<String, String> body = {'subspaceName': event.roomName};
    try {
      emit(LoadingState());
      Project? project = HomeCubit.getInstance().project;

      final response = await HomeCreation.createRoom(
          communityId: event.unit.community.uuid,
          spaceId: event.unit.id,
          body: body,
          projectId: project?.uuid ?? TempConst.projectIdDev);
      if (response['data']['uuid'] != '') {
        final roomsList = await SpacesAPI.getSubSpaceBySpaceId(
            event.unit.community.uuid,
            event.unit.id,
            project?.uuid ?? TempConst.projectIdDev);
        allDevices = await HomeManagementAPI.fetchDevicesByUserId();
        emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
        await HomeCubit.getInstance().fetchUnitsByUserId();
      } else {
        emit(const ErrorState(message: 'Something went wrong'));
      }
    } catch (_) {
      emit(const ErrorState(message: 'Something went wrong'));
      return;
    }
  }
}
