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

import { Checkbox, MobileShell } from "@/app/_components/core";
import { AppConstants } from "@/core/app_constants";
import { PendingPaymentOrderStorage } from "@/data/storage";
import {
  usePaymentDispatch,
  usePaymentState,
} from "@/stores/payment/payment-context";
import { useUserDispatch, useUserState } from "@/stores/user/user-context";
import { ROUTES } from "@/router/routes";

import {
  SubscriptionBackLink,
  SubscriptionBanner,
  SubscriptionCheckoutButton,
  SubscriptionCoinsOfferSection,
  SubscriptionPaymentMethod,
  SubscriptionPaymentSuccessDialog,
  SubscriptionPlanCard,
  SubscriptionUserRow,
  SubscriptionVipOfferSection,
} from "./components";
import styles from "./components/subscription-screen.module.css";
import {
  SUBSCRIPTION_BANNER_TITLES,
  isCreditPlan,
  isPlanForType,
  isVipPlan,
  toCoinsOfferPlanView,
  toPlanView,
  toVipOfferPlanView,
  type SubscriptionType,
} from "./subscription-screen.helpers";

const FALLBACK_USERNAME = "User name";
export type { SubscriptionType } from "./subscription-screen.helpers";

export interface SubscriptionScreenProps {
  subscriptionType?: SubscriptionType;
  shouldResumePendingOrder?: boolean;
  returnTo?: "chat" | null;
}

