import 'dart:math';

import 'package:diameter/components/detail.dart';
import 'package:diameter/components/forms/boolean_form_field.dart';
import 'package:diameter/components/forms/number_form_field.dart';
import 'package:diameter/utils/dialog_utils.dart';
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
import 'package:diameter/components/forms/form_wrapper.dart';
import 'package:diameter/models/bolus.dart';
import 'package:diameter/models/log_bolus.dart';
import 'package:diameter/models/log_entry.dart';
import 'package:diameter/models/log_meal.dart';
import 'package:diameter/models/settings.dart';
import 'package:diameter/navigation.dart';
import 'package:diameter/screens/log/log_entry/log_meal_detail.dart';
import 'package:diameter/utils/utils.dart';
import 'package:flutter/material.dart';

enum BolusType {
  meal,
  glucose,
}

enum GlucoseParameter {
  mgdlCurrent,
  mgdlTarget,
  mgdlCorrection,
  mmolCurrent,
  mmolTarget,
  mmolCorrection,
}

class LogBolusDetailScreen extends StatefulWidget {
  static const String routeName = '/log-bolus';

  final int logEntryId;
  final int id;

  const LogBolusDetailScreen({Key? key, this.logEntryId = 0, this.id = 0})
      : super(key: key);

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

class _LogBolusDetailScreenState extends State<LogBolusDetailScreen> {
  LogEntry? _logEntry;
  LogBolus? _logBolus;

  bool _isNew = true;
  bool _isSaving = false;

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

  final _unitsController = TextEditingController(text: '');
  final _carbsController = TextEditingController(text: '');
  final _mgPerDlCurrentController = TextEditingController(text: '');
  final _mgPerDlTargetController = TextEditingController(text: '');
  final _mgPerDlCorrectionController = TextEditingController(text: '');
  final _mmolPerLCurrentController = TextEditingController(text: '');
  final _mmolPerLTargetController = TextEditingController(text: '');
  final _mmolPerLCorrectionController = TextEditingController(text: '');
  final _delayController = TextEditingController(text: '');
  final _notesController = TextEditingController(text: '');

  final _delayedUnitsController = TextEditingController(text: '');
  final _immediateUnitsController = TextEditingController(text: '');

  final _mealController = TextEditingController(text: '');

  bool _setManually = false;
  BolusType _bolusType = BolusType.meal;
  LogMeal? _meal;
  Bolus? _rate;
  double _delayPercentage = 0;

  List<LogMeal> _logMeals = [];

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

    _logEntry = LogEntry.get(widget.logEntryId);
    _logMeals = LogMeal.getRecentWithoutBolus(widget.logEntryId);

    if (widget.id != 0) {
      _carbsController.text = (_logBolus!.carbs ?? '').toString();
      _delayController.text = (_logBolus!.delay ?? '').toString();
      _notesController.text = _logBolus!.notes ?? '';
      _setManually = _logBolus!.setManually;
      _meal = _logBolus!.meal.target;
      _mealController.text = (_meal ?? '').toString();
      _rate = _logBolus!.rate.target;
    }

    _rate ??= Bolus.getRateForTime(_logEntry?.time);

    _mgPerDlCurrentController.text = (_logBolus?.mgPerDlCurrent ??
            (LogEntry.hasUncorrectedGlucose(widget.logEntryId)
                ? _logEntry?.mgPerDl ?? 0
                : 0))
        .toString();
    _mgPerDlTargetController.text =
        (_logBolus?.mgPerDlTarget ?? Settings.targetMgPerDl).toString();
    _mgPerDlCorrectionController.text = (_logBolus?.mgPerDlCorrection ??
            max(
                (int.tryParse(_mgPerDlCurrentController.text) ?? 0) -
                    (int.tryParse(_mgPerDlTargetController.text) ?? 0),
                0))
        .toString();
    _mmolPerLCurrentController.text = (_logBolus?.mmolPerLCurrent ??
            (LogEntry.hasUncorrectedGlucose(widget.logEntryId)
                ? _logEntry?.mmolPerL ?? 0
                : 0))
        .toString();
    _mmolPerLTargetController.text =
        (_logBolus?.mmolPerLTarget ?? Settings.targetMmolPerL).toString();
    _mmolPerLCorrectionController.text = (_logBolus?.mmolPerLCorrection ??
            max(
                (double.tryParse(_mmolPerLCurrentController.text) ?? 0) -
                    (double.tryParse(_mmolPerLTargetController.text) ?? 0),
                0))
        .toString();

