import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

typedef TimeCallback = void Function(TimeOfDay? pickedTime);

class SchedulePicker extends StatefulWidget {
  final String name;
  Schedule schedule;

  SchedulePicker({super.key, required this.name, required this.schedule});

  @override
  State<SchedulePicker> createState() => _SchedulePickerState();
}

class _SchedulePickerState extends State<SchedulePicker> {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        customSwitch(widget.name, widget.schedule.habilitado, (value) {
          widget.schedule.habilitado = value;
        }),
        ...datePickers(widget.schedule.habilitado),
        const Divider(
          height: 15,
          color: Colors.grey,
        ),
      ],
    );
  }

  List<Widget> datePickers(bool value) {
    if (!value) return [];
    return [
      customSwitch(
        'Jornada continua',
        widget.schedule.jornadaContinua,
        (value) {
          widget.schedule.jornadaContinua = value;
        },
      ),
      Padding(
        padding: const EdgeInsets.symmetric(horizontal: 25),
        child: Row(children: [
          datePicker(widget.schedule.range1Hour1,
              (pickedTime) => widget.schedule.range1Hour1 = pickedTime),
          const Text('-'),
          ...(!widget.schedule.jornadaContinua
              ? [
                  datePicker(widget.schedule.range1Hour2,
                      (pickedTime) => widget.schedule.range1Hour2 = pickedTime),
                  const Text('   '),
                ]
              : []),
          ...(!widget.schedule.jornadaContinua
              ? [
                  datePicker(widget.schedule.range2Hour1,
                      (pickedTime) => widget.schedule.range2Hour1 = pickedTime),
                  const Text('-'),
                ]
              : []),
          datePicker(widget.schedule.range2Hour2,
              (pickedTime) => widget.schedule.range2Hour2 = pickedTime),
        ]),
      ),
    ];
  }

  datePicker(TimeOfDay? time, TimeCallback callback) {
    return Expanded(
      child: TextFormField(
        textAlign: TextAlign.center,
        onTap: () async {
          final TimeOfDay? pickedTime = await showTimePicker(
            context: context,
            initialTime: TimeOfDay.now(),
          );
          if (pickedTime != null) {
            setState(() {
              callback(pickedTime);
            });
          }
        },
        readOnly: true,
        decoration: const InputDecoration(
          hintText: 'Hora',
        ),
        controller: TextEditingController(
          text: time == null ? '' : time.format(context),
        ),
        style: const TextStyle(fontSize: 15),
      ),
    );
  }

  customSwitch(String text, bool switchValue, ValueChanged<bool> onChanged) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 30),
      child: SizedBox(
        height: 40,
        child: Row(
          children: [
            Expanded(
                child: Text(
              text,
              style: const TextStyle(
                fontSize: 15,
                color: Colors.black,
              ),
            )),
            Transform.scale(
              scale: 1.2,
              child: Switch(
                value: switchValue,
                onChanged: (bool newValue) {
                  setState(() {
                    onChanged(newValue);
                  });
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class Schedule {
  bool habilitado;
  bool jornadaContinua;
  TimeOfDay? range1Hour1;
  TimeOfDay? range1Hour2;
  TimeOfDay? range2Hour1;
  TimeOfDay? range2Hour2;

  Schedule(
    this.habilitado,
    this.jornadaContinua,
    this.range1Hour1,
    this.range1Hour2,
    this.range2Hour1,
    this.range2Hour2,
  );

  static Schedule fromJson(Map<String, dynamic> json) {
    return Schedule(
      json['habilitado'],
      json['jornadaContinua'],
      _parseTime(json['range1Hour1']),
      _parseTime(json['range1Hour2']),
      _parseTime(json['range2Hour1']),
      _parseTime(json['range2Hour2']),
    );
  }

  static TimeOfDay? _parseTime(String? time) {
    if (time == null) return null;
    final components = time.split(' ');
    final hourMinutes = components[0].split(':');
    final hour = int.parse(hourMinutes[0]);
    final minutes = int.parse(hourMinutes[1]);
    if (components[1] == 'PM' && hour < 12) {
      return TimeOfDay(hour: hour + 12, minute: minutes);
    } else if (components[1] == 'AM' && hour == 12) {
      return TimeOfDay(hour: 0, minute: minutes);
    }
    return TimeOfDay(hour: hour, minute: minutes);
  }

  static TimeOfDay stringToTimeOfDay(String? tod) {
    if (tod == null) {
      return TimeOfDay.now();
    }
    final format = DateFormat.jm();
    return TimeOfDay.fromDateTime(format.parse(tod));
  }

  @override
  String toString() {
    return 'Schedule(habilitado: $habilitado, jornadaContinua: $jornadaContinua, '
        'range1Hour1: $range1Hour1, range1Hour2: $range1Hour2, '
        'range2Hour1: $range2Hour1, range2Hour2: $range2Hour2)';
  }

  static Future<Map<String, Schedule>> getHorarios(String uid) async {
    try {
      final snapshot =
          await FirebaseFirestore.instance.collection('users').doc(uid).get();
      final Map<String, dynamic>? data = snapshot.data();
      final Map<String, dynamic>? horarioData = data?['horario'];
      final horarios = <String, Schedule>{};
      horarioData?.forEach((key, value) {
        horarios[key] = Schedule.fromJson(value);
      });
      return horarios;
    } catch (e) {
      print('Error getting user: $e');
      return {
        "Lunes": Schedule(false, false, null, null, null, null),
        "Martes": Schedule(false, false, null, null, null, null),
        "Miercoles": Schedule(false, false, null, null, null, null),
        "Jueves": Schedule(false, false, null, null, null, null),
        "Viernes": Schedule(false, false, null, null, null, null),
        "Sabado": Schedule(false, false, null, null, null, null),
        "Domingo": Schedule(false, false, null, null, null, null),
      };
    }
  }
}
