import 'dart:async';

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart';
import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_event.dart';
import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_state.dart';
import 'package:syncrow_app/features/scene/enum/effective_period_options.dart';
import 'package:syncrow_app/features/scene/model/create_automation_model.dart';
import 'package:syncrow_app/navigation/navigation_service.dart';

class EffectPeriodBloc extends Bloc<EffectPeriodEvent, EffectPeriodState> {
  final daysMap = {
    'Sun': 'S',
    'Mon': 'M',
    'Tue': 'T',
    'Wed': 'W',
    'Thu': 'T',
    'Fri': 'F',
    'Sat': 'S',
  };

  EffectPeriodBloc() : super(EffectPeriodState.initial()) {
    on<SetPeriod>(_onSetPeriod);
    on<ToggleDay>(_onToggleDay);
    on<SetCustomTime>(_onSetCustomTime);
    on<ResetEffectivePeriod>(_onResetEffectivePeriod);
    on<ResetDays>(_onResetDays);
    on<SetDays>(_setAllDays);
  }

  void _onSetPeriod(SetPeriod event, Emitter<EffectPeriodState> emit) {
    String startTime = '';
    String endTime = '';

    switch (event.period) {
      case EnumEffectivePeriodOptions.allDay:
        startTime = '00:00';
        endTime = '23:59';
        break;
      case EnumEffectivePeriodOptions.daytime:
        startTime = '06:00';
        endTime = '18:00';
        break;
      case EnumEffectivePeriodOptions.night:
        startTime = '18:00';
        endTime = '06:00';
        break;
      case EnumEffectivePeriodOptions.custom:
        startTime = state.customStartTime ?? '00:00';
        endTime = state.customEndTime ?? '23:59';
        break;
      default:
        break;
    }

    BlocProvider.of<CreateSceneBloc>(NavigationService.navigatorKey.currentContext!).add(
        EffectiveTimePeriodEvent(
            EffectiveTime(start: startTime, end: endTime, loops: state.selectedDaysBinary)));

    emit(state.copyWith(
        selectedPeriod: event.period, customStartTime: startTime, customEndTime: endTime));
  }

  void _onToggleDay(ToggleDay event, Emitter<EffectPeriodState> emit) {
    final daysList = state.selectedDaysBinary.split('');
    final dayIndex = getDayIndex(event.day);
    if (daysList[dayIndex] == '1') {
      daysList[dayIndex] = '0';
    } else {
      daysList[dayIndex] = '1';
    }
    final newDaysBinary = daysList.join();
    emit(state.copyWith(selectedDaysBinary: newDaysBinary));

    BlocProvider.of<CreateSceneBloc>(NavigationService.navigatorKey.currentContext!).add(
        EffectiveTimePeriodEvent(EffectiveTime(
            start: state.customStartTime ?? '00:00',
            end: state.customEndTime ?? '23:59',
            loops: newDaysBinary)));
  }

  void _onSetCustomTime(SetCustomTime event, Emitter<EffectPeriodState> emit) {
    String startTime = event.startTime;
    String endTime = event.endTime;
    EnumEffectivePeriodOptions period;

    // Determine the period based on start and end times
    if (startTime == '00:00' && endTime == '23:59') {
      period = EnumEffectivePeriodOptions.allDay;
    } else if (startTime == '06:00' && endTime == '18:00') {
      period = EnumEffectivePeriodOptions.daytime;
    } else if (startTime == '18:00' && endTime == '06:00') {
      period = EnumEffectivePeriodOptions.night;
    } else {
      period = EnumEffectivePeriodOptions.custom;
    }

    emit(
        state.copyWith(customStartTime: startTime, customEndTime: endTime, selectedPeriod: period));

    BlocProvider.of<CreateSceneBloc>(NavigationService.navigatorKey.currentContext!).add(
        EffectiveTimePeriodEvent(
            EffectiveTime(start: startTime, end: endTime, loops: state.selectedDaysBinary)));
  }

  void _onResetEffectivePeriod(ResetEffectivePeriod event, Emitter<EffectPeriodState> emit) {
    emit(state.copyWith(
        selectedPeriod: EnumEffectivePeriodOptions.allDay,
        customStartTime: '00:00',
        customEndTime: '23:59',
        selectedDaysBinary: '1111111'));

    BlocProvider.of<CreateSceneBloc>(NavigationService.navigatorKey.currentContext!).add(
        EffectiveTimePeriodEvent(EffectiveTime(start: '00:00', end: '23:59', loops: '1111111')));
  }

  void _onResetDays(ResetDays event, Emitter<EffectPeriodState> emit) {
    emit(state.copyWith(selectedDaysBinary: '1111111'));
  }

  int getDayIndex(String day) {
    const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
    return days.indexOf(day);
  }

  FutureOr<void> _setAllDays(SetDays event, Emitter<EffectPeriodState> emit) {
    emit(state.copyWith(selectedDaysBinary: event.daysBinary));
  }
}
