

import 'package:flutter/material.dart';
import '../../vendor/stripe_sdk/lib/stripe_sdk_ui.dart';
import '../../utils/mini_stripe_api.dart';

import '../../constants.dart';
import '../../events/eventbus.dart';
import '../../events/events.dart';
import '../../generated/l10n.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 MobileStripePayWeb extends StatefulWidget {
  final Order order;
  final PaymentPlatform paymentPlatform;
  final StripePaymentMethod? stripePaymentMethod;
  const MobileStripePayWeb(this.order, this.paymentPlatform, {Key? key, this.stripePaymentMethod});

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

}

class MobileStripePayWebState extends State<MobileStripePayWeb> {

  GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
  final formKey = GlobalKey<FormState>();
  final card = StripeCard();

  CardForm? form;

  bool isSubmitting = false;

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

    Widget body = Center(
      child: Icon(
        Icons.credit_card,
        size: 40.0,
        color: Colors.black26,
      ),
    );
    if (widget.stripePaymentMethod == null) {
      form = CardForm(card: card, formKey: formKey, displayPostalCode: false,);
      body = ListView(
        children: <Widget>[form!,],
      );
    }

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

    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(
        leading: IconButton(
          icon: Icon(Icons.arrow_back_ios),
          onPressed: (){
            Navigator.of(context).pop();
          },
        ),
        title: Text(S.of(context).add_credit_card),
        backgroundColor: Theme.of(context).primaryColor,
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.check),
            onPressed: widget.stripePaymentMethod == null ? () {
              if (formKey.currentState != null && formKey.currentState!.validate()) {
                formKey.currentState!.save();
                _paymentRequestWithCard(context);
              } else {
                ScaffoldMessenger.of(context).showSnackBar(
                    messageSnackBar(
                        context, S.of(context).this_credit_card_is_invalid
                    )
                );
              }
            } : null,
          ),
        ],
      ),
      body: body,
    );
  }

  @override
  void initState() {
    super.initState();
    isSubmitting = false;
    MiniStripeApi.init(widget.paymentPlatform.publishableKey!);
  }

  SnackBar messageSnackBar(BuildContext context, String message) {
    Column column = Column(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[Text(
        message,
        style: TextStyle(
          color: Colors.white,
        ),
      )],
    );
    return SnackBar(
      content: Container(
        height: 45.0,
        child: column,
      ),
      action: SnackBarAction(
        label: S.of(context).ok,
        onPressed: () {
          ScaffoldMessenger.of(context).hideCurrentSnackBar();
        },
      ),
    );
  }

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

      if (response.data['status'] == Constants.STRIPE_STATUS_REQUIRES_CONFIRMATION) {
        await MiniStripeApi.instance.confirmPaymentIntent(
          response.data[Constants.STRIPE_CLIENT_SECRET],
          data: {
            'payment_method': response.data['payment_method'],
          },
        ).then((result2) {
          if (result2['status'] == Constants.STRIPE_STATUS_SUCCEDED) {
            Utils.stripeChargedSuccess(widget.order,
                widget.stripePaymentMethod!.paymentMethodId,
                result2['id'], (response) {
                  if (isSubmitting) {
                    Navigator.of(context).pop();
                  }
                  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);
  }

  _paymentRequestWithCard(BuildContext context) async {
    isSubmitting = true;
    Utils.showSubmitDialog(context);
    await MiniStripeApi.instance.createPaymentMethodFromCard(card)
        .then((result) {
      Utils.stripePaymentIntent(widget.order, null, result['id'], result['type'], (response) async {
        if (response.data['status'] == Constants.STRIPE_STATUS_REQUIRES_CONFIRMATION) {
          await MiniStripeApi.instance.confirmPaymentIntent(
            response.data[Constants.STRIPE_CLIENT_SECRET],
            data: {
              'payment_method': response.data['payment_method'],
            }
          ).then((result2) {
            if (result2['status'] == Constants.STRIPE_STATUS_SUCCEDED) {
              Utils.stripeChargedSuccess(widget.order,
                result['id'], // payment method id
                result2['id'], (response) { // payment intent id
                  if (isSubmitting) {
                    Navigator.of(context).pop();
                  }
                  eventBus.fire(OnOrderUpdated());
                  Routes.router.navigateTo(context, '/orderdetail/${widget
                      .order.id}', replace: true);
                },
                (showErrorDialog)
              );
            } else {
              showErrorDialog(Exception('Unknown error'));
            }
          }).catchError(showErrorDialog);
        }
      }, (showErrorDialog),
        cardBrand: result['card']['brand'],
        cardCountry: result['card']['country'],
        cardExpMonth: result['card']['exp_month'],
        cardExpYear: result['card']['exp_year'],
        cardFunding: result['card']['funding'],
        cardLast4: result['card']['last4'],
      );
    }).catchError(showErrorDialog);
  }

  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();
    });
  }
}