"use client";

/**
 * useCrossTabSync - 多 Tab 会话同步 Hook
 *
 * 职责：
 * - 通过 BroadcastChannel('edu-session') 监听跨 Tab 事件
 * - 事件类型：logout / role-change / token-refresh
 * - logout：调用 logout() 跳转登录页
 * - role-change：刷新页面重新获取权限
 * - token-refresh：更新 localStorage 中的 token
 *
 * 维护者：ai13（teacher-portal）
 * 关联：02-architecture-design.md §2.1 会话状态
 */

import { useEffect } from "react";
import { setToken } from "@/lib/auth";

/** 跨 Tab 同步事件类型 */
export type CrossTabEventType = "logout" | "role-change" | "token-refresh";

/** 跨 Tab 事件消息体 */
export interface CrossTabMessage {
  type: CrossTabEventType;
  payload?: {
    token?: string;
  };
  /** 触发时间戳（用于去重/排序） */
  timestamp: number;
}

/** BroadcastChannel 名称 */
const CHANNEL_NAME = "edu-session";

/**
 * 广播跨 Tab 事件给其他 Tab
 *
 * 当前 Tab 主动触发（如点击登出按钮），其他 Tab 通过此 hook 接收并响应。
 */
export function broadcastCrossTabEvent(
  type: CrossTabEventType,
  payload?: CrossTabMessage["payload"],
): void {
  if (typeof window === "undefined") return;
  try {
    const channel = new BroadcastChannel(CHANNEL_NAME);
    const message: CrossTabMessage = {
      type,
      payload,
      timestamp: Date.now(),
    };
    channel.postMessage(message);
    channel.close();
  } catch (err) {
    // BroadcastChannel 不可用时静默降级（单 Tab 模式不受影响）
    console.warn("[useCrossTabSync] broadcast failed", err);
  }
}

/**
 * 订阅跨 Tab 事件并响应
 *
 * 必须在客户端组件中使用（依赖 window / BroadcastChannel）。
 */
export function useCrossTabSync(): void {
  useEffect(() => {
    if (typeof window === "undefined") return;
    if (typeof BroadcastChannel === "undefined") return;

    const channel = new BroadcastChannel(CHANNEL_NAME);

    const handleMessage = (event: MessageEvent<CrossTabMessage>) => {
      const message = event.data;
      if (!message || typeof message !== "object") return;

      switch (message.type) {
        case "logout":
          // 收到登出事件：清空本地状态并跳转登录页
          // 注：不调用 broadcastCrossTabEvent 避免循环
          window.location.href = "/login";
          break;

        case "role-change":
          // 收到角色变更事件：刷新页面以重新获取权限
          window.location.reload();
          break;

        case "token-refresh":
          // 收到 token 刷新事件：更新本地 token
          if (message.payload?.token) {
            setToken(message.payload.token);
          }
          break;
      }
    };

    channel.addEventListener("message", handleMessage);

    return () => {
      channel.removeEventListener("message", handleMessage);
      channel.close();
    };
  }, []);
}
