import 'package:flutter/material.dart';
import 'package:flutter_picker_plus/picker.dart';
import 'package:get_it/get_it.dart';
import 'package:okane/database/collections/account.dart';
import 'package:okane/database/collections/beneficiary.dart';
import 'package:okane/database/collections/recurrent.dart';
import 'package:okane/database/collections/template.dart';
import 'package:okane/database/database.dart';
import 'package:okane/ui/state/core.dart';
import 'package:okane/ui/transaction.dart';
import 'package:okane/ui/utils.dart';
import 'package:searchfield/searchfield.dart';

enum Period { days, weeks, months, years }

class AddRecurringTransactionTemplateWidget extends StatefulWidget {
  final VoidCallback onAdd;

  final Account activeAccountItem;

  const AddRecurringTransactionTemplateWidget({
    super.key,
    required this.activeAccountItem,
    required this.onAdd,
  });

  @override
  State<AddRecurringTransactionTemplateWidget> createState() =>
      _AddRecurringTransactionTemplateWidgetState();
}

class _AddRecurringTransactionTemplateWidgetState
    extends State<AddRecurringTransactionTemplateWidget> {
  final TextEditingController _beneficiaryTextController =
      TextEditingController();
  final TextEditingController _amountTextController = TextEditingController();
  final TextEditingController _templateNameController = TextEditingController();

  List<Beneficiary> beneficiaries = [];

  SearchFieldListItem<Beneficiary>? _selectedBeneficiary;

  TransactionDirection _selectedDirection = TransactionDirection.send;

  Period _selectedPeriod = Period.months;
  int _periodSize = 1;

  String getBeneficiaryName(Beneficiary item) {
    return switch (item.type) {
      BeneficiaryType.account => "${item.name} (Account)",
      BeneficiaryType.other => item.name,
    };
  }

  Future<void> _submit(BuildContext context) async {
    final beneficiaryName = _beneficiaryTextController.text;
    if (_selectedBeneficiary == null && beneficiaryName.isEmpty) {
      return;
    }
    if (_templateNameController.text.isEmpty) {
      return;
    }

    Beneficiary? beneficiary = _selectedBeneficiary?.item;
    if (beneficiary == null ||
        getBeneficiaryName(beneficiary) != beneficiaryName) {
      // Add a new beneficiary, if none was selected
      final result = await showDialog<bool>(
        context: context,
        builder:
            (context) => AlertDialog(
              title: const Text("Add Beneficiary"),
              content: Text(
                "The beneficiary '$beneficiaryName' does not exist. Do you want to add it?",
              ),
              actions: [
                TextButton(
                  style: TextButton.styleFrom(
                    textStyle: Theme.of(context).textTheme.labelLarge,
                  ),
                  child: const Text('Add'),
                  onPressed: () => Navigator.of(context).pop(true),
                ),
                TextButton(
                  style: TextButton.styleFrom(
                    textStyle: Theme.of(context).textTheme.labelLarge,
                  ),
                  child: const Text('Cancel'),
                  onPressed: () => Navigator.of(context).pop(false),
                ),
              ],
            ),
      );
      if (result == null || !result) {
        return;
      }

      beneficiary =
          Beneficiary()
            ..name = beneficiaryName
            ..type = BeneficiaryType.other;
      await upsertBeneficiary(beneficiary);
    }

    final days = switch (_selectedPeriod) {
      Period.days => _periodSize,
      Period.weeks => _periodSize * 7,
      Period.months => _periodSize * 31,
      Period.years => _periodSize * 365,
    };
    final factor = switch (_selectedDirection) {
      TransactionDirection.send => -1,
      TransactionDirection.receive => 1,
    };
    final amount = factor * double.parse(_amountTextController.text).abs();
    final template =
        TransactionTemplate()
          ..name = _templateNameController.text
          ..beneficiary.value = beneficiary
          ..account.value = widget.activeAccountItem
          ..recurring = true
          ..amount = amount;
    await upsertTransactionTemplate(template);

    final transaction =
        RecurringTransaction()
          ..lastExecution = null
          ..template.value = template
          ..account.value = widget.activeAccountItem
          ..days = days;
    await upsertRecurringTransaction(transaction);

    _periodSize = 1;
    _selectedPeriod = Period.weeks;
    _amountTextController.text = "";
    _templateNameController.text = "";
    widget.onAdd();
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.symmetric(horizontal: 16),
      child: ListView(
        shrinkWrap: true,
        children: [
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 8),
            child: TextField(
              controller: _templateNameController,
              decoration: InputDecoration(label: Text("Template name")),
            ),
          ),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 8),
            child: SearchField<Beneficiary>(
              suggestions:
                  beneficiaries
                      .where((el) {
                        final bloc = GetIt.I.get<CoreCubit>();
                        if (el.type == BeneficiaryType.account) {
                          return el.account.value?.id != bloc.activeAccount?.id;
                        }
                        return true;
                      })
                      .map((el) {
                        return SearchFieldListItem(
                          getBeneficiaryName(el),
                          item: el,
                        );
                      })
                      .toList(),
              hint: "Beneficiary",
              controller: _beneficiaryTextController,
              selectedValue: _selectedBeneficiary,
              onSuggestionTap: (beneficiary) {
                setState(() => _selectedBeneficiary = beneficiary);
              },
            ),
          ),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 8),
            child: TextField(
              controller: _amountTextController,
              keyboardType: TextInputType.numberWithOptions(
                signed: false,
                decimal: false,
              ),
              decoration: InputDecoration(hintText: "Amount"),
            ),
          ),

          Padding(
            padding: const EdgeInsets.symmetric(vertical: 8),
            child: SegmentedButton<TransactionDirection>(
              segments: [
                ButtonSegment(
                  value: TransactionDirection.send,
                  label: Text("Send"),
                  icon: Icon(Icons.remove),
                ),
                ButtonSegment(
                  value: TransactionDirection.receive,
                  label: Text("Receive"),
                  icon: Icon(Icons.add),
                ),
              ],
              selected: <TransactionDirection>{_selectedDirection},
              multiSelectionEnabled: false,
              onSelectionChanged: (selection) {
                setState(() => _selectedDirection = selection.first);
              },
            ),
          ),

          Padding(
            padding: EdgeInsets.only(left: 16, right: 16, top: 16),
            child: SegmentedButton<Period>(
              segments: [
                ButtonSegment(value: Period.days, label: Text("Days")),
                ButtonSegment(value: Period.weeks, label: Text("Weeks")),
                ButtonSegment(value: Period.months, label: Text("Months")),
                ButtonSegment(value: Period.years, label: Text("Years")),
              ],
              selected: <Period>{_selectedPeriod},
              multiSelectionEnabled: false,
              onSelectionChanged: (selection) {
                setState(() => _selectedPeriod = selection.first);
              },
            ),
          ),
          Text.rich(
            TextSpan(
              text: "Repeat every ",
              children: [
                WidgetSpan(
                  child: TextButton(
                    onPressed: () {
                      Picker(
                        adapter: NumberPickerAdapter(
                          data: [
                            NumberPickerColumn(
                              begin: 1,
                              end: 999,
                              initValue: _periodSize,
                            ),
                          ],
                        ),
                        hideHeader: true,
                        selectedTextStyle: TextStyle(color: Colors.blue),
                        onConfirm: (Picker picker, List value) {
                          setState(() {
                            _periodSize = (value.first as int) + 1;
                          });
                        },
                      ).showDialog(context);
                    },
                    child: Text(_periodSize.toString()),
                  ),
                ),
                TextSpan(
                  text: switch (_selectedPeriod) {
                    Period.days => " days",
                    Period.weeks => " weeks",
                    Period.months => " months",
                    Period.years => " years",
                  },
                ),
              ],
            ),
          ),

          Align(
            alignment: Alignment.centerRight,
            child: OutlinedButton(
              onPressed: () => _submit(context),
              child: Text("Add"),
            ),
          ),
        ],
      ),
    );
  }
}