import 'dart:async';

import 'package:equatable/equatable.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/scene/bloc/scene_bloc/scene_event.dart';
import 'package:syncrow_app/features/scene/model/scenes_model.dart';
import 'package:syncrow_app/services/api/scene_api.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';

part 'scene_state.dart';

class SceneBloc extends Bloc<SceneEvent, SceneState> {
  SceneBloc() : super(SceneInitial()) {
    on<LoadScenes>(_onLoadScenes);
    on<LoadAutomation>(_onLoadAutomation);
    on<SceneTrigger>(_onSceneTrigger);
    on<UpdateAutomationStatus>(_onUpdateAutomationStatus);
  }

  List<ScenesModel> scenes = [];
  List<ScenesModel> automationList = [];

  Future<void> _onLoadScenes(LoadScenes event, Emitter<SceneState> emit) async {
    emit(SceneLoading());

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

      if (event.unitId.isNotEmpty) {
        scenes = await SceneApi.getScenesByUnitId(event.unitId,
            event.unit.community.uuid, project?.uuid ?? TempConst.projectIdDev,
            showInDevice: event.showInDevice);
        emit(SceneLoaded(scenes, automationList));
      } else {
        emit(const SceneError(message: 'Unit ID is empty'));
      }
    } catch (e) {
      emit(const SceneError(message: 'Something went wrong'));
    }
  }

  Future<void> _onLoadAutomation(
      LoadAutomation event, Emitter<SceneState> emit) async {
    emit(SceneLoading());

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

      if (event.unitId.isNotEmpty) {
        automationList = await SceneApi.getAutomationByUnitId(
            event.unitId, event.communityId, project?.uuid ?? '');
        emit(SceneLoaded(scenes, automationList));
      } else {
        emit(const SceneError(message: 'Unit ID is empty'));
      }
    } catch (e) {
      emit(const SceneError(message: 'Something went wrong'));
    }
  }

  Future<void> _onSceneTrigger(
      SceneTrigger event, Emitter<SceneState> emit) async {
    final currentState = state;
    if (currentState is SceneLoaded) {
      emit(SceneLoaded(
        currentState.scenes,
        currentState.automationList,
        loadingSceneId: event.sceneId,
      ));

      try {
        final success = await SceneApi.triggerScene(event.sceneId);
        if (success) {
          emit(SceneTriggerSuccess(event.name));
          emit(SceneLoaded(currentState.scenes, currentState.automationList));
        } else {
          emit(const SceneError(message: 'Something went wrong'));
        }
      } catch (e) {
        emit(const SceneError(message: 'Something went wrong'));
      }
    }
  }

  Future<void> _onUpdateAutomationStatus(
      UpdateAutomationStatus event, Emitter<SceneState> emit) async {
    final currentState = state;
    if (currentState is SceneLoaded) {
      final newLoadingStates =
          Map<String, bool>.from(currentState.loadingStates)
            ..[event.automationId] = true;

      emit(SceneLoaded(
        currentState.scenes,
        currentState.automationList,
        loadingStates: newLoadingStates,
      ));

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

        final success = await SceneApi.updateAutomationStatus(
            event.automationId,
            event.automationStatusUpdate,
            project?.uuid ?? '');
        if (success) {
          automationList = await SceneApi.getAutomationByUnitId(
              event.automationStatusUpdate.spaceUuid,
              event.communityId,
              project?.uuid ?? '');
          newLoadingStates[event.automationId] = false;
          emit(SceneLoaded(
            currentState.scenes,
            automationList,
            loadingStates: newLoadingStates,
          ));
        } else {
          emit(const SceneError(message: 'Something went wrong'));
        }
      } catch (e) {
        emit(const SceneError(message: 'Something went wrong'));
      }
    }
  }
}
