"use client";
/**
 * 订阅页主屏幕
 *
 * 原始 Dart: lib/ui/subscription/...
 *
 * 布局（顶到底）：
 *   1. 顶部返回箭头
 *   2. 用户信息行
 *   3. 渐变横幅
 *   4. 三个套餐卡片
 *   5. 自动续费说明
 *   6. 权益列表卡片
 *   7. 主操作按钮
 *   8. 协议复选框
 */
import { useEffect, useMemo, useRef } from "react";

import { Checkbox, MobileShell } from "@/app/_components/core";
import { AppConstants } from "@/core/app_constants";
import type { PaymentPlan } from "@/data/dto/payment";
import { VIP_BENEFITS } from "@/data/constants/vip-benefits";
import { PendingPaymentOrderStorage } from "@/data/storage";
import {
  usePaymentDispatch,
  usePaymentState,
} from "@/stores/payment/payment-context";
import { useUserDispatch, useUserState } from "@/stores/user/user-context";

import {
  SubscriptionBackLink,
  SubscriptionBanner,
  SubscriptionBenefitsCard,
  SubscriptionCheckoutButton,
  SubscriptionPaymentMethod,
  SubscriptionPlanCard,
  SubscriptionUserRow,
} from "./components";
import styles from "./components/subscription-screen.module.css";
import type { SubscriptionPlanView } from "./components/subscription-plan-card";

const FALLBACK_USERNAME = "User name";
export type SubscriptionType = "vip" | "voice";

const SUBSCRIPTION_BANNER_TITLES: Record<SubscriptionType, string> = {
  vip: "Subscribe to become the VIP Member",
  voice: "Buy Voice Message Package",
};

function isVipPlan(plan: PaymentPlan): boolean {
  return plan.orderType.startsWith("vip_") || plan.planId.startsWith("vip_");
}

function isVoicePackagePlan(plan: PaymentPlan): boolean {
  const orderType = plan.orderType.toLowerCase();
  const planId = plan.planId.toLowerCase();
  return (
    plan.dolAmount !== null ||
    orderType.startsWith("dol_") ||
    planId.startsWith("dol_") ||
    orderType.includes("voice") ||
    planId.includes("voice")
  );
}

function isPlanForType(
  plan: PaymentPlan,
  subscriptionType: SubscriptionType,
): boolean {
  return subscriptionType === "voice"
    ? isVoicePackagePlan(plan)
    : isVipPlan(plan);
}

function currencySymbol(currency: string): string {
  if (currency === "CNY") return "¥";
  if (currency === "USD") return "$";
  return `${currency} `;
}

function formatAmount(amountCents: number | null): string | null {
  if (amountCents === null) return null;
  return (amountCents / 100).toFixed(2).replace(/\.00$/, "");
}

function planCaption(
  plan: PaymentPlan,
  subscriptionType: SubscriptionType,
): string {
  if (subscriptionType === "voice") {
    return plan.dolAmount === null
      ? "Voice package"
      : `${plan.dolAmount} voice messages`;
  }
  if (plan.dailyPriceCents !== null) {
    const dailyPrice = formatAmount(plan.dailyPriceCents);
    return dailyPrice === null
      ? "Lifetime"
      : `${currencySymbol(plan.currency)}${dailyPrice}/day`;
  }
  if (plan.vipDays === null) return "Lifetime";
  const fallbackDailyPrice = plan.amountCents / Math.max(plan.vipDays, 1);
  return `${currencySymbol(plan.currency)}${formatAmount(fallbackDailyPrice)}/day`;
}

function toPlanView(
  plan: PaymentPlan,
  subscriptionType: SubscriptionType,
): SubscriptionPlanView {
  return {
    id: plan.planId,
    name: plan.planName,
    price: formatAmount(plan.amountCents) ?? "",
    originalPrice: formatAmount(plan.originalAmountCents),
    perDay: planCaption(plan, subscriptionType),
    currencySymbol: currencySymbol(plan.currency),
  };
}

export interface SubscriptionScreenProps {
  subscriptionType?: SubscriptionType;
  shouldResumePendingOrder?: boolean;
}

