"use client";
/**
 * 订阅 checkout 触发按钮
 *
 * 包装 `SubscriptionCtaButton` —— 通过 payment 状态机创建后端订单并拉起支付。
 */
import { useEffect, useRef, useState } from "react";

import {
  getPaymentUrl,
  getStripeClientSecret,
  isEzpayPayment,
  launchEzpayRedirect,
} from "@/lib/payment/payment_launch";
import {
  usePaymentDispatch,
  usePaymentState,
} from "@/stores/payment/payment-context";
import { AppEnvUtil, Logger } from "@/utils";

import { StripePaymentDialog } from "./stripe-payment-dialog";
import dialogStyles from "./stripe-payment-dialog.module.css";
import { SubscriptionCtaButton } from "./subscription-cta-button";
import styles from "./subscription-cta-button.module.css";

const log = new Logger("SubscriptionCheckoutButton");

export interface SubscriptionCheckoutButtonProps {
  /** 是否可用（未选套餐 / 未勾选协议 → false） */
  disabled?: boolean;
  subscriptionType: "vip" | "topup";
  returnTo?: "chat" | null;
}

export function SubscriptionCheckoutButton({
  disabled = false,
  subscriptionType,
  returnTo = null,
}: SubscriptionCheckoutButtonProps) {
  const payment = usePaymentState();
  const paymentDispatch = usePaymentDispatch();
  const launchedNonceRef = useRef(0);
  const [hiddenStripeClientSecret, setHiddenStripeClientSecret] = useState<
    string | null
  >(null);
  const [isConfirmingEzpay, setIsConfirmingEzpay] = useState(false);

  useEffect(() => {
    if (!payment.payParams || payment.launchNonce <= launchedNonceRef.current) {
      return;
    }

    launchedNonceRef.current = payment.launchNonce;
    const clientSecret = getStripeClientSecret(payment.payParams);
    if (clientSecret) {
      return;
    }

    const paymentUrl = getPaymentUrl(payment.payParams);
    if (paymentUrl) {
      const isEzpay = isEzpayPayment(payment.payParams);

      if (!AppEnvUtil.isProduction() && isEzpay) {
        log.debug("[subscription-checkout] ezpay confirmation required", {
          orderId: payment.currentOrderId,
          paymentUrl,
          subscriptionType,
        });
        return;
      }

      if (isEzpay) {
        void launchEzpayRedirect({
          orderId: payment.currentOrderId,
          paymentUrl,
          subscriptionType,
          returnTo: returnTo ?? undefined,
          onFailed: (errorMessage) =>
            paymentDispatch({ type: "PaymentLaunchFailed", errorMessage }),
        });
        return;
      }

      window.location.href = paymentUrl;
      return;
    }

    paymentDispatch({
      type: "PaymentLaunchFailed",
      errorMessage:
        "Payment parameters did not include a supported URL or Stripe client secret.",
    });
  }, [
    payment.currentOrderId,
    payment.launchNonce,
    payment.payParams,
    paymentDispatch,
    returnTo,
    subscriptionType,
  ]);

  const isLoading =
    payment.isCreatingOrder ||
    payment.isPollingOrder;
  const readyLabel =
    subscriptionType === "topup" ? "Pay and Top Up" : "Pay and Activiate";
  const agreementLabel =
    subscriptionType === "topup"
      ? "Confirm the agreement and Top Up"
      : "Confirm the agreement and Activate";
  const label = payment.isPollingOrder
      ? "Processing payment..."
      : payment.isCreatingOrder
        ? "Creating order..."
        : payment.agreed
          ? readyLabel
          : agreementLabel;

  const handleClick = () => {
    if (disabled || isLoading) return;
    setIsConfirmingEzpay(false);
    setHiddenStripeClientSecret(null);
    paymentDispatch({ type: "PaymentCreateOrderSubmitted" });
  };

  const handleStripeClose = () => {
    if (stripeClientSecret) {
      setHiddenStripeClientSecret(stripeClientSecret);
    }
    if (payment.orderStatus !== "paid") {
      paymentDispatch({ type: "PaymentReset" });
    }
  };

  const handleStripeConfirmed = () => {
    if (stripeClientSecret) {
      setHiddenStripeClientSecret(stripeClientSecret);
    }
  };

  const stripeClientSecret = payment.payParams
    ? getStripeClientSecret(payment.payParams)
    : null;
  const shouldShowStripeDialog =
    stripeClientSecret !== null &&
    stripeClientSecret !== hiddenStripeClientSecret &&
    !payment.isPaid;
  const ezpayPaymentUrl = payment.payParams
    ? getPaymentUrl(payment.payParams)
    : null;
  const shouldShowEzpayConfirmDialog =
    !AppEnvUtil.isProduction() &&
    payment.payParams &&
    isEzpayPayment(payment.payParams) &&
    ezpayPaymentUrl &&
    payment.currentOrderId
      ? true
      : false;

  const handleEzpayConfirm = () => {
    if (!payment.currentOrderId || !ezpayPaymentUrl) return;
    setIsConfirmingEzpay(true);
    void launchEzpayRedirect({
      orderId: payment.currentOrderId,
      paymentUrl: ezpayPaymentUrl,
      subscriptionType,
      returnTo: returnTo ?? undefined,
      onFailed: (errorMessage) => {
        setIsConfirmingEzpay(false);
        paymentDispatch({ type: "PaymentLaunchFailed", errorMessage });
      },
    });
  };

  const handleEzpayCancel = () => {
    log.debug("[subscription-checkout] ezpay confirmation cancelled", {
      orderId: payment.currentOrderId,
      subscriptionType,
    });
    setIsConfirmingEzpay(false);
    paymentDispatch({ type: "PaymentReset" });
  };

  return (
    <>
      <SubscriptionCtaButton
        type="button"
        disabled={disabled}
        isLoading={isLoading}
        onClick={handleClick}
        className={styles.button}
      >
        {label}
      </SubscriptionCtaButton>
      {payment.errorMessage ? (
        <p
          role="alert"
          style={{
            color: "#c0392b",
            fontSize: "0.875rem",
            marginTop: "0.5rem",
            textAlign: "center",
          }}
        >
          {payment.errorMessage}
        </p>
      ) : null}
      {shouldShowEzpayConfirmDialog ? (
        <EzpayRedirectConfirmDialog
          orderId={payment.currentOrderId ?? ""}
          isConfirming={isConfirmingEzpay}
          onCancel={handleEzpayCancel}
          onConfirm={handleEzpayConfirm}
        />
      ) : null}
      {shouldShowStripeDialog ? (
        <StripePaymentDialog
          clientSecret={stripeClientSecret}
          onClose={handleStripeClose}
          onConfirmed={handleStripeConfirmed}
        />
      ) : null}
    </>
  );
}

