import 'package:diameter/components/detail.dart';
import 'package:diameter/components/forms/boolean_form_field.dart';
import 'package:diameter/localization_keys.dart';
import 'package:diameter/utils/dialog_utils.dart';
import 'package:diameter/models/bolus.dart';
import 'package:diameter/models/settings.dart';
import 'package:diameter/navigation.dart';
import 'package:diameter/screens/bolus/bolus_detail.dart';
import 'package:flutter/material.dart';
import 'package:diameter/components/forms/form_wrapper.dart';
import 'package:diameter/models/bolus_profile.dart';
import 'package:diameter/screens/bolus/bolus_list.dart';
import 'package:flutter_translate/flutter_translate.dart';

class BolusProfileDetailScreen extends StatefulWidget {
  static const String routeName = '/bolus-profile';
  final int id;
  final bool active;

  const BolusProfileDetailScreen({Key? key, this.active = false, this.id = 0})
      : super(key: key);

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

class _BolusProfileDetailScreenState extends State<BolusProfileDetailScreen> {
  BolusProfile? _bolusProfile;
  List<Bolus> _bolusRates = [];
  bool _isNew = true;

  final GlobalKey<FormState> _bolusProfileForm = GlobalKey<FormState>();
  final ScrollController _scrollController = ScrollController();

  late FloatingActionButton addBolusButton;
  late IconButton refreshButton;
  late IconButton closeButton;
  late DetailBottomRow detailBottomRow;
  late DetailBottomRow detailBottomRowWhileSaving;

  FloatingActionButton? actionButton;
  List<Widget> appBarActions = [];
  DetailBottomRow? bottomNav;

  final _nameController = TextEditingController(text: '');
  final _notesController = TextEditingController(text: '');
  bool _active = false;

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

    reload();

    if (_bolusProfile != null) {
      _nameController.text = _bolusProfile!.name;
      _active = _bolusProfile!.active;
      _notesController.text = _bolusProfile!.notes ?? '';
    }
    if (widget.active) {
      _active = true;
    }

    addBolusButton = FloatingActionButton(
      onPressed: handleAddNewBolus,
      child: const Icon(Icons.add),
    );

    refreshButton = IconButton(
      icon: const Icon(Icons.refresh),
      onPressed: reload,
    );

    closeButton = IconButton(
      onPressed: handleCancelAction,
      icon: const Icon(Icons.close),
    );

    detailBottomRow = DetailBottomRow(
      onCancel: handleCancelAction,
      onAction: handleSaveAction,
      onMiddleAction: () => handleSaveAction(close: true),
    );

    detailBottomRowWhileSaving = DetailBottomRow(
      onCancel: handleCancelAction,
      onAction: null,
    );

    actionButton = null;
    appBarActions = [closeButton];
    bottomNav = detailBottomRow;
  }

  @override
  void dispose() {
    _scrollController.dispose();
    _nameController.dispose();
    _notesController.dispose();
    super.dispose();
  }

  void reload({String? message}) {
    if (widget.id != 0) {
      setState(() {
        _bolusProfile = BolusProfile.get(widget.id);
        _bolusRates = Bolus.getAllForProfile(widget.id);
      });
      _isNew = _bolusProfile == null;
    }

    setState(() {
      if (message != null) {
        var snackBar = SnackBar(
          content: Text(message),
          duration: const Duration(seconds: 2),
        );
        ScaffoldMessenger.of(context)
          ..removeCurrentSnackBar()
          ..showSnackBar(snackBar);
      }
    });
  }