export function SubscriptionScreen({
  subscriptionType = "vip",
  shouldResumePendingOrder = false,
}: SubscriptionScreenProps) {
  const user = useUserState();
  const userDispatch = useUserDispatch();
  const payment = usePaymentState();
  const paymentDispatch = usePaymentDispatch();
  const refreshedPaidOrderRef = useRef<string | null>(null);
  const resumedPendingOrderRef = useRef<string | null>(null);

  useEffect(() => {
    if (payment.status === "idle") {
      paymentDispatch({ type: "PaymentInit" });
    }
  }, [payment.status, paymentDispatch]);

  useEffect(() => {
    if (!payment.isPaid || !payment.currentOrderId) return;
    if (refreshedPaidOrderRef.current === payment.currentOrderId) return;
    refreshedPaidOrderRef.current = payment.currentOrderId;
    userDispatch({ type: "UserFetch" });
  }, [payment.currentOrderId, payment.isPaid, userDispatch]);

  useEffect(() => {
    const canInspectPendingOrder =
      payment.status === "ready" ||
      (!shouldResumePendingOrder &&
        (payment.isPollingOrder || payment.isPaid || payment.status === "failed"));
    if (!canInspectPendingOrder) return;

    let cancelled = false;

    const handlePendingOrder = async () => {
      const result = await PendingPaymentOrderStorage.getPendingOrderForType(
        subscriptionType,
      );
      if (cancelled || !result.success || result.data === null) return;

      if (!shouldResumePendingOrder) {
        await PendingPaymentOrderStorage.clearPendingOrder();
        if (
          payment.currentOrderId === result.data.orderId &&
          (payment.isPollingOrder || payment.isPaid || payment.status === "failed")
        ) {
          paymentDispatch({ type: "PaymentReset" });
        }
        return;
      }

      if (payment.currentOrderId === result.data.orderId) return;
      if (resumedPendingOrderRef.current === result.data.orderId) return;

      resumedPendingOrderRef.current = result.data.orderId;
      paymentDispatch({
        type: "PaymentReturned",
        orderId: result.data.orderId,
      });
    };

    void handlePendingOrder();
    return () => {
      cancelled = true;
    };
  }, [
    payment.currentOrderId,
    payment.isPaid,
    payment.isPollingOrder,
    payment.status,
    paymentDispatch,
    shouldResumePendingOrder,
    subscriptionType,
  ]);

  useEffect(() => {
    if (!payment.currentOrderId) return;
    if (!payment.isPaid && payment.status !== "failed") return;

    void PendingPaymentOrderStorage.clearPendingOrder();
  }, [payment.currentOrderId, payment.isPaid, payment.status]);

  const plans = useMemo(
    () =>
      payment.plans
        .filter((plan) => isPlanForType(plan, subscriptionType))
        .map((plan) => toPlanView(plan, subscriptionType)),
    [payment.plans, subscriptionType],
  );

  const selectedPlan =
    plans.find((plan) => plan.id === payment.selectedPlanId) ?? null;
  const isPaymentBusy =
    payment.isCreatingOrder ||
    payment.isPollingOrder ||
    payment.isCheckingVipStatus;
  const canActivate =
    selectedPlan !== null && payment.agreed && !isPaymentBusy;

  const name = user.currentUser?.username ?? FALLBACK_USERNAME;
  const avatarUrl = user.currentUser?.avatarUrl ?? null;
  const autoRenewCaption = payment.autoRenew
    ? "It will automatically renew upon expiration, and can be canceled at any time"
    : "This plan is a one-time purchase and will not automatically renew";
  const plansStatusMessage =
    subscriptionType === "voice"
      ? "Voice packages are unavailable."
      : "Membership plans are unavailable.";
  const plansAriaLabel =
    subscriptionType === "voice"
      ? "Choose a voice package"
      : "Choose a subscription plan";

  useEffect(() => {
    if (payment.isLoadingPlans || payment.plans.length === 0) return;
    if (selectedPlan !== null) return;

    const nextPlan = payment.plans.find((plan) =>
      isPlanForType(plan, subscriptionType),
    );
    if (!nextPlan) return;

    paymentDispatch({
      type: "PaymentPlanSelected",
      planId: nextPlan.planId,
    });
  }, [
    payment.isLoadingPlans,
    payment.plans,
    paymentDispatch,
    selectedPlan,
    subscriptionType,
  ]);

  return (
    <MobileShell>
      <div className={styles.shell}>
        <header className={styles.header}>
          <SubscriptionBackLink className={styles.backSlot} />
        </header>

        <section className={styles.userSlot}>
          <SubscriptionUserRow name={name} avatarUrl={avatarUrl} />
        </section>

        <section className={styles.bannerSlot}>
          <SubscriptionBanner
            title={SUBSCRIPTION_BANNER_TITLES[subscriptionType]}
          />
        </section>

        <section
          className={styles.plansRow}
          aria-label={plansAriaLabel}
        >
          {plans.length > 0 ? (
            plans.map((plan, index) => (
              <SubscriptionPlanCard
                key={plan.id}
                plan={plan}
                gradientIndex={index}
                selected={payment.selectedPlanId === plan.id}
                onClick={() =>
                  paymentDispatch({
                    type: "PaymentPlanSelected",
                    planId: plan.id,
                  })
                }
              />
            ))
          ) : (
            <p className={styles.plansStatus}>
              {payment.isLoadingPlans
                ? "Loading membership plans..."
                : payment.errorMessage ?? plansStatusMessage}
            </p>
          )}
        </section>

        <p className={styles.autoRenewCaption}>{autoRenewCaption}</p>

        <section className={styles.benefitsSlot}>
          {subscriptionType === "voice" ? (
            <div className={styles.benefitsPlaceholder} aria-hidden="true" />
          ) : (
            <SubscriptionBenefitsCard
              title="VIP Membership Benefits"
              items={VIP_BENEFITS}
            />
          )}
        </section>

        <section className={styles.paymentMethodSlot}>
          <SubscriptionPaymentMethod
            value={payment.payChannel}
            disabled={isPaymentBusy}
            onChange={(payChannel) =>
              paymentDispatch({
                type: "PaymentPayChannelChanged",
                payChannel,
              })
            }
          />
        </section>

        <div className={styles.ctaSlot}>
          <SubscriptionCheckoutButton
            disabled={!canActivate}
            subscriptionType={subscriptionType}
          />
        </div>

        <div className={styles.agreementSlot}>
          <Checkbox
            checked={payment.agreed}
            onChange={(agreed) =>
              paymentDispatch({
                type: "PaymentAgreementChanged",
                agreed,
              })
            }
            label={
              <span className={styles.agreementLabel}>
                I agree to the{" "}
                <a
                  href={AppConstants.privacyPolicyUrl}
                  target="_blank"
                  rel="noreferrer"
                  className={styles.agreementLink}
                >
                  VIP Membership Benefits Agreement
                </a>{" "}
                and{" "}
                <a
                  href={AppConstants.termsOfServiceUrl}
                  target="_blank"
                  rel="noreferrer"
                  className={styles.agreementLink}
                >
                  Automatic renewal Agreement
                </a>
              </span>
            }
          />
        </div>
      </div>
    </MobileShell>
  );
}
