import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:plataforma_educativa/src/providers/db_provider.dart';
import 'package:plataforma_educativa/src/providers/events_provider.dart';
import 'package:syncfusion_flutter_calendar/calendar.dart';

class TableCalendarPage extends StatefulWidget {
  final bool revisaHijo;

  const TableCalendarPage({Key? key, required this.revisaHijo}) : super(key: key);

  @override
  _TableCalendarPageState createState() => _TableCalendarPageState();
}

class _TableCalendarPageState extends State<TableCalendarPage> {
  final _eventsProvider = EventsProvider();
  final List<Evento> _eventos = [];
  bool _isLoading = true;
  final List<String> _days = ["Lun", "Mar", "Mié", "Jue", "Vie", "Sáb", "Dom"];
  late String _daySelected;
  late int _dayNumber;
  List<Evento> _eventosSel = [];

  @override
  void initState() {
    super.initState();
    _init();
  }

  void _init() async{
    final escuelas = await DBProvider.db.getAllScans();
    final escuela = escuelas.first;

    final usuarios = await DBProvider.db.getAllUsers();
    final usuario = usuarios.first;
    final hijo = usuarios.last;

    _daySelected = _days[DateTime.now().weekday - 1];
    _dayNumber = DateTime.now().day;

    final eventos = await _eventsProvider.fetchEvents(usuario.token, widget.revisaHijo ? hijo.idUsuario : usuario.idUsuario, escuela.idEscuela);
    if(eventos.result.isNotEmpty){
      eventos.result.forEach((evento) {
        final fIni = evento.fechaInicio;
        final fFin = evento.fechaFin;
        final duracionDias = fFin.difference(fIni).inDays;
        final colorArr = evento.colorEvento.split("|");
        final color = Color.fromRGBO(int.parse(colorArr[0]), int.parse(colorArr[1]), int.parse(colorArr[2]), 1);
        final hoy = DateTime.now();

        if(duracionDias < 1){
          _eventos.add(Evento(evento.titulo, fIni, fFin, color, false));
          if(fIni.day == hoy.day && fIni.month == hoy.month && fIni.year == hoy.year){
            _eventosSel.add(Evento(evento.titulo, fIni, fFin, color, false));
          }
        }else if(duracionDias > 1){
          for(int i = 0; i < duracionDias; i++){
            final fI = i == 0 ? evento.fechaInicio : evento.fechaInicio.add(const Duration(days: 1)).subtract(Duration(
              hours: evento.fechaInicio.hour,
              minutes: evento.fechaInicio.minute,
              seconds: evento.fechaInicio.second,
              milliseconds: evento.fechaInicio.millisecond,
              microseconds: evento.fechaInicio.microsecond,
            ));

            final fF = i == duracionDias - 1 ? evento.fechaFin : evento.fechaFin.subtract(Duration(
              hours: evento.fechaFin.hour,
              minutes: evento.fechaFin.minute,
              seconds: evento.fechaFin.second,
              milliseconds: evento.fechaFin.millisecond,
              microseconds: evento.fechaFin.microsecond,
            )).add(const Duration(hours: 23, minutes: 59, seconds: 59));

            const dia = 23 * 59 * 59;

            final diff = fF.difference(fI).inSeconds;

            _eventos.add(Evento(evento.titulo, fI, fF, color, dia == diff));
            if(fI.day == hoy.day && fI.month == hoy.month && fI.year == hoy.year){
              _eventosSel.add(Evento(evento.titulo, fI, fF, color, dia == diff));
            }
          }
        }else{
          _eventos.add(Evento(evento.titulo, fIni, fFin, color, true));
          if(fIni.day == hoy.day && fIni.month == hoy.month && fIni.year == hoy.year){
            _eventosSel.add(Evento(evento.titulo, fIni, fFin, color, true));
          }
        }
      });
    }
    setState(() => _isLoading = false);
  }