  Future<void> checkActiveProfiles() async {
    int _activeCount = BolusProfile.activeCount();

    if (_active &&
        (_activeCount > 1 ||
            _activeCount == 1 && (_isNew || !_bolusProfile!.active))) {
      await showDialog(
          context: context,
          builder: (BuildContext context) {
            return AlertDialog(
              content: Text(translate(LocalizationKeys.bolusProfile_warnings_activeAlreadySet)),
              actions: [
                TextButton(
                  onPressed: () => Navigator.pop(context, 0),
                  child: Text(translate(LocalizationKeys.bolusProfile_warnings_resolve_ignore).toUpperCase()),
                ),
                TextButton(
                  onPressed: () => Navigator.pop(context, 1),
                  child: Text(translate(LocalizationKeys.bolusProfile_warnings_resolve_deactivateProfile).toUpperCase()),
                ),
                ElevatedButton(
                  onPressed: () => Navigator.pop(context, 2),
                  child: Text(translate(LocalizationKeys.bolusProfile_warnings_resolve_deactivateOthers).toUpperCase()),
                )
              ],
            );
          }).then((value) async {
        if (value == 1) {
          setState(() {
            _active = false;
          });
        } else if (value == 2) {
          BolusProfile.setAllInactive();
        }
      });
    } else if (!_active &&
        ((_isNew && _activeCount == 0) ||
            (!_isNew && _activeCount == 1 && _bolusProfile!.active))) {
      await showDialog(
          context: context,
          builder: (BuildContext context) {
            return AlertDialog(
              content: Text(translate(LocalizationKeys.bolusProfile_warnings_noActiveOnCreate)),
              actions: [
                TextButton(
                  onPressed: () => Navigator.pop(context, 0),
                  child: Text(translate(LocalizationKeys.bolusProfile_warnings_resolve_ignore).toUpperCase()),
                ),
                TextButton(
                  onPressed: () => Navigator.pop(context, 1),
                  child: Text(translate(LocalizationKeys.bolusProfile_warnings_resolve_activateCurrent).toUpperCase()),
                ),
              ],
            );
          }).then((value) {
        if (value == 1) {
          setState(() {
            _active = true;
          });
        }
      });
    }
  }

