import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:intl/intl.dart';
import 'package:prasule/api/category.dart';
import 'package:prasule/api/entry_data.dart';
import 'package:prasule/api/recurring_entry.dart';
import 'package:prasule/api/wallet.dart';
import 'package:prasule/api/wallet_manager.dart';
import 'package:prasule/pw/platformbutton.dart';
import 'package:prasule/pw/platformfield.dart';
import 'package:prasule/util/show_message.dart';

/// Used when user wants to add new entry
class CreateRecurringEntryView extends StatefulWidget {
  /// Used when user wants to add new entry
  const CreateRecurringEntryView({
    required this.w,
    required this.locale,
    super.key,
    this.editEntry,
  });

  /// The wallet, where the entry will be saved to
  final Wallet w;

  /// Entry we want to edit
  ///
  /// Is null unless we are editing an existing entry
  final RecurringWalletEntry? editEntry;

  /// Selected locale
  final String locale;

  @override
  State createState() => _CreateRecurringEntryViewState();
}

class _CreateRecurringEntryViewState extends State<CreateRecurringEntryView> {
  late RecurringWalletEntry newEntry;
  final _entryNameController = TextEditingController();
  final _entryBalanceController = TextEditingController();
  final _entryDescriptionController = TextEditingController();
  final _repeatAfterController = TextEditingController();
  @override
  void initState() {
    super.initState();
    if (widget.editEntry != null) {
      newEntry = widget.editEntry!;
    } else {
      newEntry = RecurringWalletEntry(
        id: widget.w.nextId,
        data: EntryData(amount: 0, name: ""),
        type: EntryType.expense,
        date: DateTime.now(),
        category: widget.w.categories.first,
        lastRunDate: DateTime.now(),
        recurType: RecurType.month,
      );
    }
    _entryNameController.text = newEntry.data.name;
    _entryBalanceController.text = newEntry.data.amount.toString();
    _entryDescriptionController.text = newEntry.data.description;
    _repeatAfterController.text = newEntry.repeatAfter.toString();
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(AppLocalizations.of(context).createEntry),
      ),
      body: SizedBox(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        child: Center(
          child: SingleChildScrollView(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                SizedBox(
                  width: MediaQuery.of(context).size.width * 0.8,
                  child: PlatformField(
                    labelText: AppLocalizations.of(context).name,
                    controller: _entryNameController,
                  ),
                ),
                const SizedBox(
                  height: 15,
                ),
                SizedBox(
                  width: MediaQuery.of(context).size.width * 0.8,
                  child: PlatformField(
                    labelText: AppLocalizations.of(context).amount,
                    controller: _entryBalanceController,
                    keyboardType:
                        const TextInputType.numberWithOptions(decimal: true),
                    inputFormatters: [
                      FilteringTextInputFormatter.allow(
                        RegExp(r'\d+[\.,]{0,1}\d{0,}'),
                      ),
                    ],
                  ),
                ),
                const SizedBox(
                  height: 20,
                ),
                Text(AppLocalizations.of(context).type),
                const SizedBox(
                  height: 10,
                ),
                SizedBox(
                  width: MediaQuery.of(context).size.width * 0.8,
                  child: DropdownButton<EntryType>(
                    value: newEntry.type,
                    items: [
                      DropdownMenuItem(
                        value: EntryType.expense,
                        child: SizedBox(
                          width: MediaQuery.of(context).size.width * 0.8 - 24,
                          child: Text(
                            AppLocalizations.of(context).expense,
                          ),
                        ),
                      ),
                      DropdownMenuItem(
                        value: EntryType.income,
                        child: SizedBox(
                          width: MediaQuery.of(context).size.width * 0.8 - 24,
                          child: Text(AppLocalizations.of(context).income),
                        ),
                      ),
                    ],
                    onChanged: (v) {
                      if (v == null) return;
                      newEntry.type = v;
                      setState(() {});
                    },
                  ),
                ),
                const SizedBox(
                  height: 20,
                ),
                Text(AppLocalizations.of(context).category),
                const SizedBox(
                  height: 10,
                ),
                SizedBox(
                  width: MediaQuery.of(context).size.width * 0.8,
                  child: DropdownButton<int>(
                    value: newEntry.category.id,
                    items: List.generate(
                      widget.w.categories.length,
                      (index) => DropdownMenuItem(
                        value: widget.w.categories[index].id,
                        child: SizedBox(
                          width: MediaQuery.of(context).size.width * 0.8 - 24,
                          child: Text(
                            widget.w.categories[index].name,
                          ),
                        ),
                      ),
                    ),
                    onChanged: (v) {
                      if (v == null) return;
                      newEntry.category = widget.w.categories
                          .where((element) => element.id == v)
                          .first;
                      setState(() {});
                    },
                  ),
                ),
                const SizedBox(
                  height: 20,
                ),
                Text(AppLocalizations.of(context).description),
                const SizedBox(
                  height: 10,
                ),
                ConstrainedBox(
                  constraints: BoxConstraints(
                    minWidth: MediaQuery.of(context).size.width * 0.8,
                    maxWidth: MediaQuery.of(context).size.width * 0.8,
                    maxHeight: 300,
                  ),
                  child: PlatformField(
                    keyboardType: TextInputType.multiline,
                    maxLines: null,
                    controller: _entryDescriptionController,
                  ),
                ),
                const SizedBox(
                  height: 20,
                ),
                SizedBox(
                  width: MediaQuery.of(context).size.width * 0.9,
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Text(
                        AppLocalizations.of(context)
                            .recurEvery(newEntry.repeatAfter),
                      ),
                      const SizedBox(
                        width: 10,
                      ),
                      SizedBox(
                        width: 50,
                        child: PlatformField(
                          controller: _repeatAfterController,
                          inputFormatters: [
                            FilteringTextInputFormatter.digitsOnly,
                            FilteringTextInputFormatter.deny(
                              RegExp(r"^0$"),
                              replacementString: "1",
                            ),
                            FilteringTextInputFormatter.deny(
                              r"\d+[\.,]{0,1}\d{0,}",
                              replacementString: "1",
                            ),
                          ],
                          onChanged: (s) {
                            final n = int.tryParse(s);
                            if (n == null) return;
                            newEntry.repeatAfter = n;
                            setState(() {});
                          },
                        ),
                      ),
                    ],
                  ),
                ),
                SizedBox(
                  width: 200,
                  child: DropdownButton<RecurType>(
                    value: newEntry.recurType,
                    items: [
                      DropdownMenuItem(
                        value: RecurType.day,
                        child: SizedBox(
                          width: 176,
                          child: Text(
                            AppLocalizations.of(context)
                                .dayCounter(newEntry.repeatAfter),
                          ),
                        ),
                      ),
                      DropdownMenuItem(
                        value: RecurType.month,
                        child: SizedBox(
                          width: 176,
                          child: Text(
                            AppLocalizations.of(context)
                                .monthCounter(newEntry.repeatAfter),
                          ),
                        ),
                      ),
                      DropdownMenuItem(
                        value: RecurType.year,
                        child: SizedBox(
                          width: 176,
                          child: Text(
                            AppLocalizations.of(context)
                                .yearCounter(newEntry.repeatAfter),
                          ),
                        ),
                      ),
                    ],
                    onChanged: (v) {
                      if (v == null) return;
                      newEntry.recurType = v;
                      setState(() {});
                    },
                  ),
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Text(AppLocalizations.of(context).startingWithDate),
                    const SizedBox(
                      width: 10,
                    ), // TODO: maybe use sizedbox on row with spaceEvenly?
                    PlatformButton(
                      text: DateFormat.yMMMMd(widget.locale)
                          .format(newEntry.lastRunDate),
                      onPressed: () async {
                        final d = await showDatePicker(
                          context: context,
                          firstDate: DateTime.now(),
                          lastDate:
                              DateTime.now().add(const Duration(days: 365)),
                        );
                        if (d == null) return;
                        newEntry.lastRunDate = d;
                        setState(() {});
                      },
                    ),
                  ],
                ),
                const SizedBox(
                  height: 15,
                ),
                PlatformButton(
                  text: AppLocalizations.of(context).save,
                  onPressed: () {
                    if (_entryNameController.text.isEmpty) {
                      showMessage(
                        AppLocalizations.of(context).errorEmptyName,
                        context,
                      );
                      return;
                    }
                    newEntry.data.name = _entryNameController.text;
                    newEntry.data.amount =
                        double.parse(_entryBalanceController.text);
                    newEntry.repeatAfter =
                        int.parse(_repeatAfterController.text);
                    newEntry.data.description =
                        _entryDescriptionController.text;
                    if (widget.editEntry != null) {
                      Navigator.of(context).pop(newEntry);
                      return;
                    }
                    widget.w.recurringEntries.add(newEntry);
                    WalletManager.saveWallet(widget.w).then(
                      (value) => Navigator.of(context).pop(widget.w),
                    ); // TODO loading circle?
                  },
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