interface EzpayRedirectConfirmDialogProps {
  orderId: string;
  isConfirming: boolean;
  onCancel: () => void;
  onConfirm: () => void;
}

function EzpayRedirectConfirmDialog({
  orderId,
  isConfirming,
  onCancel,
  onConfirm,
}: EzpayRedirectConfirmDialogProps) {
  return (
    <div
      className={dialogStyles.overlay}
      role="alertdialog"
      aria-modal="true"
      aria-labelledby="ezpay-redirect-title"
    >
      <div className={dialogStyles.dialog}>
        <div className={dialogStyles.header}>
          <h2 id="ezpay-redirect-title" className={dialogStyles.title}>
            Continue to Ezpay?
          </h2>
          <p className={dialogStyles.content}>
            Your order has been created. Continue to Ezpay to finish the
            payment.
          </p>
          <p className={dialogStyles.content}>Order No. {orderId}</p>
        </div>
        <div className={dialogStyles.actions}>
          <button
            type="button"
            className={`${dialogStyles.button} ${dialogStyles.secondary}`}
            disabled={isConfirming}
            onClick={onCancel}
          >
            Cancel
          </button>
          <button
            type="button"
            className={`${dialogStyles.button} ${dialogStyles.primary}`}
            disabled={isConfirming}
            onClick={onConfirm}
          >
            {isConfirming ? "Opening..." : "Continue"}
          </button>
        </div>
      </div>
    </div>
  );
}
