import 'package:diameter/utils/dialog_utils.dart';
import 'package:diameter/models/log_event.dart';
import 'package:diameter/models/settings.dart';
import 'package:diameter/screens/log/log_event/log_event_detail.dart';
import 'package:diameter/utils/date_time_utils.dart';
import 'package:flutter/material.dart';
import 'package:diameter/navigation.dart';

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

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

class _LogEventListScreenState extends State<LogEventListScreen> {
  List<LogEvent> _activeEvents = [];
  late List<LogEvent> _logEvents;

  final ScrollController _scrollController = ScrollController();

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

  late DateTime _date;
  bool _showActive = true;

  @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(() {
      _activeEvents = LogEvent.getAllActiveForTime(DateTime.now());
      _logEvents = LogEvent.getAllForDate(_date);
    });

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

  void handleAddNewEvent() async {
    final now = DateTime.now();
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) {
          return LogEventDetailScreen(
            suggestedDate: _date.isAtSameMomentAs(DateTime(now.year, now.month, now.day)) ? now : _date,
          );
        },
      ),
    ).then((result) => reload(message: result?[0]));
  }

  void handleEditAction(LogEvent event) {
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => LogEventDetailScreen(
          id: event.id,
        ),
      ),
    ).then((result) => reload(message: result?[0]));
  }

  void onDelete(LogEvent logEvent) {
    LogEvent.remove(logEvent.id);
    reload(message: 'Event deleted');
  }

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

  void onStop(LogEvent event) async {
    event.endTime = DateTime.now();
    LogEvent.put(event);
    reload(message: 'Event ended');
  }

  void handleStopAction(LogEvent event) async {
    if (Settings.get().showConfirmationDialogOnStopEvent) {
      DialogUtils.showConfirmationDialog(
        context: context,
        onConfirm: () => onStop(event),
        message: 'Are you sure you want to end this Event?',
        confirmationLabel: 'END EVENT',
      );
    } else {
      onStop(event);
    }
  }

  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 Events'),
        actions: <Widget>[
          IconButton(
              onPressed: () => onChangeDate(DateTime.now()),
              icon: const Icon(Icons.today)),
          IconButton(onPressed: reload, icon: const Icon(Icons.refresh))
        ],
      ),
      drawer: const Navigation(currentLocation: LogEventListScreen.routeName),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          GestureDetector(
            onTap: () => setState(() {
              _showActive = !_showActive;
            }),
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Row(
                mainAxisSize: MainAxisSize.max,
                children: [
                  Expanded(
                    child: Text(
                      'ACTIVE EVENTS',
                      style: Theme.of(context).textTheme.subtitle2,
                      textAlign: TextAlign.center,
                    ),
                  ),
                  Icon(_showActive
                    ? Icons.expand_less
                    : Icons.expand_more),
                ],
              ),
            ),
          ),
          !_showActive ? Container() :
            _activeEvents.isNotEmpty
              ? ListView.builder(
                  shrinkWrap: true,
                  padding: const EdgeInsets.all(10.0),
                  itemCount: _activeEvents.length,
                  itemBuilder: (context, index) {
                    LogEvent event = _activeEvents[index];
                    return Card(
                      child: ListTile(
                        onTap: () {
                          handleEditAction(event);
                        },
                        title: Row(
                          crossAxisAlignment: CrossAxisAlignment.center,
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            Text(
                              DateTimeUtils.displayDateTime(event.time),
                            ),
                            const SizedBox(width: 24),
                            Expanded(
                              child: Text(
                                (event.title ??
                                        event.eventType.target?.value ??
                                        '')
                                    .toUpperCase(),
                                style: Theme.of(context).textTheme.subtitle2,
                              ),
                            ),
                          ],
                        ),
                        trailing: Row(
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            event.hasEndTime && event.endTime == null
                                ? IconButton(
                                    icon: const Icon(
                                      Icons.stop,
                                      color: Colors.blue,
                                    ),
                                    onPressed: () => handleStopAction(event),
                                  )
                                : const SizedBox(width: 50),
                            IconButton(
                              icon: const Icon(
                                Icons.edit,
                                color: Colors.blue,
                              ),
                              onPressed: () => handleEditAction(event),
                            ),
                            IconButton(
                              icon: const Icon(
                                Icons.delete,
                                color: Colors.blue,
                              ),
                              onPressed: () => handleDeleteAction(event),
                            ),
                          ],
                        ),
                      ),
                    );
                  },
                )
              : const Center(
                  child: Text('There are no Active Events!'),
                ),
                const Padding(
                  padding: EdgeInsets.all(10.0),
                  child: Divider(),
                ),
          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: _logEvents.isNotEmpty
                ? Scrollbar(
                    controller: _scrollController,
                    child: ListView.builder(
                      controller: _scrollController,
                      shrinkWrap: true,
                      padding: const EdgeInsets.all(10.0),
                      itemCount: _logEvents.length,
                      itemBuilder: (context, index) {
                        LogEvent event = _logEvents[index];
                        return Card(
                          child: ListTile(
                            onTap: () {
                              handleEditAction(event);
                            },
                            title: Row(
                              crossAxisAlignment: CrossAxisAlignment.center,
                              mainAxisSize: MainAxisSize.min,
                              children: [
                                Text(
                                  DateTimeUtils.displayTime(event.isEndEvent
                                      ? event.endTime
                                      : event.time),
                                ),
                                const SizedBox(width: 24),
                                Expanded(
                                  child: Text(
                                    (event.title ??
                                            event.eventType.target?.value ??
                                            '')
                                        .toUpperCase(),
                                    style:
                                        Theme.of(context).textTheme.subtitle2,
                                  ),
                                ),
                              ],
                            ),
                            trailing: Row(
                              mainAxisSize: MainAxisSize.min,
                              children: [
                                event.hasEndTime && event.endTime == null
                                    ? IconButton(
                                        icon: const Icon(
                                          Icons.stop,
                                          color: Colors.blue,
                                        ),
                                        onPressed: () =>
                                            handleStopAction(event),
                                      )
                                    : const SizedBox(width: 50),
                                IconButton(
                                  icon: const Icon(
                                    Icons.edit,
                                    color: Colors.blue,
                                  ),
                                  onPressed: () => handleEditAction(event),
                                ),
                                IconButton(
                                  icon: const Icon(
                                    Icons.delete,
                                    color: Colors.blue,
                                  ),
                                  onPressed: () => handleDeleteAction(event),
                                ),
                              ],
                            ),
                          ),
                        );
                      },
                    ))
                : const Center(
                    child: Text('There are no Events for that date!'),
                  ),
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: handleAddNewEvent,
        child: const Icon(Icons.add),
      ),
    );
  }
}
