import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:jiffy/jiffy.dart';
import '../../../extensions/dateTime.dart';
import 'package:provider/provider.dart';
import 'package:rrule_generator/rrule_generator.dart';
import 'package:time_range_picker/time_range_picker.dart';

import '../../../api/mhsl/customTimetableEvent/add/addCustomTimetableEvent.dart';
import '../../../api/mhsl/customTimetableEvent/add/addCustomTimetableEventParams.dart';
import '../../../api/mhsl/customTimetableEvent/customTimetableEvent.dart';
import '../../../api/mhsl/customTimetableEvent/update/updateCustomTimetableEvent.dart';
import '../../../api/mhsl/customTimetableEvent/update/updateCustomTimetableEventParams.dart';
import '../../../model/accountData.dart';
import '../../../model/timetable/timetableProps.dart';
import '../../../widget/focusBehaviour.dart';
import '../../../widget/infoDialog.dart';
import 'customTimetableColors.dart';

class CustomTimetableEventEditDialog extends StatefulWidget {
  final CustomTimetableEvent? existingEvent;
  const CustomTimetableEventEditDialog({this.existingEvent, super.key});

  @override
  State<CustomTimetableEventEditDialog> createState() => _AddCustomTimetableEventDialogState();
}

class _AddCustomTimetableEventDialogState extends State<CustomTimetableEventEditDialog> {
  late DateTime _date = widget.existingEvent?.startDate ?? DateTime.now();
  late TimeOfDay _startTime = widget.existingEvent?.startDate.toTimeOfDay() ?? const TimeOfDay(hour: 08, minute: 00);
  late TimeOfDay _endTime = widget.existingEvent?.endDate.toTimeOfDay() ?? const TimeOfDay(hour: 09, minute: 30);
  late final TextEditingController _eventName = TextEditingController(text: widget.existingEvent?.title);
  late final TextEditingController _eventDescription = TextEditingController(text: widget.existingEvent?.description);
  late String _recurringRule = widget.existingEvent?.rrule ?? '';
  late CustomTimetableColors _customTimetableColor = CustomTimetableColors.values.firstWhere(
    (element) => element.name == widget.existingEvent?.color,
    orElse: () => TimetableColors.defaultColor
  );

  late bool isEditingExisting = widget.existingEvent != null;

  bool validate() {
    if(_eventName.text.isEmpty) return false;
    return true;
  }

  void fetchTimetable() {
    Provider.of<TimetableProps>(context, listen: false).run(renew: true);
  }

