import 'package:diameter/components/detail.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/accuracy.dart';
import 'package:diameter/models/meal_category.dart';
import 'package:diameter/models/meal_portion_type.dart';
import 'package:diameter/models/meal_source.dart';
import 'package:diameter/models/settings.dart';
import 'package:diameter/navigation.dart';
import 'package:diameter/screens/accuracy_detail.dart';
import 'package:diameter/screens/meal/meal_category_detail.dart';
import 'package:diameter/screens/meal/meal_portion_type_detail.dart';
import 'package:flutter/material.dart';

class MealSourceDetailScreen extends StatefulWidget {
  static const String routeName = '/meal-source';

  final int id;

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

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

class _MealSourceDetailScreenState extends State<MealSourceDetailScreen> {
  MealSource? _mealSource;
  bool _isNew = true;

  List<Accuracy> _portionSizeAccuracies = [];
  List<Accuracy> _carbsRatioAccuracies = [];
  List<MealCategory> _mealCategories = [];
  List<MealPortionType> _mealPortionTypes = [];

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

  final _valueController = TextEditingController(text: '');
  final _notesController = TextEditingController(text: '');

  Accuracy? _defaultCarbsRatioAccuracy;
  Accuracy? _defaultPortionSizeAccuracy;
  MealCategory? _defaultMealCategory;
  MealPortionType? _defaultMealPortionType;
  final _defaultCarbsRatioAccuracyController = TextEditingController(text: '');
  final _defaultPortionSizeAccuracyController = TextEditingController(text: '');
  final _defaultMealCategoryController = TextEditingController(text: '');
  final _defaultMealPortionTypeController = TextEditingController(text: '');

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

    reload();

    _portionSizeAccuracies = Accuracy.getAllForPortionSize();
    _carbsRatioAccuracies = Accuracy.getAllForCarbsRatio();
    _mealCategories = MealCategory.getAll();
    _mealPortionTypes = MealPortionType.getAll();

    if (_mealSource != null) {
      _valueController.text = _mealSource!.value;
      _notesController.text = _mealSource!.notes ?? '';

      _defaultPortionSizeAccuracy =
          _mealSource!.defaultPortionSizeAccuracy.target;
      _defaultPortionSizeAccuracyController.text = (_defaultPortionSizeAccuracy ?? '').toString();
      _defaultCarbsRatioAccuracy =
          _mealSource!.defaultCarbsRatioAccuracy.target;
      _defaultCarbsRatioAccuracyController.text = (_defaultCarbsRatioAccuracy ?? '').toString();

      _defaultMealCategory = _mealSource!.defaultMealCategory.target;
      _defaultMealCategoryController.text = (_defaultMealCategory ?? '').toString();
      _defaultMealPortionType = _mealSource!.defaultMealPortionType.target;
      _defaultMealPortionTypeController.text = (_defaultMealPortionType ?? '').toString();
    }
  }

  @override
  void dispose() {
    _scrollController.dispose();
    _valueController.dispose();
    _notesController.dispose();
    _defaultCarbsRatioAccuracyController.dispose();
    _defaultPortionSizeAccuracyController.dispose();
    _defaultMealCategoryController.dispose();
    _defaultMealPortionTypeController.dispose();
    super.dispose();
  }

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

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

  void handleSaveAction() async {
    MealSource mealSource = MealSource(
      id: widget.id,
      value: _valueController.text,
      notes: _notesController.text,
    );
    mealSource.defaultCarbsRatioAccuracy.target = _defaultCarbsRatioAccuracy;
    mealSource.defaultPortionSizeAccuracy.target = _defaultPortionSizeAccuracy;
    mealSource.defaultMealCategory.target = _defaultMealCategory;
    mealSource.defaultMealPortionType.target = _defaultMealPortionType;
    MealSource.put(mealSource);
    Navigator.pop(context, ['${_isNew ? 'New' : ''} Meal Source saved', mealSource]);
  }

