import 'dart:async';

import 'package:flutter/foundation.dart';

import 'package:pshared/provider/payment/flow.dart';
import 'package:pshared/provider/payment/amount.dart';
import 'package:pshared/provider/payment/provider.dart';
import 'package:pshared/provider/payment/quotation/quotation.dart';
import 'package:pshared/provider/recipient/provider.dart';

import 'package:pweb/services/posthog.dart';


class PaymentPageController extends ChangeNotifier {
  PaymentProvider? _payment;
  QuotationProvider? _quotation;
  PaymentFlowProvider? _flow;
  PaymentAmountProvider? _amount;
  RecipientsProvider? _recipients;

  bool _isSending = false;
  Exception? _error;

  bool get isSending => _isSending;
  Exception? get error => _error;

  void update(
    PaymentProvider payment,
    QuotationProvider quotation,
    PaymentFlowProvider flow,
    PaymentAmountProvider amount,
    RecipientsProvider recipients,
  ) {
    _payment = payment;
    _quotation = quotation;
    _flow = flow;
    _amount = amount;
    _recipients = recipients;
  }

  Future<bool> sendPayment() async {
    if (_isSending) return false;
    final payment = _payment;
    if (payment == null) {
      _setError(StateError('Payment provider is not ready'));
      return false;
    }

    try {
      _setSending(true);
      _error = null;
      final result = await payment.pay();
      return result != null && payment.error == null;
    } catch (e) {
      _setError(e);
      return false;
    } finally {
      _setSending(false);
    }
  }

  void resetAfterSuccess() {
    _quotation?.reset();
    _payment?.reset();
    _flow?.setManualPaymentData(null);
    _amount?.setComment('');
    _recipients?.setCurrentObject(null);
  }

  void handleSuccess() {
    unawaited(PosthogService.paymentInitiated(method: _flow?.selectedType));
    resetAfterSuccess();
  }

  void _setSending(bool value) {
    if (_isSending == value) return;
    _isSending = value;
    notifyListeners();
  }

  void _setError(Object error) {
    _error = error is Exception ? error : Exception(error.toString());
    notifyListeners();
  }
}
