'use client';
// Login.tsx — 登录（凭证 → 可选 TOTP 二段式）。承袭 ucapp.jsx UCLogin 视觉。
import React, { useEffect, useState } from 'react';
import { Icon, Mark } from './icons';
import { card, input, LangSeg } from './shared';
import { useUI } from '../lib/theme';
import { makeT } from '../lib/i18n';
import { getClient } from '../lib/api/client';
import { ApiError } from '../lib/api/types';
import { bilingual } from '../lib/api/errors';

export default function Login({ onDone }: { onDone: () => void }) {
  const { lang, setLang } = useUI();
  const t = makeT(lang);
  const api = getClient();

  const [email, setEmail] = useState('');
  const [pw, setPw] = useState('');
  const [step, setStep] = useState<'cred' | 'totp'>('cred');
  const [otp, setOtp] = useState('');
  const [pending, setPending] = useState('');
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState('');
  const [lockLeft, setLockLeft] = useState(0);

  const ok = /\S+@\S+\.\S+/.test(email) && pw.length > 0;

  // 锁定倒计时（限流在服务端,前端只做失败提示与倒计时）
  useEffect(() => {
    if (lockLeft <= 0) return;
    const id = setInterval(() => setLockLeft((s) => Math.max(0, s - 1)), 1000);
    return () => clearInterval(id);
  }, [lockLeft]);

  async function submitCred() {
    if (!ok || busy || lockLeft > 0) return;
    setBusy(true);
    setErr('');
    try {
      const r = await api.login(email.trim(), pw);
      if (r.kind === 'totp_required') {
        setPending(r.pendingToken);
        setStep('totp');
      } else {
        onDone();
      }
    } catch (e) {
      setErr(bilingual(e, lang));
      if (e instanceof ApiError && e.code === 'account_locked' && e.retryAfter) setLockLeft(e.retryAfter);
    } finally {
      setBusy(false);
    }
  }

  async function submitOtp() {
    if (otp.length !== 6 || busy) return;
    setBusy(true);
    setErr('');
    try {
      await api.loginTotp(pending, otp);
      onDone();
    } catch (e) {
      setErr(bilingual(e, lang));
    } finally {
      setBusy(false);
    }
  }

  const credDisabled = !ok || busy || lockLeft > 0;

  return (
    <div style={{ minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--bg)', padding: 24 }}>
      <div style={{ ...card, width: 400, maxWidth: '100%', padding: '36px 34px', boxSizing: 'border-box' }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 26 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <Mark size={32} />
            <div>
              <div style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 17, color: 'var(--fg1)', lineHeight: 1 }}>穿山甲</div>
              <div style={{ fontSize: 8.5, fontWeight: 600, letterSpacing: '0.2em', color: 'var(--accent)', marginTop: 3 }}>PANGOLIN</div>
            </div>
          </div>
          <LangSeg lang={lang} setLang={setLang} />
        </div>

        {step === 'cred' ? (
          <>
            <div style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 22, color: 'var(--fg1)' }}>{t('loginTitle')}</div>
            <div style={{ fontSize: 13.5, color: 'var(--fg3)', margin: '6px 0 24px' }}>{t('loginSub')}</div>
            <label style={{ display: 'block', marginBottom: 14 }}>
              <span style={{ display: 'block', fontSize: 12.5, fontWeight: 600, color: 'var(--fg2)', marginBottom: 6 }}>{t('emailLabel')}</span>
              <input style={input} value={email} onChange={(e) => setEmail(e.target.value)} placeholder={t('emailPh')} />
            </label>
            <label style={{ display: 'block' }}>
              <span style={{ display: 'block', fontSize: 12.5, fontWeight: 600, color: 'var(--fg2)', marginBottom: 6 }}>{t('pwLabel')}</span>
              <input
                style={input}
                type="password"
                value={pw}
                onChange={(e) => setPw(e.target.value)}
                placeholder={t('pwPh')}
                onKeyDown={(e) => e.key === 'Enter' && submitCred()}
              />
            </label>
            <div style={{ textAlign: 'right', margin: '10px 0 18px' }}>
              <span style={{ fontSize: 13, color: 'var(--accent)', fontWeight: 600, cursor: 'pointer' }}>{t('forgotPw')}</span>
            </div>
            {err && <ErrorLine text={lockLeft > 0 ? `${err} · ${t('lockedCountdown', { s: lockLeft })}` : err} />}
            <button
              onClick={submitCred}
              disabled={credDisabled}
              style={primaryBtn(!credDisabled)}
            >
              {busy ? t('loading') : t('doLogin')}
            </button>
            <div style={{ textAlign: 'center', fontSize: 12.5, color: 'var(--fg3)', marginTop: 18 }}>{t('noAccount')}</div>
          </>
        ) : (
          <>
            <div style={{ display: 'flex', alignItems: 'center', gap: 9, marginBottom: 6 }}>
              <Icon name="shield-check" size={20} color="var(--accent)" />
              <span style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 20, color: 'var(--fg1)' }}>{t('twoFATitle')}</span>
              <span style={{ fontSize: 10.5, fontWeight: 700, color: 'var(--accent)', background: 'var(--accent-subtle)', border: '1px solid var(--accent-border)', padding: '2px 8px', borderRadius: 999 }}>PRO</span>
            </div>
            <div style={{ fontSize: 13, color: 'var(--fg3)', margin: '4px 0 20px', lineHeight: 1.6 }}>{t('twoFAHint')}</div>
            <input
              value={otp}
              onChange={(e) => setOtp(e.target.value.replace(/\D/g, '').slice(0, 6))}
              onKeyDown={(e) => e.key === 'Enter' && submitOtp()}
              placeholder="······"
              style={{ ...input, fontFamily: 'var(--font-mono)', fontSize: 22, letterSpacing: '0.5em', textAlign: 'center', padding: '14px' }}
            />
            {err && <div style={{ marginTop: 14 }}><ErrorLine text={err} /></div>}
            <button onClick={submitOtp} disabled={otp.length !== 6 || busy} style={{ ...primaryBtn(otp.length === 6 && !busy), marginTop: 16 }}>
              {busy ? t('loading') : t('twoFAConfirm')}
            </button>
            <div onClick={() => { setStep('cred'); setErr(''); setOtp(''); }} style={{ textAlign: 'center', fontSize: 12.5, color: 'var(--fg3)', marginTop: 18, cursor: 'pointer' }}>
              {t('twoFABack')}
            </div>
          </>
        )}
      </div>
    </div>
  );
}

function primaryBtn(enabled: boolean): React.CSSProperties {
  return {
    width: '100%',
    border: 'none',
    borderRadius: 'var(--radius-full)',
    padding: '13px',
    fontFamily: 'var(--font-sans)',
    fontWeight: 700,
    fontSize: 15,
    cursor: enabled ? 'pointer' : 'not-allowed',
    background: 'var(--accent)',
    color: 'var(--fg-on-accent)',
    opacity: enabled ? 1 : 0.45,
  };
}

export function ErrorLine({ text }: { text: string }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 7, color: 'var(--danger)', fontSize: 12.5, fontWeight: 600, marginBottom: 12 }}>
      <Icon name="alert-triangle" size={14} color="var(--danger)" />
      <span>{text}</span>
    </div>
  );
}
