import { useCallback, useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import { getAvailablePlans, purchaseSubscription, setAutoRenew } from '../api/client';
import type { ActiveSubscription, PlanDefinition } from '../types';

// Plan tier order (matches PLAN_ORDER in billing-subscription.mjs)
const PLAN_ORDER: Record<string, number> = { free: 0, lite: 1, standard: 2, pro: 3 };

function formatYuan(cents: number) {
  return `¥${(cents / 100).toFixed(cents % 100 === 0 ? 0 : 2)}`;
}

function formatTokens(tokens: number) {
  if (tokens === 0) return '不限';
  if (tokens >= 10_000) return `${(tokens / 10_000).toFixed(0)} 万`;
  if (tokens >= 1_000) return `${(tokens / 1_000).toFixed(0)}k`;
  return tokens.toLocaleString('zh-CN');
}

function callsApprox(tokens: number) {
  if (tokens === 0) return '不限';
  return `约 ${Math.floor(tokens / 3_000).toLocaleString()} 次`;
}

function imageCallsApprox(images: number) {
  if (images === 0) return '不限';
  return `约 ${images.toLocaleString()} 次`;
}

const MODEL_TIER_LABELS: Record<string, string> = {
  basic: '基础模型',
  standard: '标准模型',
  premium: '旗舰模型',
};

const PLAN_HIGHLIGHT: Record<string, string> = {
  lite: '',
  standard: '推荐',
  pro: '旗舰',
};

type SubscribeModalProps = {
  open: boolean;
  onClose: () => void;
  onSuccess: (subscription: ActiveSubscription, balanceCents: number) => void;
  onRechargeNeeded: (shortfallCents: number) => void;
};

export function SubscribeModal({ open, onClose, onSuccess, onRechargeNeeded }: SubscribeModalProps) {
  const [plans, setPlans] = useState<PlanDefinition[]>([]);
  const [currentSub, setCurrentSub] = useState<ActiveSubscription | null>(null);
  const [balanceCents, setBalanceCents] = useState(0);
  const [loading, setLoading] = useState(false);
  const [purchasing, setPurchasing] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [successMessage, setSuccessMessage] = useState<string | null>(null);
  const [shortfall, setShortfall] = useState<{ planType: string; shortfallCents: number } | null>(null);
  const [autoRenew, setAutoRenewState] = useState(false);
  const [togglingAutoRenew, setTogglingAutoRenew] = useState(false);

  const reset = useCallback(() => {
    setPurchasing(null);
    setError(null);
    setSuccessMessage(null);
    setShortfall(null);
  }, []);

  useEffect(() => {
    if (!open) { reset(); return; }
    setLoading(true);
    setError(null);
    void getAvailablePlans()
      .then((data) => {
        setPlans(data.plans);
        setCurrentSub(data.subscription);
        setBalanceCents(data.balanceCents);
        setAutoRenewState(data.subscription?.autoRenew ?? false);
      })
      .catch((err) => setError(err instanceof Error ? err.message : '无法加载套餐列表'))
      .finally(() => setLoading(false));
  }, [open, reset]);

  const handlePurchase = async (planType: string) => {
    setPurchasing(planType);
    setError(null);
    setShortfall(null);
    setSuccessMessage(null);
    try {
      const result = await purchaseSubscription(planType, autoRenew);
      const plan = plans.find((p) => p.key === planType);
      const renewNote = autoRenew ? '，已开启自动续费' : '';
      setSuccessMessage(`已开通 ${plan?.name ?? planType}${renewNote}，余额剩余 ${formatYuan(result.balanceCents)}`);
      setCurrentSub(result.subscription);
      setBalanceCents(result.balanceCents);
      setAutoRenewState(result.subscription.autoRenew);
      window.setTimeout(() => onSuccess(result.subscription, result.balanceCents), 1000);
    } catch (err: unknown) {
      type E = { status?: number; code?: string; message?: string; details?: Record<string, unknown> };
      const e = err as E;
      if (e.status === 402 || e.code === 'INSUFFICIENT_BALANCE') {
        const plan = plans.find((p) => p.key === planType);
        const sf = Math.max(0, (plan?.priceCents ?? 0) - balanceCents);
        setShortfall({ planType, shortfallCents: sf });
      } else {
        setError(e.message ?? '订阅失败，请稍后重试');
      }
    } finally {
      setPurchasing(null);
    }
  };

  const handleToggleAutoRenew = async (enabled: boolean) => {
    setTogglingAutoRenew(true);
    try {
      await setAutoRenew(enabled);
      setAutoRenewState(enabled);
      setCurrentSub((s) => s ? { ...s, autoRenew: enabled } : s);
    } catch (err: unknown) {
      const e = err as { message?: string };
      setError(e.message ?? '设置失败');
    } finally {
      setTogglingAutoRenew(false);
    }
  };

  if (!open) return null;

  return createPortal(
    <div className="recharge-backdrop" role="presentation" onClick={onClose}>
      <div
        className="subscribe-dialog"
        role="dialog"
        aria-modal="true"
        aria-labelledby="subscribe-title"
        onClick={(e) => e.stopPropagation()}
      >
        {/* Header */}
        <div className="subscribe-dialog-head">
          <div>
            <p className="recharge-eyebrow">升级套餐</p>
            <h3 id="subscribe-title">选择适合你的方案</h3>
          </div>
          <button type="button" className="recharge-close" onClick={onClose} aria-label="关闭">✕</button>
        </div>

        {/* Balance row */}
        <div className="subscribe-balance-row">
          <span>当前余额</span>
          <strong>{formatYuan(balanceCents)}</strong>
          {currentSub && currentSub.planType !== 'free' && (
            <span className="subscribe-current-plan-tag">
              当前：{currentSub.planType} · 至 {new Date(currentSub.expiresAt).toLocaleDateString('zh-CN')}
            </span>
          )}
        </div>

        {/* Plan grid */}
        {loading ? (
          <p className="recharge-muted" style={{ padding: '24px 0', textAlign: 'center' }}>加载套餐中…</p>
        ) : (
          <div className="subscribe-plan-grid">
            {plans.map((plan) => {
              const canAfford = balanceCents >= plan.priceCents;
              const isActive = currentSub?.planType === plan.key;
              const badge = PLAN_HIGHLIGHT[plan.key];
              const isBuying = purchasing === plan.key;
              const currentOrder = PLAN_ORDER[currentSub?.planType ?? 'free'] ?? 0;
              const planOrder = PLAN_ORDER[plan.key] ?? 0;
              const isDowngrade = !!currentSub && planOrder < currentOrder;
              const isUpgrade = !!currentSub && !isActive && planOrder > currentOrder;

              return (
                <div
                  key={plan.key}
                  className={[
                    'subscribe-plan-card',
                    isActive ? 'subscribe-plan-card--active' : '',
                    badge === '推荐' ? 'subscribe-plan-card--highlight' : '',
                    isDowngrade ? 'subscribe-plan-card--locked' : '',
                  ].filter(Boolean).join(' ')}
                >
                  {badge && <span className="subscribe-plan-badge-top">{badge}</span>}

                  <div className="subscribe-plan-card-head">
                    <span className="subscribe-plan-name">{plan.name}</span>
                    <div className="subscribe-plan-price">
                      <span className="subscribe-plan-price-num">{formatYuan(plan.priceCents)}</span>
                      <span className="subscribe-plan-price-unit">/月</span>
                    </div>
                  </div>

                  <ul className="subscribe-plan-features">
                    <li>
                      <span className="subscribe-feat-label">对话</span>
                      <span className="subscribe-feat-val">{callsApprox(plan.periodTokens)}</span>
                    </li>
                    <li>
                      <span className="subscribe-feat-label">图片</span>
                      <span className="subscribe-feat-val">{imageCallsApprox(plan.periodImages)}</span>
                    </li>
                    <li>
                      <span className="subscribe-feat-label">Token</span>
                      <span className="subscribe-feat-val">{formatTokens(plan.periodTokens)}</span>
                    </li>
                    <li>
                      <span className="subscribe-feat-label">模型</span>
                      <span className="subscribe-feat-val">{MODEL_TIER_LABELS[plan.modelTier] ?? plan.modelTier}</span>
                    </li>
                    {plan.overageRate < 1 && (
                      <li>
                        <span className="subscribe-feat-label">超量</span>
                        <span className="subscribe-feat-val">{Math.round(plan.overageRate * 10)} 折</span>
                      </li>
                    )}
                  </ul>

                  {isActive ? (
                    <button className="subscribe-plan-btn subscribe-plan-btn--current" disabled>当前套餐</button>
                  ) : isDowngrade ? (
                    <button className="subscribe-plan-btn subscribe-plan-btn--locked" disabled>到期后可选</button>
                  ) : (
                    <button
                      className={`subscribe-plan-btn ${canAfford ? 'subscribe-plan-btn--buy' : 'subscribe-plan-btn--short'}`}
                      disabled={!!purchasing}
                      onClick={() => void handlePurchase(plan.key)}
                    >
                      {isBuying
                        ? '处理中…'
                        : canAfford
                          ? isUpgrade ? `升级 ${formatYuan(plan.priceCents)}` : `订阅 ${formatYuan(plan.priceCents)}`
                          : `差额 ${formatYuan(plan.priceCents - balanceCents)}`}
                    </button>
                  )}
                </div>
              );
            })}
          </div>
        )}

        {/* Feedback messages */}
        {shortfall && !successMessage && (
          <div className="subscribe-shortfall">
            <span>余额不足，还差 <strong>{formatYuan(shortfall.shortfallCents)}</strong> 才能订阅该套餐</span>
            <button
              className="recharge-pay-btn"
              onClick={() => { onClose(); onRechargeNeeded(shortfall.shortfallCents); }}
            >
              去充值差额
            </button>
          </div>
        )}
        {error && <p className="recharge-error">{error}</p>}
        {successMessage && <p className="recharge-success">✓ {successMessage}</p>}

        {/* Auto-renew toggle */}
        <div className="subscribe-autorenew-row">
          <label className="subscribe-autorenew-label">
            <input
              type="checkbox"
              checked={autoRenew}
              disabled={togglingAutoRenew}
              onChange={(e) => {
                if (currentSub && currentSub.planType !== 'free') {
                  void handleToggleAutoRenew(e.target.checked);
                } else {
                  setAutoRenewState(e.target.checked);
                }
              }}
            />
            <span>自动续费</span>
          </label>
          <span className="subscribe-autorenew-hint">
            {currentSub && currentSub.planType !== 'free'
              ? autoRenew
                ? '到期自动扣费续订，余额不足时将不续订'
                : '到期后自动降回免费版'
              : autoRenew
                ? '订阅后将自动续费'
                : '订阅后每月需手动续订'}
          </span>
        </div>
        <p className="subscribe-legal">余额直接扣除 · 订阅立即生效</p>
      </div>
    </div>,
    document.body,
  );
}
