import React, { useEffect, useState } from 'react';
import { Link, useLocation, useNavigate } from 'react-router-dom';
import * as authApi from '../api/auth.js';
import * as settingsApi from '../api/settings.js';
import { required as captchaRequired } from '../api/captcha.js';
import { showCaptcha } from '../components/CaptchaModal.jsx';
import { getToken, setToken, notifyAuthChange } from '../api/client.js';

/** RainID OIDC 回跳错误码 → 用户可读文案 */
const OIDC_ERROR_TEXT = {
  access_denied: '已在 RainID 拒绝授权，可重新登录',
  consent_required: '请重新完整走 RainID 登录',
  login_required: '请重新完整走 RainID 登录',
  invalid_grant: '登录状态已失效，请重新登录',
  rate_limited: '请求过于频繁，请稍后再试',
  invalid_scope: '配置错误，请联系管理员',
  invalid_request: '配置错误，请联系管理员',
};

/**
 * 登录页（迁移自 login.html）：
 * captcha.required('login') 判断 → 需要则显示"点击进行人机验证"按钮 → showCaptcha('login') 拿 proof；
 * 成功后 setToken + 通知登录态变更 + 跳转来源页或首页。
 * RainID 单点登录：rainid_enabled 时显示「使用 RainID 登录」按钮；回跳（?oidc_ticket / ?oidc_error）
 * 在此页面收尾——一次性过渡码换 token / 错误码映射提示。ROPC 表单逻辑不变（后端已转发）。
 */