export function SubscriptionScreen({
  subscriptionType = "vip",
  shouldResumePendingOrder = false,
  returnTo = null,
}: SubscriptionScreenProps) {
  const router = useRouter();
  const user = useUserState();
  const userDispatch = useUserDispatch();
  const payment = usePaymentState();
  const paymentDispatch = usePaymentDispatch();
  const refreshedPaidOrderRef = useRef<string | null>(null);
  const resumedPendingOrderRef = useRef<string | null>(null);
  const successDialogShownOrderRef = useRef<string | null>(null);
  const syncedVipOrderRef = useRef<string | null>(null);
  const [showPaymentSuccessDialog, setShowPaymentSuccessDialog] =
    useState(false);
  const [pendingChatReturnAfterVipSync, setPendingChatReturnAfterVipSync] =
    useState(false);
  const isVipSubscription = subscriptionType === "vip";

  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 currentUser = user.currentUser;
    const canMarkVipSynced =
      subscriptionType === "vip" &&
      payment.isPaid &&
      payment.currentOrderId &&
      payment.vipStatus?.isVip === true &&
      currentUser &&
      currentUser.isVip !== true;
    if (!canMarkVipSynced) return;
    if (syncedVipOrderRef.current === payment.currentOrderId) return;

    syncedVipOrderRef.current = payment.currentOrderId;
    userDispatch({
      type: "UserUpdate",
      user: {
        ...currentUser,
        isVip: true,
      },
    });
  }, [
    payment.currentOrderId,
    payment.isPaid,
    payment.vipStatus?.isVip,
    subscriptionType,
    user.currentUser,
    userDispatch,
  ]);

  useEffect(() => {
    if (!payment.isPaid || !payment.currentOrderId) return;
    if (successDialogShownOrderRef.current === payment.currentOrderId) return;

    successDialogShownOrderRef.current = payment.currentOrderId;
    setShowPaymentSuccessDialog(true);
  }, [payment.currentOrderId, payment.isPaid]);

  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))
        .slice(0, 3)
        .map((plan) => toPlanView(plan, subscriptionType)),
    [payment.plans, subscriptionType],
  );
  const vipOfferPlans = useMemo(
    () =>
      payment.plans
        .filter(isVipPlan)
        .slice(0, 3)
        .map(toVipOfferPlanView),
    [payment.plans],
  );
  const directCoinsPlans = useMemo(
    () => payment.plans.filter(isCreditPlan).map(toCoinsOfferPlanView),
    [payment.plans],
  );

  const selectedPlan =
    (isVipSubscription
      ? [...vipOfferPlans, ...directCoinsPlans].find(
          (plan) => plan.id === payment.selectedPlanId,
        )
      : 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.avatarUrl ?? user.currentUser?.avatarUrl ?? null;
  const plansStatusMessage =
    subscriptionType === "voice"
      ? "Voice packages are unavailable."
      : "Membership plans are unavailable.";
  const plansAriaLabel =
    subscriptionType === "voice"
      ? "Choose a voice package"
      : "Choose a subscription plan";

  const finishPaymentSuccessClose = () => {
    setPendingChatReturnAfterVipSync(false);
    setShowPaymentSuccessDialog(false);
    paymentDispatch({ type: "PaymentReset" });
    if (returnTo === "chat") {
      router.replace(ROUTES.chat);
    }
  };

  const handlePaymentSuccessClose = () => {
    const shouldWaitForVipSync =
      returnTo === "chat" &&
      subscriptionType === "vip" &&
      user.currentUser?.isVip !== true;

    if (shouldWaitForVipSync) {
      setPendingChatReturnAfterVipSync(true);
      if (payment.vipStatus?.isVip === true && user.currentUser) {
        userDispatch({
          type: "UserUpdate",
          user: {
            ...user.currentUser,
            isVip: true,
          },
        });
      } else {
        userDispatch({ type: "UserFetch" });
      }
      return;
    }

    finishPaymentSuccessClose();
  };

  useEffect(() => {
    if (!pendingChatReturnAfterVipSync) return;
    if (subscriptionType === "vip" && user.currentUser?.isVip !== true) return;

    const timer = window.setTimeout(() => {
      finishPaymentSuccessClose();
    }, 0);

    return () => window.clearTimeout(timer);
    // `finishPaymentSuccessClose` intentionally stays local to this component;
    // this effect is gated by pendingChatReturnAfterVipSync to avoid repeated closes.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [pendingChatReturnAfterVipSync, subscriptionType, user.currentUser?.isVip]);

  useEffect(() => {
    if (isVipSubscription) {
      const firstVipPlanId = vipOfferPlans[0]?.id ?? "";
      const hasSelectedVipPlan = vipOfferPlans.some(
        (plan) => plan.id === payment.selectedPlanId,
      );
      const hasSelectedCoinsPlan = directCoinsPlans.some(
        (plan) => plan.id === payment.selectedPlanId,
      );
      const canSelectPlan =
        firstVipPlanId.length > 0 &&
        (payment.status === "ready" ||
          payment.status === "paid" ||
          payment.status === "failed");

      if (!canSelectPlan || hasSelectedVipPlan || hasSelectedCoinsPlan) return;

      paymentDispatch({
        type: "PaymentPlanSelected",
        planId: firstVipPlanId,
      });
      return;
    }

    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,
    payment.selectedPlanId,
    payment.status,
    directCoinsPlans,
    isVipSubscription,
    selectedPlan,
    subscriptionType,
    vipOfferPlans,
  ]);

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

        {isVipSubscription ? (
          <>
            <SubscriptionVipOfferSection
              plans={vipOfferPlans}
              selectedPlanId={payment.selectedPlanId || selectedPlan?.id || null}
              onSelectPlan={(planId) =>
                paymentDispatch({
                  type: "PaymentPlanSelected",
                  planId,
                })
              }
            />
            <SubscriptionCoinsOfferSection
              plans={directCoinsPlans}
              selectedPlanId={payment.selectedPlanId || selectedPlan?.id || null}
              onSelectPlan={(planId) =>
                paymentDispatch({
                  type: "PaymentPlanSelected",
                  planId,
                })
              }
            />
          </>
        ) : (
          <>
            <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}
            returnTo={returnTo}
          />
        </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>

        <SubscriptionPaymentSuccessDialog
          open={showPaymentSuccessDialog}
          subscriptionType={subscriptionType}
          onClose={handlePaymentSuccessClose}
        />
      </div>
    </MobileShell>
  );
}
