// 登录 / 购买窗口四步流：登录（微信扫码 / 邮箱验证码）→ 时长包 → 支付二维码 → 完成
// 规格见 doc/frontend-design.html 4.2 与 ui_kits/desktop/LoginPurchase.jsx 原型；
// 二维码内容来自后端（qrcode 库本地渲染），轮询自动推进。
import { useEffect, useRef, useState } from 'react';
import { createRoot } from 'react-dom/client';
import QRCode from 'qrcode';
import '@dudu/design/styles.css';
import { Button } from '@dudu/design/components/core/Button';
import { Badge } from '@dudu/design/components/core/Badge';
import { Icon } from '@dudu/design/components/core/Icon';
import { Input } from '@dudu/design/components/forms/Input';
import { logoMark } from '@dudu/design/icons.js';
import { invoke } from '../shared/tauri';
import { setThemePref } from '../shared/theme';
import { usePoll } from '../shared/usePoll';
import { WindowFrame } from '../shared/WindowFrame';

function Center({ children }) {
  return (
    <div style={{
      display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 14,
      padding: '22px 24px 28px', boxSizing: 'border-box',
    }}>{children}</div>
  );
}

function Logo({ size = 40 }) {
  // 安全前提同 Icon 组件：内容为 icons.js 静态常量，无用户输入。
  return (
    <svg
      width={size} height={size} viewBox="0 0 48 48" fill="none" stroke="currentColor"
      strokeWidth="3.5" strokeLinecap="round" aria-hidden="true"
      dangerouslySetInnerHTML={{ __html: logoMark }}
    />
  );
}

// 二维码：qrcode 库画到 canvas（前景/背景取当前主题 token 计算值）。
function QrBox({ value, dimmed }) {
  const ref = useRef(null);
  useEffect(() => {
    if (!value || !ref.current) return;
    const css = getComputedStyle(document.documentElement);
    QRCode.toCanvas(ref.current, value, {
      width: 168,
      margin: 1,
      color: {
        dark: css.getPropertyValue('--text-1').trim() || undefined,
        light: css.getPropertyValue('--surface-card').trim() || undefined,
      },
    }).catch(() => {});
  }, [value]);
  return (
    <div style={{
      width: 180, height: 180, borderRadius: 'var(--radius-md)', border: '1px solid var(--border-1)',
      background: 'var(--surface-card)', display: 'flex', alignItems: 'center', justifyContent: 'center',
      opacity: dimmed ? 0.25 : 1, transition: 'opacity var(--dur-base) var(--ease-out)',
    }}>
      {value
        ? <canvas ref={ref} style={{ borderRadius: 4 }} />
        : <span style={{ fontSize: 'var(--text-xs)', color: 'var(--text-3)' }}>加载中</span>}
    </div>
  );
}

// 登录方式分段切换（与设置页「外观」同控件语言）
function ModeSwitch({ mode, onChange }) {
  return (
    <span style={{ display: 'inline-flex', background: 'var(--surface-2)', borderRadius: 'var(--radius-sm)', padding: 2, gap: 2 }}>
      {[['wechat', '微信扫码'], ['email', '邮箱登录']].map(([val, lab]) => (
        <button key={val} type="button" onClick={() => onChange(val)} style={{
          height: 26, padding: '0 14px', borderRadius: 4, border: 'none', cursor: 'pointer',
          fontSize: 'var(--text-xs)', fontFamily: 'var(--font-sans)',
          background: mode === val ? 'var(--surface-card)' : 'transparent',
          color: mode === val ? 'var(--text-1)' : 'var(--text-2)',
          boxShadow: mode === val ? 'var(--shadow-card)' : 'none',
          transition: 'background var(--dur-fast) var(--ease-out)',
        }}>{lab}</button>
      ))}
    </span>
  );
}

