import 'package:diameter/utils/dialog_utils.dart';
import 'package:diameter/models/glucose_target.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_entry.dart';
import 'package:diameter/utils/date_time_utils.dart';
import 'package:flutter/material.dart';
import 'dart:math' as math;

class LogScreen extends StatefulWidget {
  static const String routeName = '/log';
  const LogScreen({Key? key}) : super(key: key);

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

class _LogScreenState extends State<LogScreen> {
  late List<LogEntry> _logEntries;

  final ScrollController _scrollController = ScrollController();
  final TextEditingController _dateController = TextEditingController(text: '');

  late DateTime _date;

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

    _date = DateTime.now();
    _dateController.text = DateTimeUtils.displayDate(_date);

    reload();
  }

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

  void reload({String? message}) {
    setState(() {
      _logEntries = LogEntry.getAllForDate(_date);
    });
    setState(() {
      if (message != null) {
        var snackBar = SnackBar(
          content: Text(message),
          duration: const Duration(seconds: 2),
        );
        ScaffoldMessenger.of(context)
          ..removeCurrentSnackBar()
          ..showSnackBar(snackBar);
      }
    });
  }

  void onDelete(LogEntry logEntry) {
    LogEntry.remove(logEntry.id);
    reload(message: 'Log Entry deleted');
  }

  void handleDeleteAction(LogEntry logEntry) async {
    if (Settings.get().showConfirmationDialogOnDelete) {
      DialogUtils.showConfirmationDialog(
        context: context,
        onConfirm: () => onDelete(logEntry),
        message: 'Are you sure you want to delete this Log Entry?',
      );
    } else {
      onDelete(logEntry);
    }
  }