  void handleCancelAction() {
    if (Settings.get().showConfirmationDialogOnCancel &&
        ((_isNew &&
                (_valueController.text != '' ||
                    _defaultCarbsRatioAccuracy != null ||
                    _defaultPortionSizeAccuracy != null ||
                    _defaultMealCategory != null ||
                    _defaultMealPortionType != null ||
                    _notesController.text != '')) ||
            (!_isNew &&
                (_valueController.text != _mealSource!.value ||
                    _defaultCarbsRatioAccuracy !=
                        _mealSource!.defaultCarbsRatioAccuracy.target ||
                    _defaultPortionSizeAccuracy !=
                        _mealSource!.defaultPortionSizeAccuracy.target ||
                    _defaultMealCategory !=
                        _mealSource!.defaultMealCategory.target ||
                    _defaultMealPortionType !=
                        _mealSource!.defaultMealPortionType.target ||
                    _notesController.text != (_mealSource!.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 Meal Source' : _mealSource!.value),
      ),
      drawer:
          const Navigation(currentLocation: MealSourceDetailScreen.routeName),
      body: Scrollbar(
        controller: _scrollController,
        child: SingleChildScrollView(
          controller: _scrollController,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: <Widget>[
              FormWrapper(
                formState: _mealSourceForm,
                fields: [
                  TextFormField(
                    controller: _valueController,
                    decoration: const InputDecoration(
                      labelText: 'Name',
                    ),
                    validator: (value) {
                      if (value!.trim().isEmpty) {
                        return 'Empty name';
                      }
                      return null;
                    },
                  ),
                  Row(
                    children: [
                      Expanded(
                        child: AutoCompleteDropdownButton<Accuracy>(
                          selectedItem: _defaultCarbsRatioAccuracy,
                          controller: _defaultCarbsRatioAccuracyController,
                          label: 'Default Carbs Ratio Accuracy',
                          items: _carbsRatioAccuracies,
                          onChanged: (value) {
                            setState(() {
                              _defaultCarbsRatioAccuracy = value;
                              _defaultCarbsRatioAccuracyController.text =
                                  (_defaultCarbsRatioAccuracy ?? '').toString();
                            });
                          },
                        ),
                      ),
                      IconButton(
                        onPressed: () {
                          Navigator.push(
                            context,
                            MaterialPageRoute(
                              builder: (context) =>
                                  _defaultCarbsRatioAccuracy == null
                                      ? const AccuracyDetailScreen()
                                      : AccuracyDetailScreen(
                                          id: _defaultCarbsRatioAccuracy!.id),
                            ),
                          ).then((result) {
                            setState(() {
                              _defaultCarbsRatioAccuracy = result?[1];
                              _defaultCarbsRatioAccuracyController.text =
                                  (_defaultCarbsRatioAccuracy ?? '').toString();
                            });
                            reload(message: result?[0]);
                          });
                        },
                        icon: Icon(_defaultCarbsRatioAccuracy == null
                            ? Icons.add
                            : Icons.edit),
                      ),
                    ],
                  ),
                  Row(
                    children: [
                      Expanded(
                        child: AutoCompleteDropdownButton<Accuracy>(
                          selectedItem: _defaultPortionSizeAccuracy,
                          controller: _defaultPortionSizeAccuracyController,
                          label: 'Default Portion Size Accuracy',
                          items: _portionSizeAccuracies,
                          onChanged: (value) {
                            setState(() {
                              _defaultPortionSizeAccuracy = value;
                              _defaultPortionSizeAccuracyController.text =
                                  (_defaultPortionSizeAccuracy ?? '')
                                      .toString();
                            });
                          },
                        ),
                      ),
                      IconButton(
                        onPressed: () {
                          Navigator.push(
                            context,
                            MaterialPageRoute(
                              builder: (context) =>
                                  _defaultPortionSizeAccuracy == null
                                      ? const AccuracyDetailScreen()
                                      : AccuracyDetailScreen(
                                          id: _defaultPortionSizeAccuracy!.id),
                            ),
                          ).then((result) {
                            setState(() {
                              _defaultPortionSizeAccuracy = result?[1];
                              _defaultPortionSizeAccuracyController.text =
                                  (_defaultPortionSizeAccuracy ?? '')
                                      .toString();
                            });
                            reload(message: result?[0]);
                          });
                        },
                        icon: Icon(_defaultPortionSizeAccuracy == null
                            ? Icons.add
                            : Icons.edit),
                      ),
                    ],
                  ),
                  Row(
                    children: [
                      Expanded(
                        child: AutoCompleteDropdownButton<MealCategory>(
                          selectedItem: _defaultMealCategory,
                          controller: _defaultMealCategoryController,
                          label: 'Default Meal Category',
                          items: _mealCategories,
                          onChanged: (value) {
                            setState(() {
                              _defaultMealCategory = value;
                              _defaultMealCategoryController.text =
                                  (_defaultMealCategory ?? '').toString();
                            });
                          },
                        ),
                      ),
                      IconButton(
                        onPressed: () {
                          Navigator.push(
                            context,
                            MaterialPageRoute(
                              builder: (context) => _defaultMealCategory == null
                                  ? const MealCategoryDetailScreen()
                                  : MealCategoryDetailScreen(
                                      id: _defaultMealCategory!.id),
                            ),
                          ).then((result) {
                            setState(() {
                            _defaultMealCategory = result?[1];
                            _defaultMealCategoryController.text =
                                (_defaultMealCategory ?? '').toString();
                            });
                            reload(message: result?[0]);
                          });
                        },
                        icon: Icon(_defaultMealCategory == null
                            ? Icons.add
                            : Icons.edit),
                      ),
                    ],
                  ),
                  Row(
                    children: [
                      Expanded(
                        child: AutoCompleteDropdownButton<MealPortionType>(
                          selectedItem: _defaultMealPortionType,
                          controller: _defaultMealPortionTypeController,
                          label: 'Default Meal Portion Type',
                          items: _mealPortionTypes,
                          onChanged: (value) {
                            setState(() {
                              _defaultMealPortionType = value;
                              _defaultMealPortionTypeController.text =
                                  (_defaultMealPortionType ?? '').toString();
                            });
                          },
                        ),
                      ),
                      IconButton(
                        onPressed: () {
                          Navigator.push(
                            context,
                            MaterialPageRoute(
                              builder: (context) =>
                                  _defaultMealPortionType == null
                                      ? const MealPortionTypeDetailScreen()
                                      : MealPortionTypeDetailScreen(
                                          id: _defaultMealPortionType!.id),
                            ),
                          ).then((result) {
                            setState(() {
                              _defaultMealPortionType = result?[1];
                              _defaultMealPortionTypeController.text =
                                  (_defaultMealPortionType ?? '').toString();
                            });
                            reload(message: result?[0]);
                          });
                        },
                        icon: Icon(_defaultMealPortionType == null
                            ? Icons.add
                            : Icons.edit),
                      ),
                    ],
                  ),
                  TextFormField(
                    controller: _notesController,
                    decoration: const InputDecoration(
                      labelText: 'Notes',
                    ),
                    keyboardType: TextInputType.multiline,
                    minLines: 2,
                    maxLines: 5,
                  )
                ],
              ),
            ],
          ),
        ),
      ),
      bottomNavigationBar: DetailBottomRow(
        onCancel: handleCancelAction,
        onAction: handleSaveAction,
      ),
    );
  }
}
