import 'package:collection/collection.dart';

import 'package:flutter/material.dart';

import 'package:pshared/models/payment/methods/type.dart';
import 'package:pshared/models/payment/type.dart';
import 'package:pshared/models/recipient/recipient.dart';

import 'package:pweb/models/wallet.dart';
import 'package:pweb/providers/payment_methods.dart';
import 'package:pweb/providers/wallets.dart';
import 'package:pweb/widgets/sidebar/destinations.dart';
import 'package:pweb/services/amplitude.dart';
import 'package:pweb/providers/recipient.dart';


class PageSelectorProvider extends ChangeNotifier {
  PayoutDestination _selected = PayoutDestination.dashboard;
  PaymentType? _type;
  bool _cameFromRecipientList = false;
  PayoutDestination? _previousDestination;

  RecipientProvider? recipientProvider;
  WalletsProvider? walletsProvider;
  PaymentMethodsProvider? methodsProvider;

  PayoutDestination get selected => _selected;
  PaymentType? get type => _type;
  bool get cameFromRecipientList => _cameFromRecipientList;

  PageSelectorProvider({
    this.recipientProvider,
    this.walletsProvider,
    this.methodsProvider,
  });

  void update(
    RecipientProvider recipientProv,
    WalletsProvider walletsProv,
    PaymentMethodsProvider methodsProv,
  ) {
    recipientProvider = recipientProv;
    walletsProvider = walletsProv;
    methodsProvider = methodsProv;
  }

  void selectPage(PayoutDestination dest) {
    _selected = dest;
    notifyListeners();
  }

  void selectRecipient(Recipient? recipient, {bool fromList = false}) {
    if (recipientProvider != null) {
      recipientProvider!.selectRecipient(recipient);
      _cameFromRecipientList = fromList;
      _setPreviousDestination();
      _selected = PayoutDestination.payment;
      notifyListeners();
    } else {
      debugPrint("RecipientProvider is null — cannot select recipient");
    }
  }

  void editRecipient(Recipient? recipient, {bool fromList = false}) {
    if (recipientProvider != null) {
      recipientProvider!.selectRecipient(recipient);
      _cameFromRecipientList = fromList;
      _selected = PayoutDestination.addrecipient;
      notifyListeners();
    } else {
      debugPrint("RecipientProvider is null — cannot select recipient");
    }
  }

  void goToAddRecipient() {
    if (recipientProvider != null) {
      AmplitudeService.recipientAddStarted();
      recipientProvider!.selectRecipient(null);
      _selected = PayoutDestination.addrecipient;
      _cameFromRecipientList = false;
      notifyListeners();
    } else {
      debugPrint("RecipientProvider is null — cannot go to add recipient");
    }
  }

  void startPaymentWithoutRecipient(PaymentType type) {
    if (recipientProvider != null) {
      recipientProvider!.selectRecipient(null);
    }
    _type = type;
    _cameFromRecipientList = false;
    _setPreviousDestination();
    _selected = PayoutDestination.payment;
    notifyListeners();
  }

  void goBackFromPayment() {
    _selected = _previousDestination ??
        (_cameFromRecipientList
            ? PayoutDestination.recipients
            : PayoutDestination.dashboard);
    _type = null;
    _previousDestination = null;
    _cameFromRecipientList = false;
    notifyListeners();
  }

  void goBackFromWalletEdit() {
    selectPage(PayoutDestination.methods);
  }

  void selectWallet(Wallet wallet) {
    if (walletsProvider != null) {
      walletsProvider!.selectWallet(wallet);
      _selected = PayoutDestination.editwallet;
      notifyListeners();
    } else {
      debugPrint("WalletsProvider is null — cannot select wallet");
    }
  }

  void startPaymentFromWallet(Wallet wallet) {
    _type = PaymentType.wallet;
    _cameFromRecipientList = false;
    _setPreviousDestination();
    _selected = PayoutDestination.payment;
    notifyListeners();
  }

  PaymentMethod? getPaymentMethodForWallet(Wallet wallet) {
    if (methodsProvider == null || methodsProvider!.methods.isEmpty) {
      return null;
    }
    
    return methodsProvider!.methods.firstWhereOrNull(
      (method) => method.type == PaymentType.wallet && 
                  method.details.contains(wallet.walletUserID)
    );
  }

  Map<PaymentType, Object> getAvailablePaymentTypes() {
    final recipient = selectedRecipient;
    if (recipient == null) return {};

    return {
      if (recipient.card != null) PaymentType.card: recipient.card!,
      if (recipient.iban != null) PaymentType.iban: recipient.iban!,
      if (recipient.wallet != null) PaymentType.wallet: recipient.wallet!,
      if (recipient.bank != null) PaymentType.bankAccount: recipient.bank!,
    };
  }

  PaymentType getDefaultPaymentType() {
    final availableTypes = getAvailablePaymentTypes();
    final currentType = _type ?? PaymentType.bankAccount;
    
    if (availableTypes.containsKey(currentType)) {
      return currentType;
    } else if (availableTypes.isNotEmpty) {
      return availableTypes.keys.first;
    } else {
      return PaymentType.bankAccount;
    }
  }

  bool shouldShowPaymentForm() {
    return selectedRecipient == null;
  }

  void handleWalletAutoSelection() {
    if (selectedWallet != null && methodsProvider != null) {
      final wallet = selectedWallet!;
      final matchingMethod = getPaymentMethodForWallet(wallet);
      if (matchingMethod != null) {
        methodsProvider!.selectMethod(matchingMethod);
      }
    }
  }

  void _setPreviousDestination() {
    if (_selected != PayoutDestination.payment) {
      _previousDestination = _selected;
    }
  }

  Recipient? get selectedRecipient => recipientProvider?.selectedRecipient;
  Wallet? get selectedWallet => walletsProvider?.selectedWallet;
}
