import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_bloc.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_event.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_state.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/schedule_view/opening_clsoing_time_dialog_body.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/schedule_view/time_out_alarm_dialog_body.dart';
import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_display_data.dart';
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_model.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';

class GarageDoorDialogHelper {
  static void showAddGarageDoorScheduleDialog(BuildContext context,
      {ScheduleModel? schedule, int? index, bool? isEdit}) {
    final bloc = context.read<GarageDoorBloc>();

    if (schedule == null) {
      bloc.add((const UpdateSelectedTimeEvent(null)));
      bloc.add(InitializeAddScheduleEvent(
        selectedTime: null,
        selectedDays: List.filled(7, false),
        functionOn: false,
        isEditing: false,
      ));
    } else {
      final time = _convertStringToTimeOfDay(schedule.time);
      final selectedDays = _convertDaysStringToBooleans(schedule.days);

      bloc.add(InitializeAddScheduleEvent(
        selectedTime: time,
        selectedDays: selectedDays,
        functionOn: schedule.function.value,
        isEditing: true,
        index: index,
      ));
    }

    showDialog(
      context: context,
      builder: (ctx) {
        return BlocProvider.value(
          value: bloc,
          child: BlocBuilder<GarageDoorBloc, GarageDoorState>(
            builder: (context, state) {
              if (state is GarageDoorLoadedState) {
                return AlertDialog(
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(20),
                  ),
                  content: Column(
                    mainAxisSize: MainAxisSize.min,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          const SizedBox(),
                          Text(
                            'Scheduling',
                            style: context.textTheme.titleLarge!.copyWith(
                              color: ColorsManager.dialogBlueTitle,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                          const SizedBox(),
                        ],
                      ),
                      const SizedBox(height: 24),
                      SizedBox(
                        width: 150,
                        height: 40,
                        child: DefaultButton(
                          padding: 8,
                          backgroundColor: ColorsManager.boxColor,
                          borderRadius: 15,
                          onPressed: () async {
                            TimeOfDay? time = await showTimePicker(
                              context: context,
                              initialTime: state.selectedTime ?? TimeOfDay.now(),
                              builder: (context, child) {
                                return Theme(
                                  data: Theme.of(context).copyWith(
                                    colorScheme: const ColorScheme.light(
                                      primary: ColorsManager.primaryColor,
                                    ),
                                  ),
                                  child: child!,
                                );
                              },
                            );
                            if (time != null) {
                              bloc.add(UpdateSelectedTimeEvent(time));
                            }
                          },
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text(
                                state.selectedTime == null ? 'Time' : state.selectedTime!.format(context),
                                style: context.textTheme.bodySmall!.copyWith(
                                  color: ColorsManager.grayColor,
                                ),
                              ),
                              const Icon(
                                Icons.access_time,
                                color: ColorsManager.grayColor,
                                size: 18,
                              ),
                            ],
                          ),
                        ),
                      ),
                      const SizedBox(height: 16),
                      _buildDayCheckboxes(context, state.selectedDays, isEdit: isEdit),
                      const SizedBox(height: 16),
                      _buildFunctionSwitch(context, state.functionOn, isEdit),
                    ],
                  ),
                  actions: [
                    SizedBox(
                      width: 200,
                      child: DefaultButton(
                        height: 40,
                        onPressed: () {
                          Navigator.pop(context);
                        },
                        backgroundColor: ColorsManager.boxColor,
                        child: Text(
                          'Cancel',
                          style: context.textTheme.bodyMedium,
                        ),
                      ),
                    ),
                    SizedBox(
                      width: 200,
                      child: DefaultButton(
                        height: 40,
                        onPressed: () {
                          if (state.selectedTime != null) {
                            if (state.isEditing && index != null) {
                              bloc.add(EditGarageDoorScheduleEvent(
                                scheduleId: schedule?.scheduleId ?? '',
                                category: 'switch_1',
                                time: state.selectedTime!,
                                selectedDays: state.selectedDays,
                                functionOn: state.functionOn,
                              ));
                            } else {
                              bloc.add(AddGarageDoorScheduleEvent(
                                category: 'switch_1',
                                time: state.selectedTime!,
                                selectedDays: state.selectedDays,
                                functionOn: state.functionOn,
                              ));
                            }
                            Navigator.pop(context);
                          }
                        },
                        backgroundColor: ColorsManager.primaryColor,
                        child: const Text('Save'),
                      ),
                    ),
                  ],
                );
              }
              return const SizedBox();
            },
          ),
        );
      },
    );
  }

  static TimeOfDay _convertStringToTimeOfDay(String timeString) {
    final regex = RegExp(r'^(\d{2}):(\d{2})$');
    final match = regex.firstMatch(timeString);
    if (match != null) {
      final hour = int.parse(match.group(1)!);
      final minute = int.parse(match.group(2)!);
      return TimeOfDay(hour: hour, minute: minute);
    } else {
      throw const FormatException('Invalid time format');
    }
  }

  static List<bool> _convertDaysStringToBooleans(List<String> selectedDays) {
    final daysOfWeek = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
    List<bool> daysBoolean = List.filled(7, false);

    for (int i = 0; i < daysOfWeek.length; i++) {
      if (selectedDays.contains(daysOfWeek[i])) {
        daysBoolean[i] = true;
      }
    }

    return daysBoolean;
  }

  static Widget _buildDayCheckboxes(BuildContext context, List<bool> selectedDays, {bool? isEdit}) {
    final dayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];

    return Row(
      children: List.generate(7, (index) {
        return Row(
          children: [
            Checkbox(
              value: selectedDays[index],
              onChanged: (bool? value) {
                context.read<GarageDoorBloc>().add(UpdateSelectedDayEvent(index, value!));
              },
            ),
            Text(dayLabels[index]),
          ],
        );
      }),
    );
  }

  static Widget _buildFunctionSwitch(BuildContext context, bool isOn, bool? isEdit) {
    return Row(
      children: [
        Text(
          'Function:',
          style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.grayColor),
        ),
        const SizedBox(width: 10),
        Radio<bool>(
          value: true,
          groupValue: isOn,
          onChanged: (bool? value) {
            context.read<GarageDoorBloc>().add(const UpdateFunctionOnEvent(functionOn: true));
          },
        ),
        const Text('On'),
        const SizedBox(width: 10),
        Radio<bool>(
          value: false,
          groupValue: isOn,
          onChanged: (bool? value) {
            context.read<GarageDoorBloc>().add(const UpdateFunctionOnEvent(functionOn: false));
          },
        ),
        const Text('Off'),
      ],
    );
  }

  static void showPreferencesDialog(BuildContext context) {
    final bloc = context.read<GarageDoorBloc>();

    showDialog(
      context: context,
      builder: (ctx) {
        return BlocProvider.value(
          value: bloc,
          child: BlocBuilder<GarageDoorBloc, GarageDoorState>(
            builder: (context, state) {
              if (state is GarageDoorLoadedState) {
                return AlertDialog(
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(20),
                  ),
                  content: Column(
                    mainAxisSize: MainAxisSize.min,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          const SizedBox(),

                          /// The dialog is closed when the user taps on the close button or when the
                          /// [GarageDoorBloc] state changes.
                          Text(
                            'Preferences',
                            style: context.textTheme.titleLarge!.copyWith(
                              color: ColorsManager.dialogBlueTitle,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                          const SizedBox(),
                        ],
                      ),
                      const SizedBox(height: 24),
                      Row(
                        children: [
                          const SizedBox(width: 24),
                          SizedBox(
                            width: 190,
                            height: 150,
                            child: GestureDetector(
                              onTap: () {
                                context.customAlertDialog(
                                    alertBody: TimeOutAlarmDialogBody(bloc),
                                    title: 'Time Out Alarm',
                                    onConfirm: () {
                                      final updatedState = context.read<GarageDoorBloc>().state;
                                      if (updatedState is GarageDoorLoadedState) {
                                        context.read<GarageDoorBloc>().add(
                                              GarageDoorControlEvent(
                                                deviceId: updatedState.status.uuid,
                                                code: 'countdown_alarm',
                                                value: updatedState.status.countdownAlarm,
                                              ),
                                            );
                                        Navigator.pop(context);
                                      }
                                    });
                              },
                              child: ToggleWidget(
                                  icon: "-1",
                                  value: state.status.doorState1 == "close_time_alarm" ? false : true,
                                  code: 'door_state_1',
                                  deviceId: bloc.deviceId,
                                  label: 'Alarm when door is open',
                                  onChange: (value) {
                                    context.read<GarageDoorBloc>().add(
                                          GarageDoorControlEvent(
                                            deviceId: bloc.deviceId,
                                            code: 'door_state_1',
                                            value: state.status.doorState1 == "close_time_alarm"
                                                ? "unclosed_time"
                                                : "close_time_alarm",
                                          ),
                                        );
                                  }),
                            ),
                          ),
                          const SizedBox(
                            width: 20,
                          ),
                          SizedBox(
                            width: 190,
                            height: 150,
                            child: GestureDetector(
                              onTap: () {
                                context.customAlertDialog(
                                    alertBody: OpeningAndClosingTimeDialogBody(
                                      bloc: bloc,
                                      onDurationChanged: (newDuration) {
                                        context.read<GarageDoorBloc>().add(
                                              UpdateTrTimeConEvent(newDuration),
                                            );
                                      },
                                    ),
                                    title: 'Opening and Closing Time',
                                    onConfirm: () {
                                      final updatedState = context.read<GarageDoorBloc>().state;
                                      if (updatedState is GarageDoorLoadedState) {
                                        context.read<GarageDoorBloc>().add(
                                              GarageDoorControlEvent(
                                                deviceId: updatedState.status.uuid,
                                                code: 'tr_timecon',
                                                value: updatedState.status.trTimeCon,
                                              ),
                                            );
                                        Navigator.pop(context);
                                      }
                                    });
                              },
                              child: PresenceDisplayValue(
                                value: state.status.trTimeCon.toString(),
                                postfix: 'sec',
                                description: 'Opening & Closing Time',
                              ),
                            ),
                          ),
                          const SizedBox(width: 24),
                        ],
                      )
                    ],
                  ),
                );
              }
              return const SizedBox();
            },
          ),
        );
      },
    );
  }
}