  void onChangeDate(DateTime? date) {
    if (date != null) {
      setState(() {
        _date = DateTime(date.year, date.month, date.day);
        _dateController.text = DateTimeUtils.displayDate(date);
      });
      reload();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Log Entries'),
        actions: <Widget>[
          IconButton(
              onPressed: () => onChangeDate(DateTime.now()),
              icon: const Icon(Icons.today)),
          IconButton(onPressed: reload, icon: const Icon(Icons.refresh)),
        ],
      ),
      drawer: const Navigation(currentLocation: LogScreen.routeName),
      body: Column(
        children: [
          Row(
            children: [
              IconButton(
                onPressed: _date.isAtSameMomentAs(DateTime(2000, 1, 1))
                    ? null
                    : () =>
                        onChangeDate(_date.subtract(const Duration(days: 1))),
                icon: const Icon(Icons.arrow_back),
              ),
              Expanded(
                child: GestureDetector(
                  onTap: () async {
                    final newTime = await showDatePicker(
                      context: context,
                      initialDate: _date,
                      firstDate: DateTime(2000, 1, 1),
                      lastDate: DateTime.now().add(const Duration(days: 365)),
                    );
                    onChangeDate(newTime);
                  },
                  child: Expanded(
                    child: Text(
                      DateTimeUtils.displayDate(_date).toUpperCase(),
                      style: Theme.of(context).textTheme.subtitle2,
                      textAlign: TextAlign.center,
                    ),
                  ),
                ),
              ),
              IconButton(
                onPressed:
                    _date.add(const Duration(days: 1)).isBefore(DateTime.now())
                        ? () => onChangeDate(_date.add(const Duration(days: 1)))
                        : null,
                icon: const Icon(Icons.arrow_forward),
              ),
            ],
          ),
          Expanded(
            child: _logEntries.isNotEmpty
                ? Scrollbar(
                    controller: _scrollController,
                    child: ListView.builder(
                      controller: _scrollController,
                      padding: const EdgeInsets.all(10.0),
                      shrinkWrap: true,
                      itemCount: _logEntries.length,
                      itemBuilder: (context, index) {
                        LogEntry logEntry = _logEntries[index];
                        double bolus =
                            LogBolus.getTotalBolusForEntry(logEntry.id);
                        double carbs =
                            LogMeal.getTotalCarbsForEntry(logEntry.id);
                        TextStyle glucoseStyle = TextStyle(
                            color: GlucoseTarget.getColorForGlucose(
                                mgPerDl: logEntry.mgPerDl ?? 0,
                                mmolPerL: logEntry.mmolPerL ?? 0));
                        return Card(
                          child: ListTile(
                            onTap: () {
                              Navigator.push(
                                context,
                                MaterialPageRoute(
                                  builder: (context) =>
                                      LogEntryScreen(id: logEntry.id),
                                ),
                              ).then((result) => reload(message: result?[0]));
                            },
                            title: Row(
                              mainAxisAlignment: MainAxisAlignment.start,
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                Expanded(
                                  child: Text(
                                    DateTimeUtils.displayTime(logEntry.time),
                                  ),
                                ),
                                Expanded(
                                  child: Column(
                                    children: logEntry.mgPerDl != null &&
                                            (Settings.glucoseMeasurement ==
                                                    GlucoseMeasurement
                                                        .mgPerDl ||
                                                Settings.glucoseDisplayMode ==
                                                    GlucoseDisplayMode.both ||
                                                Settings.glucoseDisplayMode ==
                                                    GlucoseDisplayMode
                                                        .bothForList)
                                        ? [
                                            Row(
                                              mainAxisAlignment:
                                                  MainAxisAlignment.center,
                                              children: [
                                                Text(
                                                    logEntry.mgPerDl.toString(),
                                                    style: glucoseStyle),
                                                logEntry.glucoseTrend != null
                                                    ? Transform.rotate(
                                                        angle: logEntry
                                                                .glucoseTrend! *
                                                            math.pi /
                                                            180,
                                                        child: Icon(
                                                          Icons.arrow_upward,
                                                          color: glucoseStyle
                                                              .color,
                                                          size: 16.0,
                                                        ),
                                                      )
                                                    : Container(),
                                              ],
                                            ),
                                            const Text(
                                              'mg/dl',
                                              textScaleFactor: 0.75,
                                            ),
                                          ]
                                        : [],
                                  ),
                                ),
                                Expanded(
                                  child: Column(
                                    children: logEntry.mmolPerL != null &&
                                            (Settings.glucoseMeasurement ==
                                                    GlucoseMeasurement
                                                        .mmolPerL ||
                                                Settings.glucoseDisplayMode ==
                                                    GlucoseDisplayMode.both ||
                                                Settings.glucoseDisplayMode ==
                                                    GlucoseDisplayMode
                                                        .bothForList)
                                        ? [
                                            Row(
                                              mainAxisAlignment:
                                                  MainAxisAlignment.center,
                                              children: [
                                                Text(
                                                    logEntry.mmolPerL
                                                        .toString(),
                                                    style: glucoseStyle),
                                                logEntry.glucoseTrend != null
                                                    ? Transform.rotate(
                                                        angle: logEntry
                                                                .glucoseTrend! *
                                                            math.pi /
                                                            180,
                                                        child: Icon(
                                                          Icons.arrow_upward,
                                                          color: glucoseStyle
                                                              .color,
                                                          size: 16.0,
                                                        ),
                                                      )
                                                    : Container(),
                                              ],
                                            ),
                                            const Text(
                                              'mmol/l',
                                              textScaleFactor: 0.75,
                                            ),
                                          ]
                                        : [],
                                  ),
                                ),
                                Expanded(
                                  child: Column(
                                    children: (bolus > 0)
                                        ? [
                                            Text(bolus.toStringAsPrecision(3)),
                                            const Text('U',
                                                textScaleFactor: 0.75),
                                          ]
                                        : [],
                                  ),
                                ),
                                Expanded(
                                  child: Column(
                                    children: (carbs > 0)
                                        ? [
                                            Text(carbs.toStringAsPrecision(3)),
                                            Text(
                                                '${Settings.nutritionMeasurementSuffix} carbs',
                                                textScaleFactor: 0.75),
                                          ]
                                        : [],
                                  ),
                                ),
                              ],
                            ),
                            trailing: Row(
                              mainAxisSize: MainAxisSize.min,
                              children: [
                                IconButton(
                                  onPressed: () => handleDeleteAction(logEntry),
                                  icon: const Icon(Icons.delete,
                                      color: Colors.blue),
                                )
                              ],
                            ),
                          ),
                        );
                      },
                    ),
                  )
                : const Center(
                    child: Text(
                        'You have not created any Log Entries for this date yet!'),
                  ),
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          final now = DateTime.now();
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => LogEntryScreen(
                  suggestedDate: _date.isAtSameMomentAs(DateTime(now.year, now.month, now.day)) ? now : _date),
            ),
          ).then((result) => reload(message: result?[0]));
        },
        child: const Icon(Icons.add),
      ),
    );
  }
}
