'use client';

import { useEffect, useRef, useState } from 'react';
import { useAuthStore } from '@/stores/auth-store';
import { exchangeCode, refreshToken } from '@/lib/auth-api';

const REFRESH_LEAD_MS = 60_000;

/**
 * 鉴权启动 — 三路兜底:
 *   1. URL 有 ?code= → 优先 exchange 拿新 token(host 刚跳来 / 用户手动重开)
 *   2. localStorage 有 access token 且未过期 → 直接 ready(F5 主路径)
 *   3. localStorage 仅有 refresh token(access 过期或没了)→ silent refresh
 *   4. 全没了 → error,提示回宿主
 *
 * 之后挂"过期前 60s 自动 silent refresh"定时器。
 */
export function useAuthBootstrap() {
  const setTokens = useAuthStore((s) => s.setTokens);
  const clear = useAuthStore((s) => s.clear);
  const expiresAt = useAuthStore((s) => s.expiresAt);
  const refresh = useAuthStore((s) => s.refreshToken);

  const [status, setStatus] = useState<'idle' | 'authenticating' | 'ready' | 'error'>('idle');
  const bootstrapped = useRef(false);

  useEffect(() => {
    if (bootstrapped.current) return;
    bootstrapped.current = true;

    const url = new URL(window.location.href);
    const code = url.searchParams.get('code');

    const run = async () => {
      // ─── 1. URL 有 code → 优先(新人接管,覆盖旧 token)───
      if (code) {
        setStatus('authenticating');
        try {
          const r = await exchangeCode(code);
          setTokens(r);
          url.searchParams.delete('code');
          window.history.replaceState({}, '', url.toString());
          setStatus('ready');
          return;
        } catch {
          // code 失效(过期 / 重放) — 不一定要崩,localStorage 可能还有效
          url.searchParams.delete('code');
          window.history.replaceState({}, '', url.toString());
          // fall through 试 store
        }
      }

      // ─── 2. localStorage 反水合的 access token 还活着 → ready ───
      const s = useAuthStore.getState();
      if (s.accessToken && s.expiresAt && Date.now() < s.expiresAt) {
        setStatus('ready');
        return;
      }

      // ─── 3. 仅 refresh token 还在 → silent refresh ───
      if (s.refreshToken) {
        setStatus('authenticating');
        try {
          const r = await refreshToken(s.refreshToken);
          setTokens(r);
          setStatus('ready');
          return;
        } catch {
          clear();
          setStatus('error');
          return;
        }
      }

      // ─── 4. 全没了 ───
      setStatus('error');
    };

    void run();
  }, [setTokens, clear]);

  // 过期前 60s 自动 silent refresh
  useEffect(() => {
    if (!expiresAt || !refresh) return;
    const delay = Math.max(0, expiresAt - Date.now() - REFRESH_LEAD_MS);
    const timer = setTimeout(async () => {
      try {
        const res = await refreshToken(refresh);
        setTokens(res);
      } catch {
        clear();
      }
    }, delay);
    return () => clearTimeout(timer);
  }, [expiresAt, refresh, setTokens, clear]);

  return { status };
}