  @override
  Widget build(BuildContext context) {
    final _screnSize = MediaQuery.of(context).size;
    return Scaffold(
      body: Container(
        height: _screnSize.height,
        width: _screnSize.width,
        decoration: const BoxDecoration(
          image: DecorationImage(
            image: AssetImage("assets/trt0.png"),
            fit: BoxFit.cover,
          ),
        ),
        child: _isLoading ? Center(
          child: Image.asset(
            "assets/loading.gif",
            width: 64.0,
          ),
        ) : SafeArea(
          child: Column(
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  TextButton(
                    style: TextButton.styleFrom(),
                    child: const Icon(
                      Icons.arrow_back_ios,
                      color: Color.fromRGBO(22, 23, 112, 1),
                      size: 32.0,
                    ),
                    onPressed: () => Navigator.pop(context),
                  ),
                  Expanded(
                    child: Text(
                      "Calendario",
                      textAlign: TextAlign.center,
                      style: GoogleFonts.montserrat(
                        fontSize: 20.0,
                        color: Colors.black38,
                        fontWeight: FontWeight.w500,
                      ),
                    ),
                  ),
                  TextButton(
                    style: TextButton.styleFrom(),
                    child: const Icon(
                      Icons.menu,
                      color: Color.fromRGBO(22, 23, 112, 1),
                      size: 32.0,
                    ),
                    onPressed: () => true,
                  ),
                ],
              ),
              Expanded(
                child: SfCalendar(
                  view: CalendarView.month,
                  dataSource: EventosDataSource(_eventos),
                  todayHighlightColor: Colors.grey,
                  todayTextStyle: GoogleFonts.montserrat(
                    color: Colors.white
                  ),
                  backgroundColor: Colors.transparent,
                  onTap: (details) => setState(() {
                    _daySelected = _days[details.date!.weekday - 1];
                    _dayNumber = details.date!.day;
                    _eventosSel.clear();
                    details.appointments!.forEach((element) {
                      _eventosSel.add(Evento(element.eventName, element.from, element.to, element.background, element.isAllDay));
                    });
                  }),
                  headerStyle: CalendarHeaderStyle(
                    textAlign: TextAlign.center,
                    textStyle: GoogleFonts.montserrat(
                      color: const Color.fromRGBO(22, 23, 112, 1),
                      fontSize: 18.0,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                ),
              ),
              const SizedBox(height: 4.0),
              SizedBox(
                height: 128.0,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.start,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    SizedBox(
                      width: 48.0,
                      child: Column(
                        children: [
                          SizedBox(
                            width: double.infinity,
                            child: Text(
                              _daySelected,
                              textAlign: TextAlign.center,
                              style: GoogleFonts.montserrat(
                                color: Colors.black38,
                                letterSpacing: 0.5,
                                fontSize: 16.0,
                              ),
                            ),
                          ),
                          SizedBox(
                            width: double.infinity,
                            child: Text(
                              "$_dayNumber",
                              textAlign: TextAlign.center,
                              style: GoogleFonts.montserrat(
                                color: Colors.black54,
                                fontWeight: FontWeight.bold,
                                fontSize: 20.0,
                              ),
                            ),
                          )
                        ],
                      ),
                    ),
                    const SizedBox(width: 4.0),
                    Expanded(
                      child: SingleChildScrollView(
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.start,
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            if(_eventosSel.isEmpty)
                              SizedBox(
                                width: double.infinity,
                                child: Text(
                                  "No existen eventos para este día.",
                                  style: GoogleFonts.montserrat(
                                    color: Colors.black54,
                                    fontSize: 16.0,
                                  ),
                                ),
                              ),
                            if(_eventosSel.isNotEmpty)
                              for(int i = 0; i < _eventosSel.length; i++)
                                Container(
                                  width: double.infinity,
                                  child: ElevatedButton(
                                    child: Container(
                                      width: double.infinity,
                                      padding: const EdgeInsets.all(8.0),
                                      child: Column(
                                        children: [
                                          SizedBox(
                                            width: double.infinity,
                                            child: Text(
                                              _eventosSel[i].eventName,
                                              style: GoogleFonts.montserrat(
                                                color: Colors.white,
                                                fontWeight: FontWeight.bold,
                                                fontSize: 16.0,
                                                letterSpacing: 0.5,
                                              ),
                                              maxLines: 1,
                                              overflow: TextOverflow.ellipsis,
                                            ),
                                          ),
                                          const SizedBox(height: 4.0),
                                          SizedBox(
                                            width: double.infinity,
                                            child: Text(
                                              _buildDates(_eventosSel[i].from, _eventosSel[i].to),
                                              style: GoogleFonts.montserrat(
                                                color: Colors.white,
                                                fontSize: 14.0,
                                                letterSpacing: 0.5,
                                              ),
                                              maxLines: 1,
                                              overflow: TextOverflow.ellipsis,
                                            ),
                                          ),
                                        ],
                                      ),
                                    ),
                                    onPressed: () => true,
                                    style: ElevatedButton.styleFrom(
                                      primary: _eventosSel[i].background,
                                      padding: EdgeInsets.zero,
                                      minimumSize: Size(0.0, 0.0),
                                      tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                                      elevation: 0
                                    ),
                                  ),
                                  margin: const EdgeInsets.only(bottom: 4.0, right: 4.0),
                                )
                          ],
                        ),
                      ),
                    )
                  ],
                ),
              )
            ],
          ),
        ),
      ),
    );
  }

  String _buildDates(DateTime inicio, DateTime fin){
    String strFinal = "";
    final iniStr = inicio.toIso8601String();
    final timeIni = iniStr.split("T")[1];
    final timeIniArr = timeIni.split(":");
    final horaIniInt = int.parse(timeIniArr.first);
    String tiempoIni;

    if(horaIniInt > 12){
      final horaIniPM = horaIniInt - 12;
      final pmIni = horaIniPM < 10 ? "0$horaIniPM" : "$horaIniPM";
      strFinal += "$pmIni:";
      tiempoIni = "PM";
    }else{
      final amIni = horaIniInt < 10 ? "0$horaIniInt" : "$horaIniInt";
      strFinal += "$amIni:";
      tiempoIni = "AM";
    }

    strFinal += "${timeIniArr[1]} $tiempoIni - ";

    final finStr = fin.toIso8601String();
    final timeFin = finStr.split("T")[1];
    final timeFinArr = timeFin.split(":");
    final horaFinInt = int.parse(timeFinArr.first);
    String tiempoFin;

    if(horaFinInt > 12){
      final horaFinPM = horaFinInt - 12;
      final pmFin = horaFinPM < 10 ? "0$horaFinPM" : "$horaFinPM";
      strFinal += "$pmFin:";
      tiempoFin = "PM";
    }else{
      final amFin = horaFinInt < 10 ? "0$horaFinInt" : "$horaFinInt";
      strFinal += "$amFin:";
      tiempoFin = "AM";
    }

    strFinal += "${timeFinArr[1]} $tiempoFin";

    return strFinal;
  }
}

class Evento{
  Evento(this.eventName, this.from, this.to, this.background, this.isAllDay);

  String eventName;
  DateTime from;
  DateTime to;
  Color background;
  bool isAllDay;
}

class EventosDataSource extends CalendarDataSource{
  EventosDataSource(List<Evento> eventos){
    appointments = eventos;
  }

  @override
  DateTime getStartTime(int index) {
    return appointments![index].from;
  }

  @override
  DateTime getEndTime(int index) {
    return appointments![index].to;
  }

  @override
  String getSubject(int index) {
    return appointments![index].eventName;
  }

  @override
  Color getColor(int index) {
    return appointments![index].background;
  }

  @override
  bool isAllDay(int index) {
    return appointments![index].isAllDay;
  }
}
