'use client';

import { useEffect, useRef } from 'react';
import { useRouter } from 'next/navigation';
import { useAuth } from '@/lib/auth';
import { applySsoTokensFromHash } from '@/lib/sso-landing';

/**
 * AuthBootstrap：app 启动时执行两件事：
 *   1. v2.4 新增：检测 SSO 回跳 hash（`#accessToken=...&refreshToken=...`），若存在
 *      则写 localStorage + zustand store + 清 hash + 跳转目标页（详见 `lib/sso-landing.ts`）。
 *   2. 拉一次 /users/me 刷新权限/角色到 zustand。
 *
 * 设计动机
 * --------
 * 后端 OIDC callback 成功时 302 到 `${sso_redirect}#accessToken=<jwt>&refreshToken=<jwt>`，
 * sso_redirect 可以是任何业务路径（用户登录前所在页，默认 /overview）。如果只在 /sso/landing
 * 路由处理 hash，绕过中间页直接 302 到业务页时 token 会"卡"在 hash 不被消费。
 * 因此把 hash 处理放在 root Providers 内的 AuthBootstrap，让任何首次加载页面都能消费。
 *
 * issue #159 之前 useAuth 走 AuthContext useEffect 完成；现在 useAuth 合并到 zustand
 * 后，没有 Provider 钩子可挂 useEffect，于是用独立 client-only 组件占位。
 *
 * 渲染 null，无可见 UI；放在 <Providers> 内部，确保路由切换时不重复触发
 * （Next.js app router 不会卸载 Providers）。
 */
export function AuthBootstrap() {
  const reload = useAuth((s) => s.reload);
  const router = useRouter();
  const handledRef = useRef(false);

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

    // Step 1: SSO hash 处理（v2.4）
    const ssoResult = applySsoTokensFromHash();

    if (ssoResult.kind === 'error') {
      // hash 含 accessToken= 但解析失败 → 跳登录页带错误码
      router.replace(`/login?ssoError=${ssoResult.errorCode}`);
      return;
    }

    // Step 2: 拉 /users/me 刷新权限（SSO ok 路径也走这条，把 user 对象填上）
    // fire-and-forget；reload 内部对 401 / 缺 token 已 graceful 处理
    reload().catch(() => undefined);

    // Step 3: SSO ok 路径若有显式 target，主动跳转一次。
    //    多数情况下 ssoResult.target === 当前 location（callback 已 302 到这），
    //    跳转是 noop 但保险起见做一次 router.replace，确保 history 干净。
    if (ssoResult.kind === 'ok' && typeof window !== 'undefined') {
      const current = `${window.location.pathname}${window.location.search}`;
      if (ssoResult.target !== current) {
        router.replace(ssoResult.target);
      }
    }
  }, [reload, router]);

  return null;
}
