import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
import 'package:syncrow_web/services/devices_mang_api.dart';
part 'device_managment_event.dart';
part 'device_managment_state.dart';

class DeviceManagementBloc
    extends Bloc<DeviceManagementEvent, DeviceManagementState> {
  int _selectedIndex = 0;
  List<AllDevicesModel> _devices = [];
  int _onlineCount = 0;
  int _offlineCount = 0;
  int _lowBatteryCount = 0;
  List<AllDevicesModel> _selectedDevices = [];
  List<AllDevicesModel> _filteredDevices = [];
  String productName = '';

  DeviceManagementBloc() : super(DeviceManagementInitial()) {
    on<FetchDevices>(_onFetchDevices);
    on<FilterDevices>(_onFilterDevices);
    on<SelectedFilterChanged>(_onSelectedFilterChanged);
    on<SearchDevices>(_onSearchDevices);
    on<SelectDevice>(_onSelectDevice);
    on<ResetFilters>(_onResetFilters);
  }

  Future<void> _onFetchDevices(
      FetchDevices event, Emitter<DeviceManagementState> emit) async {
    emit(DeviceManagementLoading());
    try {
      final devices = await DevicesManagementApi().fetchDevices();
      _selectedDevices.clear();
      _devices = devices;
      _filteredDevices = devices;
      _calculateDeviceCounts();
      emit(DeviceManagementLoaded(
        devices: devices,
        selectedIndex: 0,
        onlineCount: _onlineCount,
        offlineCount: _offlineCount,
        lowBatteryCount: _lowBatteryCount,
        selectedDevice: null,
      ));
    } catch (e) {
      emit(DeviceManagementInitial());
    }
  }

  void _onFilterDevices(
      FilterDevices event, Emitter<DeviceManagementState> emit) async {
    if (_devices.isNotEmpty) {
      _filteredDevices = List.from(_devices.where((device) {
        switch (event.filter) {
          case 'Online':
            return device.online == true;
          case 'Offline':
            return device.online == false;
          case 'Low Battery':
            return device.batteryLevel != null && device.batteryLevel! < 20;
          default:
            return true;
        }
      }).toList());

      emit(DeviceManagementFiltered(
        filteredDevices: _filteredDevices,
        selectedIndex: _selectedIndex,
        onlineCount: _onlineCount,
        offlineCount: _offlineCount,
        lowBatteryCount: _lowBatteryCount,
        selectedDevice:
            _selectedDevices.isNotEmpty ? _selectedDevices.first : null,
      ));

      if (productName.isNotEmpty) {
        add(SearchDevices(productName: productName));
      }
    }
  }

  Future<void> _onResetFilters(
      ResetFilters event, Emitter<DeviceManagementState> emit) async {
    productName = '';
    _selectedDevices.clear();
    _filteredDevices = List.from(_devices);
    _selectedIndex = 0;
    emit(DeviceManagementLoaded(
      devices: _devices,
      selectedIndex: 0,
      onlineCount: _onlineCount,
      offlineCount: _offlineCount,
      lowBatteryCount: _lowBatteryCount,
      selectedDevice: null,
    ));
  }

  void _onSelectedFilterChanged(
      SelectedFilterChanged event, Emitter<DeviceManagementState> emit) {
    _selectedIndex = event.selectedIndex;
    add(FilterDevices(_getFilterFromIndex(_selectedIndex)));
  }

  void _onSelectDevice(
      SelectDevice event, Emitter<DeviceManagementState> emit) {
    final selectedUuid = event.selectedDevice.uuid;

    if (_selectedDevices.any((device) => device.uuid == selectedUuid)) {
      _selectedDevices.removeWhere((device) => device.uuid == selectedUuid);
    } else {
      _selectedDevices.add(event.selectedDevice);
    }

    bool isControlButtonEnabled = _selectedDevices.length == 1;

    if (state is DeviceManagementLoaded) {
      emit(DeviceManagementLoaded(
        devices: _devices,
        selectedIndex: _selectedIndex,
        onlineCount: _onlineCount,
        offlineCount: _offlineCount,
        lowBatteryCount: _lowBatteryCount,
        selectedDevice: isControlButtonEnabled ? _selectedDevices.first : null,
      ));
    } else if (state is DeviceManagementFiltered) {
      emit(DeviceManagementFiltered(
        filteredDevices: (state as DeviceManagementFiltered).filteredDevices,
        selectedIndex: _selectedIndex,
        onlineCount: _onlineCount,
        offlineCount: _offlineCount,
        lowBatteryCount: _lowBatteryCount,
        selectedDevice: isControlButtonEnabled ? _selectedDevices.first : null,
      ));
    }
  }

  void _calculateDeviceCounts() {
    _onlineCount = _devices.where((device) => device.online == true).length;
    _offlineCount = _devices.where((device) => device.online == false).length;
    _lowBatteryCount = _devices
        .where((device) =>
            device.batteryLevel != null && device.batteryLevel! < 20)
        .length;
  }

  String _getFilterFromIndex(int index) {
    switch (index) {
      case 1:
        return 'Online';
      case 2:
        return 'Offline';
      case 3:
        return 'Low Battery';
      default:
        return 'All';
    }
  }

  void _onSearchDevices(
      SearchDevices event, Emitter<DeviceManagementState> emit) {
    // If the search fields are all empty, restore the last filtered devices
    if ((event.community == null || event.community!.isEmpty) &&
        (event.unitName == null || event.unitName!.isEmpty) &&
        (event.productName == null || event.productName!.isEmpty)) {
      productName = '';
      // If the current state is filtered, re-emit the filtered state
      if (state is DeviceManagementFiltered) {
        add(FilterDevices(_getFilterFromIndex(_selectedIndex)));
      }
    }

    productName = event.productName ?? '';
    List<AllDevicesModel> devicesToSearch = _filteredDevices;

    if (devicesToSearch.isNotEmpty) {
      _selectedDevices.clear();
      _selectedIndex = _selectedIndex;

      final filteredDevices = devicesToSearch.where((device) {
        final matchesCommunity = event.community == null ||
            event.community!.isEmpty ||
            (device.room?.name
                    ?.toLowerCase()
                    .contains(event.community!.toLowerCase()) ??
                false);
        final matchesUnit = event.unitName == null ||
            event.unitName!.isEmpty ||
            (device.unit?.name
                    ?.toLowerCase()
                    .contains(event.unitName!.toLowerCase()) ??
                false);
        final matchesProductName = event.productName == null ||
            event.productName!.isEmpty ||
            (device.name
                    ?.toLowerCase()
                    .contains(event.productName!.toLowerCase()) ??
                false);
        final matchesDeviceName = event.productName == null ||
            event.productName!.isEmpty ||
            (device.categoryName
                    ?.toLowerCase()
                    .contains(event.productName!.toLowerCase()) ??
                false);

        return matchesCommunity &&
            matchesUnit &&
            (matchesProductName || matchesDeviceName);
      }).toList();

      emit(DeviceManagementFiltered(
        filteredDevices: filteredDevices,
        selectedIndex: _selectedIndex,
        onlineCount: _onlineCount,
        offlineCount: _offlineCount,
        lowBatteryCount: _lowBatteryCount,
        selectedDevice: null,
      ));
    }
  }

  List<AllDevicesModel> get selectedDevices => _selectedDevices;
}