  @override
  Widget build(BuildContext context) => AlertDialog(
      insetPadding: const EdgeInsets.all(20),
      contentPadding: const EdgeInsets.all(10),
      title: const Text('Termin hinzufügen'),
      content: SingleChildScrollView(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            ListTile(
              title: TextField(
                controller: _eventName,
                autofocus: true,
                decoration: const InputDecoration(
                  labelText: 'Terminname',
                  border: OutlineInputBorder()
                ),
                onTapOutside: (PointerDownEvent event) => FocusBehaviour.textFieldTapOutside(context),
              ),
            ),
            ListTile(
              title: TextField(
                controller: _eventDescription,
                maxLines: 2,
                minLines: 2,
                decoration: const InputDecoration(
                  labelText: 'Beschreibung',
                  border: OutlineInputBorder()
                ),
                onTapOutside: (PointerDownEvent event) => FocusBehaviour.textFieldTapOutside(context),
              ),
            ),
            const Divider(),
            ListTile(
              leading: const Icon(Icons.date_range_outlined),
              title: Text(Jiffy.parseFromDateTime(_date).yMMMd),
              subtitle: const Text('Datum'),
              onTap: () async {
                final pickedDate = await showDatePicker(
                  context: context,
                  initialDate: _date,
                  firstDate: DateTime.now().subtract(const Duration(days: 30)),
                  lastDate: DateTime.now().add(const Duration(days: 30)),
                );
                if (pickedDate != null && pickedDate != _date) {
                  setState(() {
                    _date = pickedDate;
                  });
                }
              },
            ),
            ListTile(
              leading: const Icon(Icons.access_time_outlined),
              title: Text('${_startTime.format(context).toString()} - ${_endTime.format(context).toString()}'),
              subtitle: const Text('Zeitraum'),
              onTap: () async {
                TimeRange timeRange = await showTimeRangePicker(
                  context: context,
                  start: _startTime,
                  end: _endTime,
                  disabledTime: TimeRange(startTime: const TimeOfDay(hour: 16, minute: 30), endTime: const TimeOfDay(hour: 08, minute: 00)),
                  disabledColor: Colors.grey,
                  paintingStyle: PaintingStyle.fill,
                  interval: const Duration(minutes: 5),
                  fromText: 'Beginnend',
                  toText: 'Endend',
                  strokeColor: Theme.of(context).colorScheme.secondary,
                  minDuration: const Duration(minutes: 15),
                  selectedColor: Theme.of(context).primaryColor,
                  ticks: 24,
                );

                setState(() {
                  _startTime = timeRange.startTime;
                  _endTime = timeRange.endTime;
                });
              },
            ),
            const Divider(),
            ListTile(
              leading: const Icon(Icons.color_lens_outlined),
              title: const Text('Farbgebung'),
              trailing: DropdownButton<CustomTimetableColors>(
                value: _customTimetableColor,
                icon: const Icon(Icons.arrow_drop_down),
                items: CustomTimetableColors.values.map((e) => DropdownMenuItem<CustomTimetableColors>(
                  value: e,
                  enabled: e != _customTimetableColor,
                  child: Row(
                    children: [
                      Icon(Icons.circle, color: TimetableColors.getDisplayOptions(e).color),
                      const SizedBox(width: 10),
                      Text(TimetableColors.getDisplayOptions(e).displayName),
                    ],
                  ),
                )).toList(),
                onChanged: (e) {
                  setState(() {
                    _customTimetableColor = e!;
                  });
                },
              ),
            ),
            const Divider(),
            RRuleGenerator(
              config: RRuleGeneratorConfig(
                headerEnabled: true,
                weekdayBackgroundColor: Theme.of(context).colorScheme.secondary,
                weekdaySelectedBackgroundColor: Theme.of(context).primaryColor,
                weekdayColor: Colors.black,
              ),
              initialRRule: _recurringRule,
              textDelegate: const GermanRRuleTextDelegate(),
              onChange: (String newValue) {
                log('Rule: $newValue');
                setState(() {
                  _recurringRule = newValue;
                });
              },
            )
          ],
        ),
      ),
      actions: <Widget>[
        TextButton(
          onPressed: () {
            Navigator.of(context).pop();
          },
          child: const Text('Abbrechen'),
        ),
        TextButton(
          onPressed: () {
            if(!validate()) return;

            var editedEvent = CustomTimetableEvent(
              id: '',
              title: _eventName.text,
              description: _eventDescription.text,
              startDate: _date.withTime(_startTime),
              endDate: _date.withTime(_endTime),
              color: _customTimetableColor.name,
              rrule: _recurringRule,
              createdAt: DateTime.now(),
              updatedAt: DateTime.now(),
            );

            if(!isEditingExisting) {
              AddCustomTimetableEvent(
                  AddCustomTimetableEventParams(
                      AccountData().getUserSecret(),
                      editedEvent
                  )
              ).run().then((value) {
                Navigator.of(context).pop();
                fetchTimetable();
              })
              .catchError((error, stack) {
                InfoDialog.show(context, error.toString());
              });
            } else {
              UpdateCustomTimetableEvent(
                UpdateCustomTimetableEventParams(
                  widget.existingEvent?.id ?? '',
                  editedEvent
                )
              ).run().then((value) {
                Navigator.of(context).pop();
                fetchTimetable();
              })
              .catchError((error, stack) {
                InfoDialog.show(context, error.toString());
              });
            }


          },
          child: Text(isEditingExisting ? 'Speichern' : 'Erstellen'),
        ),
      ],
    );
}