    _unitsController.text = (_logBolus?.units ??
            (_rate != null && !_setManually
                ? ((int.tryParse(_mgPerDlCorrectionController.text) ?? 0) /
                    ((_rate!.mgPerDl ?? 0) / _rate!.units))
                : 0))
        .toString();

    if (widget.id == 0 && LogEntry.hasUncorrectedGlucose(widget.logEntryId)) {
      _bolusType = BolusType.glucose;
    }

    calculateBolus();
  }

  @override
  void dispose() {
    _scrollController.dispose();
    _unitsController.dispose();
    _carbsController.dispose();
    _mgPerDlCurrentController.dispose();
    _mgPerDlTargetController.dispose();
    _mgPerDlCorrectionController.dispose();
    _mmolPerLCurrentController.dispose();
    _mmolPerLTargetController.dispose();
    _mmolPerLCorrectionController.dispose();
    _delayController.dispose();
    _notesController.dispose();
    _delayedUnitsController.dispose();
    _immediateUnitsController.dispose();
    _mealController.dispose();
    super.dispose();
  }

  void reload({String? message}) {
    if (widget.id != 0) {
      setState(() {
        _logBolus = LogBolus.get(widget.id);
      });
    }
    _isNew = _logBolus == null;

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

  void updateLogMeal(LogMeal? value) {
    setState(() {
      _meal = value;
      _mealController.text = (_meal ?? '').toString();
    });
    if (_meal != null) {
      if (_meal!.totalCarbs != null) {
        _carbsController.text = (_meal!.totalCarbs).toString();
      }
      if (_meal!.meal.hasValue) {
        if (_meal!.meal.target!.delayedBolusDuration != null) {
          _delayController.text =
              (_meal!.meal.target?.delayedBolusDuration).toString();
        }
        if (_meal!.meal.target!.delayedBolusDuration != null) {
          _delayPercentage = _meal!.meal.target!.delayedBolusPercentage!;
        }
      }
      calculateBolus();
    }
  }

  void onSelectMeal(LogMeal? meal) {
    updateLogMeal(meal);
    if (meal != null && meal.totalCarbs != null) {
      setState(() {
        _carbsController.text = meal.totalCarbs.toString();
        calculateBolus();
      });
    }
  }

  void calculateBolus() {
    if (_rate != null && !_setManually) {
      double? units;

      if (_bolusType == BolusType.glucose) {
        if (Settings.glucoseMeasurement == GlucoseMeasurement.mgPerDl) {
          units = (int.tryParse(_mgPerDlCorrectionController.text) ?? 0) /
              (_rate!.mgPerDl ?? 1) /
              _rate!.units;
        }
        if (Settings.glucoseMeasurement == GlucoseMeasurement.mmolPerL) {
          units = (int.tryParse(_mmolPerLCorrectionController.text) ?? 0) /
              (_rate!.mmolPerL ?? 1) /
              _rate!.units;
        }
      }
      if (_bolusType == BolusType.meal) {
        units = (double.tryParse(_carbsController.text) ?? 0) /
            (_rate!.carbs / _rate!.units);
      }

      updateDelayedRatio(totalUnitsUpdate: units);
    }
  }

  void onChangeGlucose() {
    int? mgPerDlCurrent;
    int? mgPerDlTarget;
    int? mgPerDlCorrection;

    double? mmolPerLCurrent;
    double? mmolPerLTarget;
    double? mmolPerLCorrection;

    if (Settings.glucoseMeasurement == GlucoseMeasurement.mgPerDl &&
        _mgPerDlCurrentController.text != '' &&
        _mgPerDlTargetController.text != '') {
      mgPerDlCurrent = int.tryParse(_mgPerDlCurrentController.text);
      mgPerDlTarget = int.tryParse(_mgPerDlTargetController.text);
      mgPerDlCorrection = max((mgPerDlCurrent ?? 0) - (mgPerDlTarget ?? 0), 0);
    }
    if (Settings.glucoseMeasurement == GlucoseMeasurement.mmolPerL &&
        _mmolPerLCurrentController.text != '') {
      mmolPerLCurrent = double.tryParse(_mmolPerLCurrentController.text);
      mmolPerLTarget = double.tryParse(_mmolPerLTargetController.text);
      mmolPerLCorrection =
          max((mmolPerLCurrent ?? 0) - (mmolPerLTarget ?? 0), 0);
    }

    if ((mgPerDlCurrent != null && mmolPerLCurrent == null) ||
        (mgPerDlTarget != null && mmolPerLTarget == null) ||
        (mgPerDlCorrection != null && mmolPerLCorrection == null)) {
      setState(() {
        _mgPerDlCorrectionController.text = (mgPerDlCorrection ?? 0).toString();
        _mmolPerLCurrentController.text =
            Utils.convertMgPerDlToMmolPerL(mgPerDlCurrent ?? 0).toString();
        _mmolPerLTargetController.text =
            Utils.convertMgPerDlToMmolPerL(mgPerDlTarget ?? 0).toString();
        _mmolPerLCorrectionController.text =
            Utils.convertMgPerDlToMmolPerL(mgPerDlCorrection ?? 0).toString();
        calculateBolus();
      });
    }
    if ((mmolPerLCurrent != null && mgPerDlCurrent == null) ||
        (mmolPerLTarget != null && mgPerDlTarget == null) ||
        (mmolPerLCorrection != null && mgPerDlCorrection == null)) {
      setState(() {
        _mmolPerLCurrentController.text = (mmolPerLCorrection ?? 0).toString();
        _mgPerDlCurrentController.text =
            Utils.convertMmolPerLToMgPerDl(mmolPerLCurrent ?? 0).toString();
        _mgPerDlTargetController.text =
            Utils.convertMmolPerLToMgPerDl(mmolPerLTarget ?? 0).toString();
        _mgPerDlCorrectionController.text =
            Utils.convertMmolPerLToMgPerDl(mmolPerLCorrection ?? 0).toString();
        calculateBolus();
      });
    }
  }

  void updateDelayedRatio({
      double? totalUnitsUpdate,
      double? delayedUnitsUpdate,
      double? immediateUnitsUpdate,
      double? percentageUpdate
  }) {
    int precision = Utils.getFractionDigitsLength(Settings.insulinSteps);

    double? totalUnits;
    double? delayedUnits;
    double? immediateUnits;

    if (totalUnitsUpdate != null) {
      totalUnits = Utils.roundToMultipleOfBase(totalUnitsUpdate, Settings.insulinSteps);
    } else if (double.tryParse(_unitsController.text) != null) {
      totalUnits = Utils.roundToMultipleOfBase(double.tryParse(_unitsController.text)!, Settings.insulinSteps);
    }
    
    if (delayedUnitsUpdate != null) {
      delayedUnits = Utils.roundToMultipleOfBase(delayedUnitsUpdate, Settings.insulinSteps);
    } else if (double.tryParse(_delayedUnitsController.text) != null) {
      delayedUnits = Utils.roundToMultipleOfBase(double.tryParse(_delayedUnitsController.text)!, Settings.insulinSteps);
    }

    if (immediateUnitsUpdate != null) {
      immediateUnits = Utils.roundToMultipleOfBase(immediateUnitsUpdate, Settings.insulinSteps);
    } else if (double.tryParse(_immediateUnitsController.text) != null) {
      immediateUnits = Utils.roundToMultipleOfBase(double.tryParse(_immediateUnitsController.text)!, Settings.insulinSteps);
    }

    if (totalUnits == null) {
      if (percentageUpdate != null) {
        if (immediateUnits != null) {
          totalUnits = immediateUnits / (100 - percentageUpdate) * 100;
        } else if (delayedUnits != null) {
          totalUnits = delayedUnits / percentageUpdate * 100;
        }
      } else if (delayedUnits != null && immediateUnits != null) {
        totalUnits = Utils.addDoublesWithPrecision(
            delayedUnits, immediateUnits, precision);
      }

      if (totalUnits != null) {
        totalUnits =
          Utils.roundToMultipleOfBase(totalUnits, Settings.insulinSteps);
      }
    }

    setState(() {
      _unitsController.text = Utils.toStringMatchingTemplateFractionPrecision(
          totalUnits ?? 0, Settings.insulinSteps);
    });

    if (totalUnits != null) {
      double percentage = percentageUpdate ?? _delayPercentage;

      if (totalUnitsUpdate != null || percentageUpdate != null) {
        immediateUnits = Utils.roundToMultipleOfBase(
            totalUnits * (100 - percentage) / 100, Settings.insulinSteps);
      } else if (delayedUnitsUpdate != null) {
        immediateUnits = totalUnits - delayedUnits!;
      }

      if (immediateUnits != null) {
        delayedUnits = Utils.addDoublesWithPrecision(
            totalUnits, -immediateUnits, precision);

        setState(() {
          _immediateUnitsController.text =
              Utils.toStringMatchingTemplateFractionPrecision(
                  immediateUnits!, Settings.insulinSteps);
          _delayedUnitsController.text =
              Utils.toStringMatchingTemplateFractionPrecision(
                  delayedUnits!, Settings.insulinSteps);
          if (totalUnits != 0) {
            _delayPercentage = delayedUnits / totalUnits! * 100;
          }
        });
      }
    }
  }

  void handleSaveAction() async {
    setState(() {
      _isSaving = true;
    });
    if (_logBolusForm.currentState!.validate()) {
      LogBolus logBolus;
      LogBolus? delayedBolus;

      if ((int.tryParse(_delayController.text) ?? 0) != 0 &&
          _delayPercentage != 0 &&
          _delayPercentage != 100) {
        logBolus = LogBolus(
          id: widget.id,
          units: double.tryParse(_immediateUnitsController.text) ?? 0,
          setManually: _setManually,
          notes: _notesController.text,
        );
        delayedBolus = LogBolus(
          delay: int.tryParse(_delayController.text),
          units: double.tryParse(_delayedUnitsController.text) ?? 0,
          setManually: _setManually,
          notes: _notesController.text,
        );
      } else {
        logBolus = LogBolus(
          id: widget.id,
          units: double.tryParse(_unitsController.text) ?? 0,
          delay: _delayPercentage == 100
              ? int.tryParse(_delayController.text)
              : null,
          setManually: _setManually,
          notes: _notesController.text,
        );
      }

      if (_bolusType == BolusType.meal) {
        logBolus.carbs = double.tryParse(_carbsController.text);
        if (delayedBolus != null) {
          delayedBolus.carbs = double.tryParse(_carbsController.text);
        }
        logBolus.mgPerDlCurrent = null;
        logBolus.mmolPerLCurrent = null;
      } else {
        logBolus.carbs = null;
        logBolus.mgPerDlCurrent = int.tryParse(_mgPerDlCurrentController.text);
        logBolus.mmolPerLCurrent =
            double.tryParse(_mmolPerLCurrentController.text);
        logBolus.mgPerDlTarget = int.tryParse(_mgPerDlTargetController.text);
        logBolus.mmolPerLTarget =
            double.tryParse(_mmolPerLTargetController.text);
        logBolus.mgPerDlCorrection =
            int.tryParse(_mgPerDlCorrectionController.text);
        logBolus.mmolPerLCorrection =
            double.tryParse(_mmolPerLCorrectionController.text);
        if (delayedBolus != null) {
          delayedBolus.mgPerDlCurrent =
              int.tryParse(_mgPerDlCurrentController.text);
          delayedBolus.mmolPerLCurrent =
              double.tryParse(_mmolPerLCurrentController.text);
          delayedBolus.mgPerDlTarget =
              int.tryParse(_mgPerDlTargetController.text);
          delayedBolus.mmolPerLTarget =
              double.tryParse(_mmolPerLTargetController.text);
          delayedBolus.mgPerDlCorrection =
              int.tryParse(_mgPerDlCorrectionController.text);
          delayedBolus.mmolPerLCorrection =
              double.tryParse(_mmolPerLCorrectionController.text);
        }
      }
      logBolus.logEntry.target = _logEntry;
      logBolus.meal.target = _meal;
      logBolus.rate.target = _rate;
      LogBolus.put(logBolus);

      if (delayedBolus != null) {
        delayedBolus.logEntry.target = _logEntry;
        delayedBolus.meal.target = _meal;
        delayedBolus.rate.target = _rate;
        LogBolus.put(delayedBolus);
      }

      Navigator.pop(context,
          ['${_isNew ? 'New' : ''} Bolus Saved', logBolus, delayedBolus]);
    }
    setState(() {
      _isSaving = false;
    });
  }

  void handleCancelAction() {
    if (Settings.get().showConfirmationDialogOnCancel &&
        ((_isNew &&
                (_carbsController.text != '' ||
                    (_bolusType == BolusType.glucose &&
                        (_mgPerDlCurrentController.text !=
                                (_logEntry?.mgPerDl.toString() ?? '') ||
                            _mmolPerLCurrentController.text !=
                                (_logEntry?.mmolPerL.toString() ?? ''))) ||
                    _mgPerDlTargetController.text !=
                        Settings.targetMgPerDl.toString() ||
                    _mmolPerLTargetController.text !=
                        Settings.targetMmolPerL.toString() ||
                    _delayController.text != '' ||
                    _setManually ||
                    _notesController.text != '')) ||
            (!_isNew &&
                (double.tryParse(_unitsController.text) != _logBolus!.units ||
                    double.tryParse(_carbsController.text) !=
                        _logBolus!.carbs ||
                    int.tryParse(_mgPerDlCurrentController.text) !=
                        _logBolus!.mgPerDlCurrent ||
                    int.tryParse(_mgPerDlTargetController.text) !=
                        _logBolus!.mgPerDlTarget ||
                    int.tryParse(_mgPerDlCorrectionController.text) !=
                        _logBolus!.mgPerDlCorrection ||
                    double.tryParse(_mmolPerLCurrentController.text) !=
                        _logBolus!.mmolPerLCurrent ||
                    double.tryParse(_mmolPerLTargetController.text) !=
                        _logBolus!.mmolPerLTarget ||
                    double.tryParse(_mmolPerLCorrectionController.text) !=
                        _logBolus!.mmolPerLCorrection ||
                    int.tryParse(_delayController.text) != _logBolus!.delay ||
                    _setManually != _logBolus!.setManually ||
                    _notesController.text != (_logBolus!.notes ?? ''))))) {
      DialogUtils.showCancelConfirmationDialog(
        context: context,
        isNew: _isNew,
        onSave: handleSaveAction,
      );
    } else {
      Navigator.pop(context);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(_isNew ? 'New Bolus' : 'Edit Bolus'),
      ),
      drawer: const Navigation(currentLocation: LogBolusDetailScreen.routeName),
      body: Scrollbar(
        controller: _scrollController,
        child: SingleChildScrollView(
          controller: _scrollController,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: <Widget>[
              FormWrapper(
                formState: _logBolusForm,
                fields: [
                  Row(
                    children: [
                      Expanded(
                        child: NumberFormField(
                          label: 'Bolus Units',
                          suffix: ' U',
                          controller: _unitsController,
                          step: Settings.insulinSteps,
                          autoRoundToMultipleOfStep: true,
                          onChanged: (value) {
                            setState(() {
                              _setManually = true;
                            });
                            updateDelayedRatio(totalUnitsUpdate: value);
                          },
                        ),
                      ),
                      Expanded(
                        child: BooleanFormField(
                          contentPadding: const EdgeInsets.only(
                              left: 10.0, right: 10.0, top: 10.0),
                          value: _setManually,
                          label: 'set manually',
                          onChanged: (value) {
                            setState(() {
                              _setManually = value;
                              calculateBolus();
                            });
                          },
                        ),
                      ),
                    ],
                  ),
                  Row(
                    children: [
                      Expanded(
                        child: RadioListTile(
                            title: const Text('for glucose'),
                            groupValue: _bolusType,
                            value: BolusType.glucose,
                            onChanged: (_) {
                              setState(() {
                                _bolusType = BolusType.glucose;
                                calculateBolus();
                              });
                            }),
                      ),
                      Expanded(
                        child: RadioListTile(
                            title: const Text('for meal'),
                            groupValue: _bolusType,
                            value: BolusType.meal,
                            onChanged: (value) {
                              setState(() {
                                _bolusType = BolusType.meal;
                                calculateBolus();
                              });
                            }),
                      ),
                    ],
                  ),
                  Column(
                    children: _bolusType == BolusType.glucose
                        ? [
                            Row(
                              children: Settings.glucoseMeasurement ==
                                          GlucoseMeasurement.mgPerDl ||
                                      [
                                        GlucoseDisplayMode.both,
                                        GlucoseDisplayMode.bothForDetail
                                      ].contains(Settings.glucoseDisplayMode)
                                  ? [
                                      Expanded(
                                        child: Padding(
                                          padding:
                                              const EdgeInsets.only(right: 5.0),
                                          child: NumberFormField(
                                            label: 'Current',
                                            suffix: 'mg/dl',
                                            controller:
                                                _mgPerDlCurrentController,
                                            onChanged: (_) => onChangeGlucose(),
                                            showSteppers: false,
                                          ),
                                        ),
                                      ),
                                      Expanded(
                                        child: Padding(
                                          padding: const EdgeInsets.symmetric(
                                              horizontal: 5.0),
                                          child: NumberFormField(
                                            label: 'Target',
                                            suffix: 'mg/dl',
                                            controller:
                                                _mgPerDlTargetController,
                                            onChanged: (_) => onChangeGlucose(),
                                            showSteppers: false,
                                          ),
                                        ),
                                      ),
                                      Expanded(
                                        child: Padding(
                                          padding:
                                              const EdgeInsets.only(left: 5.0),
                                          child: TextFormField(
                                            decoration: const InputDecoration(
                                              labelText: 'Correction',
                                              suffixText: 'mg/dl',
                                            ),
                                            controller:
                                                _mgPerDlCorrectionController,
                                            readOnly: true,
                                          ),
                                        ),
                                      ),
                                    ]
                                  : [],
                            ),
                            Padding(
                              padding: EdgeInsets.only(
                                  top: [
                                GlucoseDisplayMode.both,
                                GlucoseDisplayMode.bothForDetail
                              ].contains(Settings.glucoseDisplayMode)
                                      ? 10.0
                                      : 0.0),
                              child: Row(
                                children: Settings.glucoseMeasurement ==
                                            GlucoseMeasurement.mmolPerL ||
                                        [
                                          GlucoseDisplayMode.both,
                                          GlucoseDisplayMode.bothForDetail
                                        ].contains(Settings.glucoseDisplayMode)
                                    ? [
                                        Expanded(
                                          child: Padding(
                                            padding: const EdgeInsets.only(
                                                right: 5.0),
                                            child: NumberFormField(
                                              label: 'Current',
                                              suffix: 'mmol/l',
                                              controller:
                                                  _mmolPerLCurrentController,
                                              onChanged: (_) =>
                                                  onChangeGlucose(),
                                              showSteppers: false,
                                            ),
                                          ),
                                        ),
                                        Expanded(
                                          child: Padding(
                                            padding: const EdgeInsets.symmetric(
                                                horizontal: 5.0),
                                            child: NumberFormField(
                                              label: 'Target',
                                              suffix: 'mmol/l',
                                              controller:
                                                  _mmolPerLTargetController,
                                              onChanged: (_) =>
                                                  onChangeGlucose(),
                                              showSteppers: false,
                                            ),
                                          ),
                                        ),
                                        Expanded(
                                          child: Padding(
                                            padding: const EdgeInsets.only(
                                                left: 5.0),
                                            child: TextFormField(
                                              decoration: const InputDecoration(
                                                labelText: 'Correction',
                                                suffixText: 'mmol/l',
                                              ),
                                              controller:
                                                  _mmolPerLCorrectionController,
                                              readOnly: true,
                                            ),
                                          ),
                                        ),
                                      ]
                                    : [],
                              ),
                            ),
                          ]
                        : [
                            Row(
                              children: [
                                Expanded(
                                  child: AutoCompleteDropdownButton<LogMeal>(
                                    controller: _mealController,
                                    selectedItem: _meal,
                                    label: 'Meal',
                                    items: _logMeals,
                                    onChanged: onSelectMeal,
                                  ),
                                ),
                                IconButton(
                                  onPressed: () {
                                    Navigator.push(
                                      context,
                                      MaterialPageRoute(
                                        builder: (context) => _meal == null
                                            ? const LogMealDetailScreen()
                                            : LogMealDetailScreen(
                                                id: _meal!.id),
                                      ),
                                    ).then((result) {
                                      updateLogMeal(result?[1]);
                                      reload(message: result?[0]);
                                    });
                                  },
                                  icon: Icon(
                                      _meal == null ? Icons.add : Icons.edit),
                                ),
                              ],
                            ),
                            Padding(
                              padding: const EdgeInsets.only(top: 10.0),
                              child: NumberFormField(
                                label: 'Carbs',
                                suffix: Settings.nutritionMeasurementSuffix,
                                controller: _carbsController,
                                step: Settings.nutritionSteps,
                                onChanged: (value) {
                                  _carbsController.text =
                                      (value ?? 0).toString();
                                  calculateBolus();
                                },
                              ),
                            ),
                          ],
                  ),
                  Row(
                    children: [
                      Expanded(
                        child: TextFormField(
                          decoration: const InputDecoration(
                            labelText: 'Delayed Bolus Duration',
                            suffixText: ' min',
                          ),
                          controller: _delayController,
                          onChanged: (value) => setState(() {}),
                          keyboardType: const TextInputType.numberWithOptions(),
                        ),
                      ),
                      Expanded(
                        child: Slider(
                          label: '${_delayPercentage.floor().toString()}%',
                          divisions: 100,
                          value: _delayPercentage,
                          min: 0,
                          max: 100,
                          onChanged: (value) {
                            updateDelayedRatio(percentageUpdate: value);
                          },
                        ),
                      ),
                      const Text('%', textScaleFactor: 1.5),
                    ],
                  ),
                  Row(
                    children: (int.tryParse(_delayController.text) ?? 0) != 0
                        ? [
                            Expanded(
                              child: Padding(
                                padding: const EdgeInsets.only(right: 5.0),
                                child: NumberFormField(
                                  label: 'Immediate Bolus',
                                  suffix: ' U',
                                  controller: _immediateUnitsController,
                                  max: double.tryParse(_unitsController.text),
                                  step: Settings.insulinSteps,
                                  readOnly: true,
                                  onChanged: (value) => updateDelayedRatio(
                                      immediateUnitsUpdate: value),
                                ),
                              ),
                            ),
                            Expanded(
                              child: Padding(
                                padding: const EdgeInsets.only(left: 5.0),
                                child: NumberFormField(
                                    label: 'Delayed Bolus',
                                    suffix: ' U',
                                    controller: _delayedUnitsController,
                                    max: double.tryParse(_unitsController.text),
                                    step: Settings.insulinSteps,
                                    readOnly: true,
                                    onChanged: (value) => {
                                          updateDelayedRatio(
                                              delayedUnitsUpdate: value),
                                        }),
                              ),
                            ),
                          ]
                        : [],
                  ),
                  TextFormField(
                    controller: _notesController,
                    decoration: const InputDecoration(
                      labelText: 'Notes',
                    ),
                    keyboardType: TextInputType.multiline,
                    minLines: 2,
                    maxLines: 5,
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
      bottomNavigationBar: DetailBottomRow(
        onCancel: handleCancelAction,
        onAction: _isSaving ? null : handleSaveAction,
      ),
    );
  }
}
