import 'package:flutter/material.dart';

import 'package:collection/collection.dart';

import 'package:provider/provider.dart';

import 'package:pshared/models/currency.dart';
import 'package:pshared/models/describable.dart';
import 'package:pshared/models/payment/chain_network.dart';
import 'package:pshared/models/payment/type.dart';
import 'package:pshared/provider/accounts/employees.dart';
import 'package:pshared/provider/ledger.dart';
import 'package:pshared/provider/payment/wallets.dart';

import 'package:pweb/pages/dashboard/buttons/balance/add/form.dart';
import 'package:pweb/pages/dashboard/buttons/balance/add/constants.dart';
import 'package:pweb/pages/dashboard/buttons/balance/add/cancel.dart';
import 'package:pweb/pages/dashboard/buttons/balance/add/submit.dart';
import 'package:pweb/utils/error/snackbar.dart';

import 'package:pweb/generated/i18n/app_localizations.dart';


Future<void> showAddBalanceDialog(BuildContext context) => showDialog<void>(
  context: context,
  builder: (dialogContext) => const AddBalanceDialog(),
);

class AddBalanceDialog extends StatefulWidget {
  const AddBalanceDialog({super.key});

  @override
  State<AddBalanceDialog> createState() => _AddBalanceDialogState();
}

class _AddBalanceDialogState extends State<AddBalanceDialog> {
  final _formKey = GlobalKey<FormState>();
  final _nameController = TextEditingController();
  final _descriptionController = TextEditingController();

  PaymentType _assetType = PaymentType.managedWallet;
  String? _ownerRef;
  CurrencyCode _managedCurrency = managedCurrencyDefault;
  ChainNetwork _network = managedNetworkDefault;
  CurrencyCode _ledgerCurrency = ledgerCurrencyDefault;

  @override
  void dispose() {
    _nameController.dispose();
    _descriptionController.dispose();
    super.dispose();
  }

  void _setAssetType(PaymentType? value) {
    if (value == null) return;
    setState(() => _assetType = value);
  }

  void _setOwnerRef(String? value) => setState(() => _ownerRef = value);

  void _setManagedCurrency(CurrencyCode? value) {
    if (value == null) return;
    setState(() => _managedCurrency = value);
  }

  void _setNetwork(ChainNetwork? value) {
    if (value == null) return;
    setState(() => _network = value);
  }

  void _setLedgerCurrency(CurrencyCode? value) {
    if (value == null) return;
    setState(() => _ledgerCurrency = value);
  }

  Future<void> _submit() async {
    final form = _formKey.currentState;
    if (form == null || !form.validate()) return;

    final l10n = AppLocalizations.of(context)!;
    final name = _nameController.text.trim();
    final description = _descriptionController.text.trim();
    final employees = context.read<EmployeesProvider>().employees;
    final effectiveOwnerRef = employees.any((employee) => employee.id == _ownerRef)
        ? _ownerRef
        : null;
    final isOrgWallet = effectiveOwnerRef == null;
    final owner = isOrgWallet
        ? null
        : employees.firstWhereOrNull((employee) => employee.id == effectiveOwnerRef);

    final errorMessage = _assetType == PaymentType.managedWallet
      ? l10n.errorCreateManagedWallet
      : l10n.errorCreateLedgerAccount;

    final result = await executeActionWithNotification<bool>(
      context: context,
      errorMessage: errorMessage,
      action: () async {
        if (_assetType == PaymentType.managedWallet) {
          await context.read<WalletsProvider>().create(
            describable: newDescribable(name: name, description: description),
            chain: _network,
            currency: _managedCurrency,
            ownerRef: owner?.id,
          );
        } else {
          await context.read<LedgerAccountsProvider>().create(
            describable: newDescribable(name: name, description: description),
            currency: _ledgerCurrency,
            ownerRef: owner?.id,
          );
        }
        return true;
      },
    );

    if (result == true && mounted) {
      Navigator.of(context).pop();
    }
  }

  @override
  Widget build(BuildContext context) {
    final l10n = AppLocalizations.of(context)!;
    final screenWidth = MediaQuery.of(context).size.width;
    final maxWidth = (screenWidth - 48).clamp(0.0, double.infinity);
    final dialogWidth = maxWidth >= 360.0 ? (maxWidth > 520.0 ? 520.0 : maxWidth) : maxWidth;
    final employeesProvider = context.watch<EmployeesProvider>();
    final employees = employeesProvider.employees;
    final isSaving = context.watch<WalletsProvider>().isLoading ||
        context.watch<LedgerAccountsProvider>().isLoading;

    final ownerItems = <DropdownMenuItem<String?>>[
      DropdownMenuItem(
        value: null,
        child: Text(l10n.organizationOwned),
      ),
      ...employees.map((employee) => DropdownMenuItem(
        value: employee.id,
        child: Text(employee.fullName.isNotEmpty ? employee.fullName : employee.login),
      )),
    ];

    final resolvedOwnerRef = ownerItems.any((item) => item.value == _ownerRef) ? _ownerRef : null;

    return AlertDialog(
      title: Text(l10n.actionAddNew),
      content: SizedBox(
        width: dialogWidth,
        child: AddBalanceForm(
          formKey: _formKey,
          assetType: _assetType,
          isSaving: isSaving,
          ownerItems: ownerItems,
          ownerValue: resolvedOwnerRef,
          onAssetTypeChanged: _setAssetType,
          onOwnerChanged: _setOwnerRef,
          nameController: _nameController,
          descriptionController: _descriptionController,
          managedCurrency: _managedCurrency,
          network: _network,
          ledgerCurrency: _ledgerCurrency,
          onManagedCurrencyChanged: _setManagedCurrency,
          onNetworkChanged: _setNetwork,
          onLedgerCurrencyChanged: _setLedgerCurrency,
          showEmployeesLoading: employeesProvider.isLoading,
        ),
      ),
      actions: [
        DialogCancelButton(
          label: l10n.cancel,
          isSaving: isSaving,
          onCancel: () => Navigator.of(context).pop(),
        ),
        DialogSubmitButton(
          label: l10n.add,
          isSaving: isSaving,
          onSubmit: _submit,
        ),
      ],
    );
  }
}
