// ===== page-order.jsx =====
const { useState: useSO, useEffect: useEO, useRef: useRO } = React;

// 后端 status → 前端 phase
const STATUS_TO_PHASE = {
  pending: 'pending',
  uploaded: 'uploaded',
  processing: 'processing',
  done: 'done',
  refunded: 'refunded',
  expired: 'expired',
  llm_failed: 'failed',
};

function OrderPage({ navigate, params }) {
  const orderId = params?.id || '';
  const urlToken = params?.token || '';

  // URL 自带 token 时立即落盘到 localStorage，避免后续丢失（关 tab/换设备等）
  if (orderId && urlToken) {
    window.API.saveToken(orderId, urlToken);
  }

  const [order, setOrder]       = useSO(null);
  const [loading, setLoading]   = useSO(true);
  const [error, setError]       = useSO(null);
  const [secondsLeft, setSecondsLeft] = useSO(0);
  const [procProgress, setProcProgress] = useSO(0);
  const phase = order ? (STATUS_TO_PHASE[order.status] || 'pending') : 'pending';
  const pollingRef = useRO(null);

  // 初次加载 + polling
  const fetchOrder = async () => {
    try {
      const data = await window.API.getOrder(orderId);
      setOrder(data);
      setError(null);
    } catch (err) {
      console.error('fetch order failed', err);
      setError(err);
    } finally {
      setLoading(false);
    }
  };

  useEO(() => {
    if (!orderId) {
      setError({ message: '订单号缺失' });
      setLoading(false);
      return;
    }
    fetchOrder();
    // 每 5s polling 一次
    pollingRef.current = setInterval(fetchOrder, 5000);
    return () => clearInterval(pollingRef.current);
  }, [orderId]);

  // 倒计时：基于 expires_at
  useEO(() => {
    if (!order || phase !== 'pending') return;
    const tick = () => {
      const expires = new Date(order.expires_at + (order.expires_at.endsWith('Z') ? '' : 'Z')).getTime();
      const remaining = Math.max(0, Math.floor((expires - Date.now()) / 1000));
      setSecondsLeft(remaining);
    };
    tick();
    const id = setInterval(tick, 1000);
    return () => clearInterval(id);
  }, [order, phase]);

  // processing 阶段：合成进度条（仅视觉）
  useEO(() => {
    if (phase !== 'processing') { setProcProgress(0); return; }
    let p = procProgress;
    const id = setInterval(() => {
      p = Math.min(95, p + 2 + Math.random() * 3);
      setProcProgress(p);
    }, 400);
    return () => clearInterval(id);
  }, [phase]);

  // 完成时自动跳报告页
  useEO(() => {
    if (phase !== 'done' || !order) return;
    setProcProgress(100);
    const t = setTimeout(() => {
      clearInterval(pollingRef.current);
      // 把 token 一并带进报告页 URL（来源：URL query 或本地存储）
      const t2 = urlToken || window.API.getToken(order.order_id);
      navigate('report', { id: order.order_id, token: t2 });
    }, 1200);
    return () => clearTimeout(t);
  }, [phase, order, navigate, urlToken]);

  if (loading) {
    return (
      <div className="min-h-screen bg-ink-50 pt-12 pb-24">
        <div className="max-w-[1100px] mx-auto px-6 lg:px-8">
          <div className="flex items-center justify-center h-[60vh]">
            <I.Spinner size={28} className="text-brand-600" />
            <span className="ml-3 text-ink-500">加载订单中...</span>
          </div>
        </div>
      </div>
    );
  }

  if (error || !order) {
    return (
      <div className="min-h-screen bg-ink-50 pt-12 pb-24">
        <div className="max-w-[640px] mx-auto px-6 lg:px-8">
          <Card className="p-8 text-center">
            <div className="w-14 h-14 mx-auto rounded-full bg-bad-50 text-bad-600 flex items-center justify-center"><I.AlertTriangle size={26} /></div>
            <h2 className="mt-4 text-[20px] font-bold text-navy-900">订单获取失败</h2>
            <p className="mt-2 text-[13.5px] text-ink-500">{error?.message || '订单可能已过期或不存在'}</p>
            <Button kind="dark" size="lg" onClick={() => navigate('upload')} className="mt-6">重新上传论文</Button>
          </Card>
        </div>
      </div>
    );
  }

  const amount = order.amount.toFixed(2);
  const orderIdDisplay = `#${order.order_id}`;
  const fmtTime = (s) => `${String(Math.floor(s/60)).padStart(2,'0')}:${String(s%60).padStart(2,'0')}`;

  return (
    <div className="min-h-screen bg-ink-50 pt-12 pb-24">
      <div className="max-w-[1100px] mx-auto px-6 lg:px-8">
        <div className="flex items-center gap-2 text-[12.5px] text-ink-500 mb-6">
          <a onClick={() => navigate('home')}    className="hover:text-navy-900 cursor-pointer">首页</a>
          <I.Chevron size={12} />
          <a onClick={() => navigate('upload')} className="hover:text-navy-900 cursor-pointer">上传论文</a>
          <I.Chevron size={12} />
          <span className="text-navy-900">订单支付</span>
        </div>

        <div className="grid lg:grid-cols-12 gap-6">
          <div className="lg:col-span-7">
            <Card className="p-7">
              <div className="flex items-start justify-between">
                <div>
                  <div className="text-[11px] tracking-[0.18em] uppercase text-ink-500 font-semibold">订单信息</div>
                  <div className="mt-1 text-[20px] font-semibold text-navy-900">AIGC 智能分析</div>
                </div>
                <Badge tone="ink" className="mono">{orderIdDisplay}</Badge>
              </div>

              <dl className="mt-7 divide-y divide-ink-200">
                <KV label="检测项">AIGC 智能分析 · 5 维度统计模型</KV>
                <KV label="论文字数">{order.word_count.toLocaleString()} 字</KV>
                <KV label="检测方案">{order.plan === 'premium' ? '完整版' : '标准版'}</KV>
                <KV label="文件名">{order.file_name}</KV>
                <KV label="预计耗时">≤ 30 秒</KV>
              </dl>

              <div className="mt-6 p-5 rounded-xl bg-navy-950 text-white">
                <div className="text-[11px] tracking-[0.18em] uppercase text-brand-500 font-semibold">应付金额</div>
                <div className="mt-2 flex items-baseline gap-1">
                  <span className="text-[18px] text-ink-300">¥</span>
                  <span className="num text-[48px] font-bold leading-none tracking-tight">{amount}</span>
                </div>
                <div className="mt-3 flex items-start gap-2 text-[12px] text-ink-300">
                  <I.AlertCircle size={13} className="text-warn-500 mt-0.5 flex-shrink-0" />
                  <span><strong className="text-white">请按精确金额支付</strong>，便于系统自动对账。金额错误将无法自动识别订单。</span>
                </div>
              </div>

              <div className="mt-7">
                <div className="text-[11px] tracking-[0.18em] uppercase text-ink-500 font-semibold mb-4">订单状态</div>
                <StatusTimeline phase={phase} secondsLeft={secondsLeft} fmtTime={fmtTime} procProgress={procProgress} />
              </div>

              {/* 保存访问凭证 */}
              <AccessCredsCard orderId={order.order_id} />

              {/* 失败/退款/过期 状态 */}
              {(phase === 'failed' || phase === 'refunded' || phase === 'expired') && (
                <div className="mt-7 p-4 rounded-xl bg-bad-50 ring-1 ring-bad-100">
                  <div className="flex items-start gap-3">
                    <I.AlertTriangle size={18} className="text-bad-600 mt-0.5" />
                    <div className="flex-1">
                      <div className="text-[13.5px] font-semibold text-bad-600">
                        {phase === 'failed' && '分析失败'}
                        {phase === 'refunded' && '订单已退款'}
                        {phase === 'expired' && '订单已过期'}
                      </div>
                      <div className="text-[12px] text-ink-700 mt-1">
                        {phase === 'failed' && '检测引擎临时故障，已通知运维人工重试。如需立刻处理请联系 support@mojian.ai'}
                        {phase === 'refunded' && '订单金额已退回原支付账户，3 个工作日内到账。'}
                        {phase === 'expired' && '订单 30 分钟未支付，已自动关闭。可重新上传论文。'}
                      </div>
                    </div>
                  </div>
                </div>
              )}
            </Card>
          </div>

          <div className="lg:col-span-5">
            <div className="mb-4 flex items-center gap-2 px-4 py-3 rounded-xl bg-navy-950 text-white">
              <span className="relative flex h-2 w-2">
                <span className="absolute inset-0 rounded-full bg-bad-500 opacity-70 animate-ping" />
                <span className="relative inline-flex rounded-full h-2 w-2 bg-bad-500" />
              </span>
              <div className="text-[12.5px]">
                🔥 本周已为 <span className="num font-semibold"><AnimatedNumber value={47} /></span> 位同学完成检测 · 你不是一个人在熬夜
              </div>
            </div>
            <PaymentPanel amount={amount} suffix={order.amount_suffix} phase={phase} secondsLeft={secondsLeft} fmtTime={fmtTime} />

            <div className="mt-4 p-4 rounded-xl bg-white ring-1 ring-ink-200">
              <div className="flex items-center gap-2 text-[12.5px] text-navy-900 font-semibold">
                <I.ShieldCheck size={14} className="text-ok-600" /> 资金与隐私
              </div>
              <ul className="mt-3 space-y-2 text-[12px] text-ink-500 leading-relaxed">
                <li>· 我们仅记录付款金额与订单号匹配，不获取你的支付宝账户信息</li>
                <li>· 30 分钟未支付订单自动关闭，论文文件 24 小时内同步删除</li>
                <li>· 异常订单可通过 support@mojian.ai 申请人工核对</li>
              </ul>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

function AccessCredsCard({ orderId }) {
  const [copied, setCopied] = useSO('');
  const token = window.API.getToken(orderId);
  const url = `${window.location.origin}/#/order/${orderId}`;
  if (!token) return null;

  const copy = (text, key) => {
    navigator.clipboard.writeText(text).then(() => {
      setCopied(key);
      setTimeout(() => setCopied(''), 1800);
    }).catch(() => {});
  };

  return (
    <div className="mt-7 p-4 rounded-xl bg-warn-50 ring-1 ring-warn-100">
      <div className="flex items-start gap-3">
        <I.Lock size={16} className="text-warn-600 mt-0.5 flex-shrink-0" />
        <div className="flex-1 min-w-0">
          <div className="text-[13px] font-semibold text-warn-600">⚠ 保存你的访问凭证</div>
          <p className="mt-1 text-[12px] text-ink-700 leading-relaxed">
            如果你换设备或清缓存，需要凭这组凭证（订单号 + 访问令牌）才能找回报告。建议立刻复制下来。
          </p>

          <div className="mt-3 space-y-2">
            <div>
              <div className="flex items-center justify-between gap-2 mb-1">
                <span className="text-[10.5px] uppercase tracking-wider text-ink-500 font-semibold">订单号</span>
                <button onClick={() => copy(orderId, 'id')} className="text-[11px] text-brand-600 hover:text-brand-700">
                  {copied === 'id' ? '已复制 ✓' : '复制'}
                </button>
              </div>
              <div className="mono text-[12px] text-navy-900 bg-white p-2 rounded ring-1 ring-ink-200 break-all">
                {orderId}
              </div>
            </div>

            <div>
              <div className="flex items-center justify-between gap-2 mb-1">
                <span className="text-[10.5px] uppercase tracking-wider text-ink-500 font-semibold">访问令牌</span>
                <button onClick={() => copy(token, 'tok')} className="text-[11px] text-brand-600 hover:text-brand-700">
                  {copied === 'tok' ? '已复制 ✓' : '复制'}
                </button>
              </div>
              <div className="mono text-[11px] text-navy-900 bg-white p-2 rounded ring-1 ring-ink-200 break-all">
                {token}
              </div>
            </div>

            <div>
              <div className="flex items-center justify-between gap-2 mb-1">
                <span className="text-[10.5px] uppercase tracking-wider text-ink-500 font-semibold">完整访问链接</span>
                <button onClick={() => copy(url, 'url')} className="text-[11px] text-brand-600 hover:text-brand-700">
                  {copied === 'url' ? '已复制 ✓' : '复制链接'}
                </button>
              </div>
              <div className="mono text-[11px] text-ink-700 bg-white p-2 rounded ring-1 ring-ink-200 break-all">
                {url}
              </div>
            </div>
          </div>

          <p className="mt-3 text-[11px] text-ink-500">
            找回入口：<a className="text-brand-600 hover:underline cursor-pointer" onClick={() => window.location.hash = '#/lookup'}>底部"找回订单"</a>
          </p>
        </div>
      </div>
    </div>
  );
}

function KV({ label, children }) {
  return (
    <div className="py-3 flex items-baseline justify-between gap-4">
      <dt className="text-[13px] text-ink-500">{label}</dt>
      <dd className="text-[14px] text-navy-900 font-medium num text-right">{children}</dd>
    </div>
  );
}

function StatusTimeline({ phase, secondsLeft, fmtTime, procProgress }) {
  const steps = [
    { key: 'pending',    label: '等待支付',          desc: '请在右侧完成支付宝扫码付款' },
    { key: 'uploaded',   label: '已支付，等待确认',   desc: '系统正在比对支付金额与订单' },
    { key: 'processing', label: '报告生成中',        desc: 'LLM 多维度分析中，请稍候' },
    { key: 'done',       label: '完成',              desc: '报告已生成，即将跳转' },
  ];
  const order = ['pending', 'uploaded', 'processing', 'done'];
  const currentIdx = order.indexOf(phase);

  return (
    <ol className="relative space-y-5">
      <span className="absolute left-[11px] top-2 bottom-2 w-px bg-ink-200" />
      {steps.map((s, i) => {
        const done = i < currentIdx;
        const active = i === currentIdx;
        return (
          <li key={s.key} className="relative pl-9 fade-up">
            <span className={`absolute left-0 top-0.5 w-[22px] h-[22px] rounded-full flex items-center justify-center ring-4 ring-white
              ${done ? 'bg-ok-500 text-white' : active ? 'bg-brand-600 text-white' : 'bg-ink-200 text-ink-400'}`}>
              {done
                ? <I.Check size={12} />
                : active
                  ? <span className="w-2 h-2 rounded-full bg-white pulse-dot" />
                  : <span className="w-2 h-2 rounded-full bg-white" />}
            </span>
            <div className="flex items-center justify-between gap-4">
              <div className={`text-[14px] font-semibold ${active ? 'text-navy-900' : done ? 'text-ink-700' : 'text-ink-400'}`}>{s.label}</div>
              {active && s.key === 'pending' && (
                <div className="text-[12px] num text-ink-500">剩余 <span className="text-warn-600 font-semibold">{fmtTime(secondsLeft)}</span></div>
              )}
              {active && s.key === 'processing' && (
                <div className="num text-[12px] text-brand-600 font-semibold">{Math.round(procProgress)}%</div>
              )}
              {done && <Badge tone="ok"><I.Check size={10} /> 完成</Badge>}
            </div>
            <div className={`text-[12.5px] mt-0.5 ${active ? 'text-ink-500' : 'text-ink-400'}`}>{s.desc}</div>
            {active && s.key === 'processing' && (
              <div className="mt-3 h-1.5 rounded-full bg-ink-100 overflow-hidden">
                <div className="h-full bg-brand-600 rounded-full" style={{ width: `${procProgress}%` }} />
              </div>
            )}
          </li>
        );
      })}
    </ol>
  );
}

function FakeQR({ size = 220 }) {
  const N = 25;
  const cells = [];
  let seed = 0x4d6f6a;
  const rand = () => { seed = (seed * 9301 + 49297) % 233280; return seed / 233280; };
  for (let r = 0; r < N; r++) for (let c = 0; c < N; c++) {
    const inFinder = (r < 7 && c < 7) || (r < 7 && c >= N - 7) || (r >= N - 7 && c < 7);
    if (inFinder) {
      const lr = r < 7 ? r : r - (N - 7);
      const lc = c < 7 ? c : c - (N - 7);
      const onRing = lr === 0 || lr === 6 || lc === 0 || lc === 6;
      const onCore = lr >= 2 && lr <= 4 && lc >= 2 && lc <= 4;
      cells.push(onRing || onCore);
    } else if (r === 6 || c === 6) {
      cells.push((r + c) % 2 === 0);
    } else {
      cells.push(rand() > 0.52);
    }
  }
  return (
    <svg width={size} height={size} viewBox={`0 0 ${N} ${N}`} className="block">
      <rect width={N} height={N} fill="white" />
      {cells.map((on, i) => on ? (
        <rect key={i} x={i % N} y={Math.floor(i / N)} width="1" height="1" fill="#0F172A" />
      ) : null)}
      <rect x={10} y={10} width={5} height={5} fill="white" />
      <rect x={10.5} y={10.5} width={4} height={4} rx="0.6" fill="#1677FF" />
      <text x={12.5} y={13.4} fontSize="2.5" fill="white" textAnchor="middle" fontWeight="700" fontFamily="Inter">支</text>
    </svg>
  );
}

// 真实支付宝码：若 /qrcode.png 存在则显示，否则降级为 FakeQR。
function PaymentQR({ size = 220 }) {
  const [hasReal, setHasReal] = useSO(true);
  if (!hasReal) return <FakeQR size={size} />;
  return (
    <img
      src="/qrcode.png"
      alt="支付宝收款码"
      width={size}
      height={size}
      onError={() => setHasReal(false)}
      className="block rounded-md"
      style={{ width: size, height: size, objectFit: 'contain' }}
    />
  );
}

function PaymentPanel({ amount, suffix, phase, secondsLeft, fmtTime }) {
  const paid = phase !== 'pending' && phase !== 'expired';
  const suffixStr = String(suffix).padStart(2, '0');
  return (
    <Card className="p-6 sm:p-7 relative overflow-hidden">
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-2">
          <div className="w-8 h-8 rounded-md bg-[#1677FF] text-white flex items-center justify-center font-bold text-[13px]">支</div>
          <div>
            <div className="text-[14px] font-semibold text-navy-900">支付宝扫码支付</div>
            <div className="text-[11.5px] text-ink-500">打开支付宝 · 扫一扫</div>
          </div>
        </div>
        <Badge tone={paid ? 'ok' : 'warn'}>
          <span className={`w-1.5 h-1.5 rounded-full ${paid ? 'bg-ok-500' : 'bg-warn-500'} pulse-dot`} />
          {paid ? '已收到支付' : '等待付款'}
        </Badge>
      </div>

      <div className="relative mt-6 mx-auto w-fit p-5 bg-white ring-1 ring-ink-200 rounded-2xl">
        <div className="relative">
          <PaymentQR size={224} />
          {paid && (
            <div className="absolute inset-0 bg-white/85 backdrop-blur-sm rounded-md flex flex-col items-center justify-center fade-up">
              <div className="w-14 h-14 rounded-full bg-ok-500 text-white flex items-center justify-center"><I.Check size={28} /></div>
              <div className="mt-3 text-[14px] font-semibold text-navy-900">支付成功</div>
            </div>
          )}
        </div>
        <CornerMarks />
      </div>

      <div className="mt-5 text-center">
        <div className="text-[12px] text-ink-500">请扫码支付</div>
        <div className="mt-1 flex items-baseline justify-center gap-1">
          <span className="text-[16px] text-ink-500">¥</span>
          <span className="num text-[40px] font-bold text-navy-900 leading-none">{amount}</span>
        </div>
        <div className="mt-2 text-[12px] text-bad-600 font-medium">⚠ 金额必须精确为 ¥{amount}，请勿修改默认金额</div>
      </div>

      {phase === 'pending' && (
        <div className="mt-5 p-3 rounded-lg bg-warn-50 ring-1 ring-warn-100">
          <div className="flex items-center justify-between gap-2">
            <div className="text-[12px] text-warn-600 leading-snug">金额尾数 <span className="mono font-semibold">.{suffixStr}</span> 是你的专属订单标识</div>
            <div className="num text-[14px] font-semibold text-warn-600 flex-shrink-0">{fmtTime(secondsLeft)}</div>
          </div>
          <div className="mt-1 text-[11px] text-ink-500">超时后释放给他人 · 请勿关闭页面</div>
        </div>
      )}
    </Card>
  );
}

function CornerMarks() {
  return (
    <>
      <div className="absolute top-0 left-0 w-5 h-5"><div className="absolute top-0 left-0 w-3 h-0.5 bg-brand-600" /><div className="absolute top-0 left-0 w-0.5 h-3 bg-brand-600" /></div>
      <div className="absolute top-0 right-0 w-5 h-5"><div className="absolute top-0 right-0 w-3 h-0.5 bg-brand-600" /><div className="absolute top-0 right-0 w-0.5 h-3 bg-brand-600" /></div>
      <div className="absolute bottom-0 left-0 w-5 h-5"><div className="absolute bottom-0 left-0 w-3 h-0.5 bg-brand-600" /><div className="absolute bottom-0 left-0 w-0.5 h-3 bg-brand-600" /></div>
      <div className="absolute bottom-0 right-0 w-5 h-5"><div className="absolute bottom-0 right-0 w-3 h-0.5 bg-brand-600" /><div className="absolute bottom-0 right-0 w-0.5 h-3 bg-brand-600" /></div>
    </>
  );
}

window.OrderPage = OrderPage;
