"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
module.exports = StripeCheckout;
var _jsxRuntime = require("react/jsx-runtime");
var _Center = _interopRequireDefault(require("@arcblock/ux/lib/Center"));
var _Dialog = _interopRequireDefault(require("@arcblock/ux/lib/Dialog"));
var _context = require("@arcblock/ux/lib/Locale/context");
var _material = require("@mui/material");
var _system = require("@mui/system");
var _ahooks = require("ahooks");
var _react = require("react");
var _mobile = require("../../../hooks/mobile");
var _loadingButton = _interopRequireDefault(require("../../../components/loading-button"));
var _confirmRecovery = require("./confirm-recovery");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const {
  Elements,
  PaymentElement,
  useElements,
  useStripe,
  loadStripe,
  LinkAuthenticationElement
} = globalThis.__STRIPE_COMPONENTS__;
const PaymentElementContainer = (0, _system.styled)("div")`
  width: 100%;
  opacity: 0;
  transition: opacity 300ms ease;
  &.visible {
    opacity: 1;
  }
`;
function StripeCheckoutForm({
  clientSecret,
  intentType,
  customer,
  mode,
  onConfirm,
  onSkip = null,
  returnUrl = "",
  submitButtonText = ""
}) {
  const stripe = useStripe();
  const elements = useElements();
  const {
    t
  } = (0, _context.useLocaleContext)();
  const theme = (0, _material.useTheme)();
  const [state, setState] = (0, _ahooks.useSetState)({
    message: "",
    confirming: false,
    loaded: false,
    showBillingForm: false,
    isTransitioning: false,
    paymentMethod: "card"
  });
  const handlePaymentMethodChange = event => {
    const method = event.value?.type;
    const needsBillingInfo = method === "google_pay" || method === "apple_pay";
    const shouldShowForm = needsBillingInfo && !isCompleteBillingAddress(customer.address);
    if (shouldShowForm && !state.showBillingForm) {
      setState({
        isTransitioning: true
      });
      setTimeout(() => {
        setState({
          isTransitioning: false,
          paymentMethod: method,
          showBillingForm: true
        });
      }, 300);
    } else {
      setState({
        showBillingForm: false,
        paymentMethod: method,
        isTransitioning: false
      });
    }
  };
  const isCompleteBillingAddress = address => {
    return address && address.line1 && address.city && address.state && address.postal_code && address.country;
  };
  (0, _react.useEffect)(() => {
    if (!stripe) {
      return;
    }
    if (!clientSecret) {
      return;
    }
    const method = intentType === "payment_intent" ? "retrievePaymentIntent" : "retrieveSetupIntent";
    stripe[method](clientSecret).then(({
      paymentIntent,
      setupIntent
    }) => {
      const intent = paymentIntent || setupIntent;
      switch (intent?.status) {
        case "succeeded":
          setState({
            message: t("paymentCredit.preparePayMessage.succeeded")
          });
          break;
        case "processing":
          setState({
            message: t("paymentCredit.preparePayMessage.processing")
          });
          break;
        case "requires_payment_method":
        // 忽略该状态
        default:
          break;
      }
    });
  }, [stripe, clientSecret]);
  const handleSubmit = (0, _react.useCallback)(async e => {
    e.preventDefault();
    if (!stripe || !elements) {
      return;
    }
    try {
      setState({
        confirming: true,
        message: ""
      });
      const method = intentType === "payment_intent" ? "confirmPayment" : "confirmSetup";
      const {
        error: submitError
      } = await elements.submit();
      if (submitError) {
        setState({
          confirming: false
        });
        return;
      }
      const {
        error,
        paymentIntent,
        setupIntent
      } = await stripe[method]({
        elements,
        redirect: "if_required",
        confirmParams: {
          return_url: returnUrl || window.location.href,
          ...(!state.showBillingForm ? {
            payment_method_data: {
              billing_details: {
                name: customer.name,
                phone: customer.phone,
                email: customer.email,
                address: {
                  ...(customer.address || {}),
                  country: customer.address?.country || "us",
                  line1: customer.address?.line1 || "",
                  line2: customer.address?.line2 || "",
                  city: customer.address?.city || "",
                  state: customer.address?.state || "",
                  postal_code: customer.address?.postal_code || "00000"
                }
              }
            }
          } : {})
        }
      });
      const intent = paymentIntent || setupIntent;
      if (intent?.status === "canceled" || intent?.status === "requires_payment_method") {
        setState({
          confirming: false
        });
        return;
      }
      setState({
        confirming: false
      });
      if (error) {
        if (error.type === "validation_error") {
          return;
        }
        setState({
          message: error.message
        });
        return;
      }
      onConfirm();
    } catch (err) {
      console.error(err);
      const recovery = await (0, _confirmRecovery.recoverStripeConfirmResult)(stripe, intentType, clientSecret, err);
      setState({
        confirming: false
      });
      if (recovery.action === "failed") {
        setState({
          message: recovery.message
        });
        return;
      }
      onConfirm();
    }
  }, [customer, intentType, stripe, state.showBillingForm, returnUrl]
  // eslint-disable-line
  );
  return /* @__PURE__ */(0, _jsxRuntime.jsxs)(Content, {
    onSubmit: handleSubmit,
    children: [(!state.paymentMethod || ["link", "card"].includes(state.paymentMethod)) && /* @__PURE__ */(0, _jsxRuntime.jsx)(LinkAuthenticationElement, {
      options: {
        defaultValues: {
          email: customer.email
        }
      }
    }), /* @__PURE__ */(0, _jsxRuntime.jsx)(PaymentElementContainer, {
      className: !state.isTransitioning ? "visible" : "",
      children: /* @__PURE__ */(0, _jsxRuntime.jsx)(PaymentElement, {
        options: {
          layout: "auto",
          fields: {
            billingDetails: state.showBillingForm ? "auto" : "never"
          },
          readOnly: state.confirming,
          defaultValues: {
            billingDetails: {
              name: customer.name,
              phone: customer.phone,
              email: customer.email,
              address: customer.address
            }
          },
          appearance: {
            theme: theme.palette.mode,
            variables: {
              colorPrimary: theme.palette.primary.main,
              colorBackground: theme.palette.background.paper,
              colorText: theme.palette.text.primary,
              colorDanger: theme.palette.error.main,
              borderRadius: "4px"
            }
          }
        },
        onChange: handlePaymentMethodChange,
        onReady: () => setState({
          loaded: true
        })
      })
    }), (!stripe || !elements || !state.loaded) && /* @__PURE__ */(0, _jsxRuntime.jsx)(_Center.default, {
      relative: "parent",
      children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.CircularProgress, {})
    }), stripe && elements && state.loaded && /* @__PURE__ */(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
      children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_loadingButton.default, {
        fullWidth: true,
        sx: {
          mt: 2,
          mb: 1,
          borderRadius: 0,
          fontSize: "0.875rem"
        },
        type: "submit",
        disabled: state.confirming || !state.loaded,
        loading: state.confirming,
        variant: "contained",
        color: "primary",
        size: "large",
        children: submitButtonText || t("payment.checkout.continue", {
          action: t(`payment.checkout.${mode}`)
        })
      }), onSkip && /* @__PURE__ */(0, _jsxRuntime.jsx)(_loadingButton.default, {
        fullWidth: true,
        sx: {
          mb: 1,
          borderRadius: 0,
          fontSize: "0.875rem",
          borderColor: "divider"
        },
        disabled: state.confirming,
        variant: "outlined",
        color: "primary",
        onClick: () => onSkip(),
        children: t("payment.checkout.skipPaymentMethod", {
          defaultValue: "Skip, bind later"
        })
      })]
    }), state.message && /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
      sx: {
        mt: 1,
        color: "error.main"
      },
      children: state.message
    })]
  });
}
const Content = (0, _system.styled)("form")`
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  min-height: 320px;
`;
function StripeCheckout({
  clientSecret,
  intentType,
  publicKey,
  mode,
  customer,
  onConfirm,
  onCancel,
  onSkip = null,
  returnUrl = "",
  title = "",
  submitButtonText = ""
}) {
  const stripePromise = loadStripe(publicKey);
  const {
    isMobile
  } = (0, _mobile.useMobile)();
  const {
    t,
    locale
  } = (0, _context.useLocaleContext)();
  const theme = (0, _material.useTheme)();
  const [state, setState] = (0, _ahooks.useSetState)({
    open: true,
    closable: true
  });
  const handleClose = (_, reason) => {
    if (reason === "backdropClick") {
      return;
    }
    setState({
      open: false
    });
    onCancel();
  };
  return /* @__PURE__ */(0, _jsxRuntime.jsx)(_Dialog.default, {
    title: title || t("payment.checkout.cardPay", {
      action: t(`payment.checkout.${mode}`)
    }),
    showCloseButton: state.closable,
    open: state.open,
    onClose: handleClose,
    disableEscapeKeyDown: true,
    sx: {
      ".StripeElement": {
        minWidth: isMobile ? "100%" : "500px",
        py: 1
      },
      form: {
        justifyContent: "flex-start"
      },
      ".StripeElement--focus": {
        borderColor: theme.palette.primary.main
      },
      ".StripeElement--invalid": {
        borderColor: theme.palette.error.main
      },
      ".StripeElement--complete": {
        borderColor: theme.palette.success.main
      }
    },
    PaperProps: {
      style: {
        minWidth: isMobile ? "100%" : "500px"
      }
    },
    children: /* @__PURE__ */(0, _jsxRuntime.jsx)(Elements, {
      options: {
        clientSecret,
        locale: locale === "zh" ? "zh-CN" : "en",
        appearance: {
          theme: theme.palette.mode,
          variables: {
            colorPrimary: theme.palette.primary.main,
            colorBackground: theme.palette.background.paper,
            colorText: theme.palette.text.primary,
            colorDanger: theme.palette.error.main
          }
        }
      },
      stripe: stripePromise,
      children: /* @__PURE__ */(0, _jsxRuntime.jsx)(StripeCheckoutForm, {
        clientSecret,
        intentType,
        mode,
        customer,
        onConfirm,
        onSkip,
        returnUrl,
        submitButtonText
      })
    })
  });
}