

import 'package:flutter/material.dart';
import 'package:stripe_payment/stripe_payment.dart';

import '../../constants.dart';
import '../../events/eventbus.dart';
import '../../events/events.dart';
import '../../models/order.dart';
import '../../models/payment_platform.dart';
import '../../models/stripe_payment_method.dart';
import '../../routes.dart';
import '../../store/actions.dart';
import '../../store/store.dart';
import '../../utils/utils.dart';


class StripePay extends StatefulWidget {
  final Key key;
  final Order order;
  final PaymentPlatform paymentPlatform;
  final StripePaymentMethod stripePaymentMethod;
  const StripePay(this.order, this.paymentPlatform, {this.key, this.stripePaymentMethod});

  @override
  State<StatefulWidget> createState() {
    return StripePayState();
  }

}

class StripePayState extends State<StripePay> {

  GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();

  bool isSubmitting;

  @override
  Widget build(BuildContext context) {
    store.dispatch(UpdateContext(context));

    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      if (widget.stripePaymentMethod != null) {
        _paymentWithPaymentMethod(context);
      } else {
        _paymentRequestWithCardForm(context);
      }
    });

    return Scaffold(
      key: _scaffoldKey,
      body: Center(
        child: Icon(
          Icons.credit_card,
          size: 40.0,
          color: Colors.black26,
        ),
      ),
    );
  }

  @override
  void initState() {
    super.initState();
    isSubmitting = false;
    StripePayment.setOptions(
        StripeOptions(publishableKey: widget.paymentPlatform.publishableKey,
            merchantId: widget.paymentPlatform.merchantId,
            androidPayMode: 'test')
    );
  }

  _paymentWithPaymentMethod(BuildContext context) async {
    Utils.stripePaymentIntent(widget.order, widget.stripePaymentMethod.customerId,
        widget.stripePaymentMethod.paymentMethodId,
        widget.stripePaymentMethod.paymentMethodType, (response){

      if (response.data['status'] == Constants.STRIPE_STATUS_REQUIRES_CONFIRMATION) {
        StripePayment.confirmPaymentIntent(
          PaymentIntent(
            clientSecret: response.data[Constants.STRIPE_CLIENT_SECRET],
            paymentMethodId: response.data['payment_method'],
          ),
        ).then((paymentIntentResult) {
          if (paymentIntentResult.status == Constants.STRIPE_STATUS_SUCCEDED) {
            Utils.stripeChargedSuccess(widget.order,
                widget.stripePaymentMethod.paymentMethodId,
                paymentIntentResult.paymentIntentId,
                    (response) {
                  eventBus.fire(OnOrderUpdated());
                  Routes.router.navigateTo(context, '/orderdetail/${widget
                      .order.id}', replace: true);
                },
                (showErrorDialog)
            );
          } else {
            showErrorDialog(Exception('Unknown error'));
          }
        }).catchError(showErrorDialog);
      }
    }, (showErrorDialog));
    isSubmitting = true;
    Utils.showSubmitDialog(context);
  }

  _paymentRequestWithCardForm(BuildContext context) async {
    StripePayment.paymentRequestWithCardForm(
      CardFormPaymentRequest()
    ).then((paymentMethod) {
      Utils.stripePaymentIntent(widget.order, null, paymentMethod.id, paymentMethod.type, (response){

        if (response.data['status'] == Constants.STRIPE_STATUS_REQUIRES_CONFIRMATION) {
          StripePayment.confirmPaymentIntent(
            PaymentIntent(
              clientSecret: response.data[Constants.STRIPE_CLIENT_SECRET],
              paymentMethodId: response.data['payment_method'],
            ),
          ).then((paymentIntentResult) {
            if (paymentIntentResult.status == Constants.STRIPE_STATUS_SUCCEDED) {
              Utils.stripeChargedSuccess(widget.order,
                  paymentMethod.id,
                  paymentIntentResult.paymentIntentId,
                      (response) {
                    eventBus.fire(OnOrderUpdated());
                    Routes.router.navigateTo(context, '/orderdetail/${widget
                        .order.id}', replace: true);
                  },
                  (showErrorDialog)
              );
            } else {
              showErrorDialog(Exception('Unknown error'));
            }
          }).catchError(showErrorDialog);
        }
      }, (showErrorDialog),
        cardBrand: paymentMethod.card.brand,
        cardCountry: paymentMethod.card.country,
        cardExpMonth: paymentMethod.card.expMonth,
        cardExpYear: paymentMethod.card.expYear,
        cardFunding: paymentMethod.card.funding,
        cardLast4: paymentMethod.card.last4,
      );
    }).catchError(showErrorDialog);
    isSubmitting = true;
    Utils.showSubmitDialog(context);
  }

  void showErrorDialog(dynamic error) {
    if (isSubmitting) {
      Navigator.of(context).pop();
      isSubmitting = false;
    }
    Utils.showMessageDialog(context, error, onOk: () {
      Navigator.of(context).pop();
      Navigator.of(context).pop();
    });
  }
}