function LoginApp() {
  const [step, setStep] = useState('login'); // login | plans | pay | done
  const [mode, setMode] = useState('wechat'); // wechat | email
  const [qr, setQr] = useState(null);
  const [qrExpired, setQrExpired] = useState(false);
  const [packs, setPacks] = useState([]);
  const [sel, setSel] = useState('pack_500');
  const [order, setOrder] = useState(null);
  const [me, setMe] = useState(null);
  const [qrNonce, setQrNonce] = useState(0); // 递增以触发二维码重建（刷新）

  // 邮箱登录态
  const [email, setEmail] = useState('');
  const [code, setCode] = useState('');
  const [cooldown, setCooldown] = useState(0);
  const [emailErr, setEmailErr] = useState('');
  const [busy, setBusy] = useState(false);

  // 启动应用主题：随系统/已存偏好（深色模式下不再停在浅色）。
  useEffect(() => {
    invoke('get_settings').then((s) => s && setThemePref(s.theme));
  }, []);

  useEffect(() => {
    if (cooldown <= 0) return undefined;
    const t = setTimeout(() => setCooldown(cooldown - 1), 1000);
    return () => clearTimeout(t);
  }, [cooldown]);

  // 扫码登录：创建二维码（进入 login 步或点击刷新时重建；邮箱模式下不建）。
  useEffect(() => {
    if (step !== 'login' || mode !== 'wechat') return undefined;
    let live = true;
    setQrExpired(false);
    setQr(null);
    invoke('login_qr_create').then((r) => { if (live && r) setQr(r); });
    return () => { live = false; };
  }, [step, mode, qrNonce]);

  const enterPlans = async () => {
    const m = await invoke('fetch_me');
    const ps = await invoke('fetch_packs');
    setMe(m);
    setPacks(ps || []);
    setStep('plans');
  };

  // 扫码登录轮询：拿到 confirmed/expired 即停（不再永久 1Hz 打后端）。
  usePoll(async (alive) => {
    const st = await invoke('login_qr_poll', { state: qr.state });
    if (!alive()) return 'stop';
    if (st && st.status === 'confirmed') {
      await enterPlans();
      return 'stop';
    }
    if (st && st.status === 'expired') {
      setQrExpired(true);
      return 'stop';
    }
    return undefined;
  }, 1000, [qr && qr.state], step === 'login' && mode === 'wechat' && !!qr && !qrExpired);

  // 支付轮询：付款成功即停。
  usePoll(async (alive) => {
    const st = await invoke('order_status', { orderId: order.order_id });
    if (!alive()) return 'stop';
    if (st && st.status === 'paid') {
      const m = await invoke('fetch_me');
      if (!alive()) return 'stop';
      setMe(m);
      setStep('done');
      return 'stop';
    }
    return undefined;
  }, 1000, [order && order.order_id], step === 'pay' && !!order);

  const refreshQr = () => setQrNonce((n) => n + 1);

  const sendCode = async () => {
    setEmailErr('');
    const status = await invoke('login_email_code', { email: email.trim() });
    if (status === 204) setCooldown(60);
    else if (status === 429) setEmailErr('发送太频繁，稍后再试');
    else setEmailErr('发送失败，检查邮箱地址');
  };

  const emailLogin = async () => {
    setBusy(true);
    setEmailErr('');
    const r = await invoke('login_email', { email: email.trim(), code });
    setBusy(false);
    if (r && r.token) {
      await enterPlans();
    } else {
      setEmailErr('验证码错误或已过期');
    }
  };

  const pack = packs.find((p) => p.id === sel);

  if (step === 'login') {
    return (
      <WindowFrame title="dudu — 登录">
        <Center>
          <span style={{ color: 'var(--accent)', marginTop: 4 }}><Logo size={40} /></span>
          <div style={{ fontSize: 'var(--text-lg)', fontWeight: 'var(--weight-semibold)', color: 'var(--text-1)' }}>登录 dudu</div>
          <ModeSwitch mode={mode} onChange={setMode} />

          {mode === 'wechat' ? (
            <>
              <QrBox value={qr && qr.qr_url} dimmed={qrExpired} />
              {qrExpired ? (
                <>
                  <div style={{ fontSize: 'var(--text-sm)', color: 'var(--text-2)', textAlign: 'center' }}>二维码已过期，点击刷新重新扫码</div>
                  <Button variant="primary" size="sm" onClick={refreshQr}>刷新二维码</Button>
                </>
              ) : (
                <div style={{ fontSize: 'var(--text-sm)', color: 'var(--text-2)', textAlign: 'center' }}>打开微信扫一扫，确认后自动登录</div>
              )}
            </>
          ) : (
            <div style={{ alignSelf: 'stretch', display: 'flex', flexDirection: 'column', gap: 10, padding: '4px 8px 0' }}>
              <Input
                size="lg" type="email" placeholder="邮箱地址" autoFocus
                value={email} onChange={(e) => setEmail(e.target.value)}
                style={{ width: '100%', boxSizing: 'border-box' }}
              />
              <div style={{ display: 'flex', gap: 8 }}>
                <Input
                  size="lg" inputMode="numeric" maxLength={6} placeholder="6 位验证码"
                  value={code} onChange={(e) => setCode(e.target.value.replace(/\D/g, ''))}
                  style={{ flex: 1, minWidth: 0 }}
                />
                <Button variant="secondary" disabled={cooldown > 0 || !email.includes('@')} onClick={sendCode}>
                  {cooldown > 0 ? `${cooldown}s` : '发送验证码'}
                </Button>
              </div>
              <Button variant="primary" block disabled={code.length !== 6 || busy} onClick={emailLogin}>
                {busy ? '登录中…' : '登录'}
              </Button>
              <div style={{ fontSize: 'var(--text-xs)', color: emailErr ? 'var(--danger)' : 'var(--text-3)', textAlign: 'center' }}>
                {emailErr || '未注册的邮箱将自动创建账号'}
              </div>
            </div>
          )}
        </Center>
      </WindowFrame>
    );
  }
  if (step === 'plans') {
    return (
      <WindowFrame title="dudu — 购买时长">
        <Center>
        <div style={{ alignSelf: 'stretch', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <span style={{ fontSize: 'var(--text-lg)', fontWeight: 'var(--weight-semibold)', color: 'var(--text-1)' }}>购买时长</span>
          {me && <span style={{ display: 'inline-flex', gap: 8, alignItems: 'center', fontSize: 'var(--text-sm)', color: 'var(--text-2)' }}>
            {me.nickname_masked} <Badge tone="blue">{me.account_state === 'ok' ? '余额充足' : '试用中'}</Badge>
          </span>}
        </div>
        <div style={{ alignSelf: 'stretch', display: 'flex', flexDirection: 'column', gap: 10 }}>
          {packs.map((p) => {
            const active = sel === p.id;
            return (
              <button key={p.id} type="button" onClick={() => setSel(p.id)} style={{
                display: 'flex', justifyContent: 'space-between', alignItems: 'center', textAlign: 'left',
                padding: '13px 16px', borderRadius: 'var(--radius-md)', cursor: 'pointer',
                border: active ? '1.5px solid var(--accent)' : '1px solid var(--border-1)',
                background: active ? 'var(--accent-soft)' : 'var(--surface-card)', fontFamily: 'var(--font-sans)',
              }}>
                <span>
                  <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
                    <span style={{ fontSize: 'var(--text-base)', fontWeight: 'var(--weight-medium)', color: 'var(--text-1)' }}>{p.minutes} 分钟</span>
                    {p.tag && <span style={{ fontSize: 10, padding: '1px 7px', borderRadius: 'var(--radius-full)', background: 'var(--warning-soft)', color: 'var(--warning)', fontWeight: 'var(--weight-medium)' }}>{p.tag}</span>}
                  </span>
                  <span style={{ display: 'block', fontSize: 'var(--text-xs)', color: 'var(--text-2)', marginTop: 3 }}>{p.unit_desc}</span>
                </span>
                <span style={{ fontSize: 'var(--text-2xl)', fontWeight: 'var(--weight-bold)', color: active ? 'var(--accent-text)' : 'var(--text-1)' }}>
                  ¥{p.price_cents / 100}
                </span>
              </button>
            );
          })}
        </div>
        <div style={{ alignSelf: 'stretch', fontSize: 'var(--text-xs)', color: 'var(--text-3)' }}>时长不过期 · 每天另有 3 分钟免费试用</div>
        <Button variant="primary" block disabled={!pack} onClick={async () => {
          const o = await invoke('create_order', { packId: sel });
          if (o) { setOrder(o); setStep('pay'); }
        }}>微信支付 ¥{pack ? pack.price_cents / 100 : '—'}</Button>
        </Center>
      </WindowFrame>
    );
  }
  if (step === 'pay') {
    return (
      <WindowFrame title="dudu — 购买时长">
        <Center>
        <div style={{ fontSize: 'var(--text-lg)', fontWeight: 'var(--weight-semibold)', color: 'var(--text-1)' }}>微信扫码支付</div>
        <div style={{ fontSize: 'var(--text-3xl)', fontWeight: 'var(--weight-bold)', color: 'var(--text-1)' }}>
          ¥{pack.price_cents / 100}
          <span style={{ fontSize: 'var(--text-sm)', fontWeight: 'var(--weight-regular)', color: 'var(--text-3)' }}> · {pack.minutes} 分钟时长包</span>
        </div>
        <QrBox value={order && order.code_url} />
        <div style={{ fontSize: 'var(--text-sm)', color: 'var(--text-2)' }}>支付完成后自动开通</div>
        <Button variant="secondary" size="sm" onClick={() => setStep('plans')}>返回</Button>
        </Center>
      </WindowFrame>
    );
  }
  return (
    <WindowFrame title="dudu — 购买时长">
      <Center>
      <span style={{
        width: 56, height: 56, borderRadius: '50%', background: 'var(--positive-soft)', color: 'var(--positive)',
        display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 28, marginTop: 24,
      }}>
        <Icon name="check" size={28} sw={2.5} />
      </span>
      <div style={{ fontSize: 'var(--text-lg)', fontWeight: 'var(--weight-semibold)', color: 'var(--text-1)' }}>已到账 {pack.minutes} 分钟</div>
      <div style={{ fontSize: 'var(--text-sm)', color: 'var(--text-2)', textAlign: 'center' }}>
        时长余额 {me ? Math.floor(me.balance_seconds / 60) : '—'} 分钟 · 不过期 · 现在就按住 ⌘⇧Space 试试
      </div>
      <Button variant="primary" onClick={() => invoke('close_login')}>开始使用</Button>
      </Center>
    </WindowFrame>
  );
}

createRoot(document.getElementById('root')).render(<LoginApp />);
