import 'dart:async'; import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/routiens/models/create_scene/create_scene_model.dart'; import 'package:syncrow_web/pages/routiens/models/device_functions.dart'; import 'package:syncrow_web/pages/routiens/models/routine_model.dart'; import 'package:syncrow_web/services/routines_api.dart'; part 'routine_event.dart'; part 'routine_state.dart'; const spaceId = '25c96044-fadf-44bb-93c7-3c079e527ce6'; class RoutineBloc extends Bloc { bool isAutomation = false; bool isTabToRun = false; RoutineBloc() : super(const RoutineState()) { on(_onAddToIfContainer); on(_onAddToThenContainer); on(_onLoadScenes); on(_onLoadAutomation); on(_onAddFunctionsToRoutine); on(_onSearchRoutines); on(_onAddSelectedIcon); on(_onCreateScene); // on(_onRemoveFunction); // on(_onClearFunctions); } void _onAddToIfContainer(AddToIfContainer event, Emitter emit) { final updatedIfItems = List>.from(state.ifItems) ..add(event.item); isTabToRun = event.isTabToRun; emit(state.copyWith(ifItems: updatedIfItems)); } void _onAddToThenContainer( AddToThenContainer event, Emitter emit) { final updatedThenItems = List>.from(state.thenItems) ..add(event.item); emit(state.copyWith(thenItems: updatedThenItems)); } void _onAddFunctionsToRoutine( AddFunctionToRoutine event, Emitter emit) { final currentSelectedFunctions = Map>.from(state.selectedFunctions); if (currentSelectedFunctions.containsKey(event.uniqueCustomId)) { currentSelectedFunctions[event.uniqueCustomId]!.addAll(event.functions); } else { currentSelectedFunctions[event.uniqueCustomId] = event.functions; } emit(state.copyWith(selectedFunctions: currentSelectedFunctions)); } // void _onRemoveFunction(RemoveFunction event, Emitter emit) { // final functions = List.from(state.selectedFunctions) // ..removeWhere((f) => // f.functionCode == event.function.functionCode && // f.value == event.function.value); // emit(state.copyWith(selectedFunctions: functions)); // } // void _onClearFunctions(ClearFunctions event, Emitter emit) { // emit(state.copyWith(selectedFunctions: [])); // } Future _onLoadScenes( LoadScenes event, Emitter emit) async { emit(state.copyWith(isLoading: true, errorMessage: null)); try { final scenes = await SceneApi.getScenesByUnitId(event.unitId); emit(state.copyWith( scenes: scenes, isLoading: false, )); } catch (e) { emit(state.copyWith( isLoading: false, errorMessage: 'Failed to load scenes', )); } } Future _onLoadAutomation( LoadAutomation event, Emitter emit) async { emit(state.copyWith(isLoading: true, errorMessage: null)); try { final automations = await SceneApi.getAutomationByUnitId(event.unitId); emit(state.copyWith( automations: automations, isLoading: false, )); } catch (e) { emit(state.copyWith( isLoading: false, errorMessage: 'Failed to load automations', )); } } FutureOr _onSearchRoutines( SearchRoutines event, Emitter emit) { emit(state.copyWith(routineName: event.query)); } FutureOr _onAddSelectedIcon( AddSelectedIcon event, Emitter emit) { emit(state.copyWith(selectedIcon: event.icon)); } bool _isFirstActionDelay(List> actions) { if (actions.isEmpty) return false; return actions.first['deviceId'] == 'delay'; } Future _onCreateScene( CreateSceneEvent event, Emitter emit) async { try { // Check if first action is delay if (_isFirstActionDelay(state.thenItems)) { emit(state.copyWith( errorMessage: 'Cannot have delay as the first action', isLoading: false, )); return; } emit(state.copyWith(isLoading: true)); final actions = state.thenItems .map((item) { final functions = state.selectedFunctions[item['uniqueCustomId']] ?? []; if (functions.isEmpty) return null; final function = functions.first; if (item['deviceId'] == 'delay') { return CreateSceneAction( entityId: function.entityId, actionExecutor: 'delay', executorProperty: CreateSceneExecutorProperty( functionCode: '', functionValue: '', delaySeconds: function.value, ), ); } return CreateSceneAction( entityId: function.entityId, actionExecutor: 'device_issue', executorProperty: CreateSceneExecutorProperty( functionCode: function.functionCode.toString(), functionValue: function.value, delaySeconds: 0, ), ); }) .whereType() .toList(); final createSceneModel = CreateSceneModel( spaceUuid: spaceId, iconId: state.selectedIcon ?? '', showInDevice: true, sceneName: state.routineName ?? '', decisionExpr: 'and', actions: actions, ); final result = await SceneApi.createScene(createSceneModel); if (result['success']) { emit(state.copyWith( isLoading: false, errorMessage: null, )); } else { emit(state.copyWith( isLoading: false, errorMessage: result['message'], )); } } catch (e) { emit(state.copyWith( isLoading: false, errorMessage: e.toString(), )); } } }