  void handleAddNewBolus() async {
    TimeOfDay? suggestedStartTime;
    TimeOfDay? suggestedEndTime;

    if (_bolusRates.isEmpty) {
      suggestedStartTime = const TimeOfDay(hour: 0, minute: 0);
      suggestedEndTime = const TimeOfDay(hour: 0, minute: 0);
    } else {
      _bolusRates.asMap().forEach((index, bolus) {
        if (suggestedStartTime == null && suggestedEndTime == null) {
          if (index == 0 &&
              (bolus.startTime.hour != 0 || bolus.startTime.minute != 0)) {
            suggestedStartTime = const TimeOfDay(hour: 0, minute: 0);
            suggestedEndTime = TimeOfDay.fromDateTime(bolus.startTime);
          } else if ((index == _bolusRates.length - 1) &&
              (bolus.endTime.hour != 0 || bolus.endTime.minute != 0)) {
            suggestedStartTime = TimeOfDay.fromDateTime(bolus.endTime);
            suggestedEndTime = const TimeOfDay(hour: 0, minute: 0);
          } else if (index != 0) {
            var lastEndTime = _bolusRates[index - 1].endTime;
            if (bolus.startTime.isAfter(lastEndTime)) {
              suggestedStartTime = TimeOfDay.fromDateTime(lastEndTime);
              suggestedEndTime = TimeOfDay.fromDateTime(bolus.startTime);
            }
          }
        }
      });
    }

    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) {
          return BolusDetailScreen(
            bolusProfileId: widget.id,
            suggestedStartTime: suggestedStartTime,
            suggestedEndTime: suggestedEndTime,
          );
        },
      ),
    ).then((result) => reload(message: result?[0]));
  }

  void handleSaveAction({bool close = false}) async {
    setState(() {
      bottomNav = detailBottomRowWhileSaving;
    });

    if (_bolusProfileForm.currentState!.validate()) {
      await checkActiveProfiles();
      BolusProfile bolusProfile = BolusProfile(
        id: widget.id,
        name: _nameController.text,
        active: _active,
        notes: _notesController.text,
      );
      BolusProfile.put(bolusProfile);

      if (close) {
        Navigator.pop(context, [
          translate(
            LocalizationKeys.bolusProfile_saved,
            args: {
              "status": _isNew ? '${translate(LocalizationKeys.bolusProfile_new)} ' : ''
            },
          ), bolusProfile
        ],
      );
      } else {
        if (_isNew) {
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) =>
                  BolusProfileDetailScreen(id: bolusProfile.id),
            ),
          ).then((result) => Navigator.pop(context, result));
        } else {
          reload(message: translate(LocalizationKeys.bolusProfile_saved));
        }
      }
    }

    setState(() {
      bottomNav = detailBottomRow;
    });
  }

  void handleCancelAction() {
    if (Settings.get().showConfirmationDialogOnCancel &&
            (_isNew &&
                (_active != widget.active ||
                    _nameController.text != '' ||
                    _notesController.text != '')) ||
        (!_isNew &&
            (_bolusProfile!.active != _active ||
                _bolusProfile!.name != _nameController.text ||
                (_bolusProfile!.notes ?? '') != _notesController.text))) {
      DialogUtils.showCancelConfirmationDialog(
        context: context,
        isNew: _isNew,
        onSave: handleSaveAction,
      );
    } else {
      Navigator.pop(context);
    }
  }

  void renderTabButtons(index) {
    if (_bolusProfile != null) {
      setState(() {
        switch (index) {
          case 1:
            actionButton = addBolusButton;
            appBarActions = [refreshButton, closeButton];
            bottomNav = null;
            break;
          default:
            actionButton = null;
            appBarActions = [closeButton];
            bottomNav = detailBottomRow;
        }
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: _isNew ? 1 : 2,
      child: Builder(builder: (BuildContext context) {
        final TabController tabController = DefaultTabController.of(context)!;
        tabController.addListener(() {
          renderTabButtons(tabController.index);
        });

        List<Widget> tabs = [
          Scrollbar(
            controller: _scrollController,
            child: SingleChildScrollView(
              controller: _scrollController,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: [
                  FormWrapper(
                    formState: _bolusProfileForm,
                    fields: [
                      TextFormField(
                        controller: _nameController,
                        decoration: InputDecoration(
                          labelText: translate(LocalizationKeys.bolusProfile_fields_name),
                        ),
                        validator: (value) {
                          if (value!.trim().isEmpty) {
                            return translate(LocalizationKeys.bolusProfile_fields_validators_name);
                          }
                          return null;
                        },
                      ),
                      TextFormField(
                        decoration: InputDecoration(
                          labelText: translate(LocalizationKeys.bolusProfile_fields_notes),
                        ),
                        controller: _notesController,
                        keyboardType: TextInputType.multiline,
                        minLines: 2,
                        maxLines: 5,
                      ),
                      BooleanFormField(
                        value: _active,
                        onChanged: (value) {
                          setState(() {
                            _active = value;
                          });
                        },
                        label: translate(LocalizationKeys.bolusProfile_fields_active),
                      ),
                    ],
                  ),
                ],
              ),
            ),
          ),
        ];

        if (!_isNew) {
          tabs.add(BolusListScreen(
              bolusProfile: _bolusProfile!,
              bolusRates: _bolusRates,
              reload: reload));
        }

        return Scaffold(
          appBar: AppBar(
            title: Text(translate(LocalizationKeys.bolusProfile_detail_title, args: {
                "status": _isNew ? '${translate(LocalizationKeys.bolusProfile_new)} ' : '',
                "profileName": _bolusProfile!.name,
              })),
            bottom: _isNew
                ? PreferredSize(child: Container(), preferredSize: Size.zero)
                : TabBar(
                    tabs: [
                      Tab(text: translate(LocalizationKeys.bolusProfile_detail_tabs_profile).toUpperCase()),
                      Tab(text: translate(LocalizationKeys.bolusProfile_detail_tabs_rates).toUpperCase()),
                    ],
                  ),
            actions: appBarActions,
          ),
          drawer: const Navigation(
              currentLocation: BolusProfileDetailScreen.routeName),
          body: TabBarView(
            children: tabs,
          ),
          bottomNavigationBar: bottomNav,
          floatingActionButton: actionButton,
          floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
        );
      }),
    );
  }
}