export default function Login() {
  const navigate = useNavigate();
  const location = useLocation();
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [showPw, setShowPw] = useState(false);
  const [error, setError] = useState('');
  const [busy, setBusy] = useState(false);
  const [capRequired, setCapRequired] = useState(false);
  const [capDone, setCapDone] = useState(false);
  const [capResult, setCapResult] = useState(null);
  const [rainidEnabled, setRainidEnabled] = useState(false);
  const [oidcBusy, setOidcBusy] = useState(false);

  /** 清理地址栏的 oidc 过渡参数（替换为纯路径，避免残留/刷新重复兑换） */
  const clearOidcParams = () => {
    window.history.replaceState({}, '', window.location.pathname);
  };

  /** RainID 回跳收尾：一次性过渡码换 token → 复用本地登录成功逻辑 */
  const handleOidcTicket = async (ticket) => {
    setBusy(true);
    try {
      const data = await authApi.oidcExchange(ticket);
      setToken(data.token);
      notifyAuthChange();
      clearOidcParams();
      const from = location.state && location.state.from;
      navigate(from || '/');
    } catch (e) {
      clearOidcParams();
      setError(e.message || 'RainID 登录失败，请重试');
      setBusy(false);
    }
  };

  useEffect(() => {
    // 1) RainID 回跳优先处理（一次性码 30s 有效，须先兑换）
    // 注意：OIDC 走整页跳转，此 effect 仅在页面挂载时执行一次；
    // 兑换后 navigate 触发 location 变化时不再重跑（避免覆盖 from 目标）。
    const params = new URLSearchParams(window.location.search);
    const ticket = params.get('oidc_ticket');
    const oidcError = params.get('oidc_error');
    if (ticket) { handleOidcTicket(ticket); return; }
    if (oidcError) {
      setError(OIDC_ERROR_TEXT[oidcError] || 'RainID 登录失败，请重试');
      clearOidcParams();
      return;
    }
    // 2) 已登录直接回首页
    if (getToken()) { navigate('/', { replace: true }); return; }
    // 3) 公开设置：rainid_enabled → 显示 RainID 按钮
    settingsApi.getPublicSettings()
      .then((s) => { if (s.rainid_enabled === '1') setRainidEnabled(true); })
      .catch(() => {});
    // 4) 人机验证需求
    captchaRequired('login')
      .then((r) => { if (r && r.required) setCapRequired(true); })
      .catch(() => {});
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const doCaptcha = async () => {
    const result = await showCaptcha('login');
    if (result) { setCapResult(result); setCapDone(true); }
  };

  /** RainID 整页跳转（loading 防重复点击） */
  const handleRainId = () => {
    if (oidcBusy) return;
    setOidcBusy(true);
    authApi.oidcLoginRedirect();
  };

  const handleLogin = async () => {
    if (!username.trim() || !password) { setError('请输入用户名和密码'); return; }
    if (capRequired && !capDone) { setError('请先点击验证按钮完成验证'); return; }
    setError('');
    setBusy(true);
    try {
      const data = await authApi.login(username.trim(), password, capResult || undefined);
      setToken(data.token);
      notifyAuthChange();
      const from = location.state && location.state.from;
      navigate(from || '/');
    } catch (e) {
      // 401 文案透传（含 RainID 已开启时的 2FA 提示："该账号已开启二次验证，请使用 RainID 登录"）
      setError(e.message || '登录失败');
      setBusy(false);
      // 验证码 proof 为一次性消费：无论密码错还是 proof 已被使用，登录失败后均作废，
      // 重置「已验证」标记允许用户重新完成验证，否则按钮保持 disabled 死锁。
      setCapDone(false);
      setCapResult(null);
    }
  };

  return (
    <div className="login-page" style={{ minHeight: '70vh' }}>
      <div className="card login-card">
        <h1>登录</h1>
        <p className="subtitle">欢迎回到 RainWeb</p>

        <div className="form-group">
          <label>用户名</label>
          <input
            type="text"
            value={username}
            onChange={(e) => setUsername(e.target.value)}
            placeholder="输入用户名"
            autoComplete="username"
            autoFocus
            onKeyDown={(e) => { if (e.key === 'Enter') document.getElementById('loginPw').focus(); }}
          />
        </div>
        <div className="form-group">
          <label>密码</label>
          <div style={{ position: 'relative' }}>
            <input
              id="loginPw"
              type={showPw ? 'text' : 'password'}
              value={password}
              onChange={(e) => setPassword(e.target.value)}
              placeholder="输入密码"
              autoComplete="current-password"
              style={{ width: '100%', paddingRight: 44 }}
              onKeyDown={(e) => { if (e.key === 'Enter') handleLogin(); }}
            />
            <button
              type="button"
              tabIndex="-1"
              style={{ position: 'absolute', right: 8, top: '50%', transform: 'translateY(-50%)', background: 'none', border: 'none', color: 'var(--md-ref-on-surface-variant)', cursor: 'pointer', padding: 4, borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center' }}
              onClick={() => setShowPw((v) => !v)}
            >
              <span className="material-icons" style={{ fontSize: 20 }}>{showPw ? 'visibility' : 'visibility_off'}</span>
            </button>
          </div>
        </div>

        {error && <div style={{ color: 'var(--md-ref-error)', fontSize: 14, marginBottom: 12 }}>{error}</div>}

        {capRequired && (
          <button
            className="btn w-full"
            onClick={doCaptcha}
            disabled={capDone}
            style={{
              display: 'inline-flex',
              marginBottom: 8,
              justifyContent: 'center',
              height: 44,
              ...(capDone
                ? { background: '#e8f5e9', borderColor: '#4caf50', color: '#2e7d32' }
                : { background: 'var(--md-ref-surface-container)', color: 'var(--md-ref-on-surface)', border: '1px solid var(--md-ref-outline-variant)' }),
            }}
          >
            <span className="material-icons" style={{ fontSize: 20 }}>{capDone ? 'check_circle' : 'verified_user'}</span>
            <span>{capDone ? '验证通过' : '点击进行人机验证'}</span>
          </button>
        )}

        {rainidEnabled && (
          <button
            className="btn btn-outline w-full"
            onClick={handleRainId}
            disabled={busy || oidcBusy}
            style={{ display: 'inline-flex', marginBottom: 8, justifyContent: 'center', height: 44, gap: 8, alignItems: 'center' }}
          >
            <span className="material-icons" style={{ fontSize: 20 }}>fingerprint</span>
            <span>{oidcBusy ? '正在跳转 RainID…' : '使用 RainID 登录'}</span>
          </button>
        )}

        <button className="btn btn-filled w-full" onClick={handleLogin} disabled={busy}>
          {busy ? '登录中...' : '登录'}
        </button>

        <div style={{ textAlign: 'center', marginTop: 16 }}>
          <span className="text-muted">没有账户？</span>
          <Link to="/register.html" className="btn-text btn" style={{ fontSize: 14 }}>注册</Link>
        </div>
        <div style={{ textAlign: 'center', marginTop: 8 }}>
          <Link to="/" className="btn-text btn" style={{ fontSize: 14 }}>← 返回主页</Link>
        </div>
      </div>
    </div>
  );
}
