import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
import 'package:syncrow_web/pages/device_managment/device_setting/settings_model/device_info_model.dart';
import 'package:syncrow_web/pages/device_managment/device_setting/bloc/setting_bloc_state.dart';
import 'package:syncrow_web/pages/device_managment/device_setting/settings_model/sub_space_model.dart';
import 'package:syncrow_web/services/devices_mang_api.dart';
import 'package:syncrow_web/services/space_mana_api.dart';
import 'package:syncrow_web/utils/snack_bar.dart';
part 'setting_bloc_event.dart';

class SettingDeviceBloc extends Bloc<DeviceSettingEvent, DeviceSettingsState> {
  final String deviceId;
  SettingDeviceBloc({
    required this.deviceId,
  }) : super(const DeviceSettingsInitial()) {
    on<DeviceSettingInitialInfo>(_fetchDeviceInfo);
    on<SettingBlocSaveName>(_saveName);
    on<ChangeNameEvent>(_changeName);
    on<SettingBlocDeleteDevice>(_deleteDevice);
    on<SettingBlocFetchRooms>(_fetchRooms);
    on<SettingBlocAssignRoom>(_onAssignDevice);
  }
  final TextEditingController nameController = TextEditingController();
  List<SubSpaceModel> roomsList = [];
  bool isEditingName = false;

  bool _validateInputs() {
    final nameError = _fullNameValidator(nameController.text);
    if (nameError != null) {
      CustomSnackBar.displaySnackBar(nameError);
      return true;
    }
    return false;
  }

  String? _fullNameValidator(String? value) {
    if (value == null) return 'name is required';
    final withoutExtraSpaces = value.replaceAll(RegExp(r"\s+"), ' ').trim();
    if (withoutExtraSpaces.length < 2 || withoutExtraSpaces.length > 30) {
      return 'name must be between 2 and 30 characters long';
    }
    if (RegExp(r"/[^ a-zA-Z0-9-\']/").hasMatch(withoutExtraSpaces)) {
      return 'Only alphanumeric characters, space, dash and single quote are allowed';
    }
    return null;
  }

  Future<void> _saveName(
      SettingBlocSaveName event, Emitter<DeviceSettingsState> emit) async {
    if (_validateInputs()) return;
    try {
      emit(DeviceSettingsLoading());
      await DevicesManagementApi.putDeviceName(
          deviceId: deviceId, deviceName: nameController.text);
      add(DeviceSettingInitialInfo());
      CustomSnackBar.displaySnackBar('Save Successfully');
      emit(DeviceSettingsUpdate(deviceName: nameController.text));
    } catch (e) {
      emit(DeviceSettingsError(message: e.toString()));
    }
  }

  Future<void> _fetchDeviceInfo(
      DeviceSettingInitialInfo event, Emitter<DeviceSettingsState> emit) async {
    try {
      emit(DeviceSettingsLoading());
      var response = await DevicesManagementApi.getDeviceInfo(deviceId);
      DeviceInfoModel deviceInfo = DeviceInfoModel.fromJson(response);
      nameController.text = deviceInfo.name;
      emit(DeviceSettingsUpdate(
        deviceName: nameController.text,
        deviceInfo: deviceInfo,
        roomsList: roomsList,
      ));
    } catch (e) {
      emit(DeviceSettingsError(message: e.toString()));
    }
  }

  bool editName = false;
  final FocusNode focusNode = FocusNode();

  void _changeName(ChangeNameEvent event, Emitter<DeviceSettingsState> emit) {
    emit(DeviceSettingsInitial(
      deviceName: nameController.text,
      deviceId: deviceId,
      isEditingName: event.value ?? false,
      editingNameValue: event.value?.toString() ?? '',
      deviceInfo: state.deviceInfo,
    ));
    editName = event.value!;
    if (editName) {
      Future.delayed(const Duration(milliseconds: 500), () {
        focusNode.requestFocus();
      });
    } else {
      add(const SettingBlocSaveName());
      focusNode.unfocus();
    }
    emit(DeviceSettingsUpdate(
      deviceName: nameController.text,
      deviceInfo: state.deviceInfo,
      roomsList: roomsList,
    ));
  }

  void _deleteDevice(
      SettingBlocDeleteDevice event, Emitter<DeviceSettingsState> emit) async {
    try {
      emit(DeviceSettingsLoading());
      await DevicesManagementApi.resetDevice(devicesUuid: deviceId);
      CustomSnackBar.displaySnackBar('Reset Successfully');
      emit(DeviceSettingsUpdate(
        deviceName: nameController.text,
        deviceInfo: state.deviceInfo,
        roomsList: roomsList,
      ));
    } catch (e) {
      emit(DeviceSettingsError(message: e.toString()));
      return;
    }
  }

  void _onAssignDevice(
      SettingBlocAssignRoom event, Emitter<DeviceSettingsState> emit) async {
    try {
      emit(DeviceSettingsLoading());
      final projectUuid = await ProjectManager.getProjectUUID() ?? '';
      await CommunitySpaceManagementApi.assignDeviceToRoom(
          communityId: event.communityUuid,
          spaceId: event.spaceUuid,
          subSpaceId: event.subSpaceUuid,
          deviceId: deviceId,
          projectId: projectUuid);
      add(DeviceSettingInitialInfo());
      CustomSnackBar.displaySnackBar('Save Successfully');
      emit(DeviceSettingsSaveSelectionSuccess());
    } catch (e) {
      emit(DeviceSettingsError(message: e.toString()));
      return;
    }
  }

  void _fetchRooms(
      SettingBlocFetchRooms event, Emitter<DeviceSettingsState> emit) async {
    try {
      emit(DeviceSettingsLoading());
      final projectUuid = await ProjectManager.getProjectUUID() ?? '';
      roomsList = await CommunitySpaceManagementApi.getSubSpaceBySpaceId(
          communityId: event.communityUuid,
          spaceId: event.spaceUuid,
          projectId: projectUuid);
      emit(DeviceSettingsUpdate(
        deviceName: nameController.text,
        deviceInfo: state.deviceInfo,
        roomsList: roomsList,
      ));
    } catch (e) {
      emit(DeviceSettingsError(message: e.toString()));
      return;
    }
  }
}
