/**
 * 多标签页检测 Hook（ai14）
 *
 * 使用 BroadcastChannel 检测同一考试是否已在其他标签页打开
 * 降级方案：Safari < 15.4 不支持时使用 localStorage 事件
 */

import { useState, useEffect, useCallback } from "react";

const CHANNEL_NAME = "student-exam-guard";

type GuardMessage =
  | { type: "tab-opened"; examId: string; tabId: string; ts: number }
  | { type: "tab-exists"; examId: string; tabId: string; ts: number }
  | { type: "tab-closed"; examId: string; tabId: string; ts: number };

export interface UseMultiTabGuardReturn {
  /** 是否检测到重复标签页 */
  isDuplicate: boolean;
  /** 关闭警告（用户确认后） */
  dismissWarning: () => void;
}

function generateTabId(): string {
  return `tab-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
}

export function useMultiTabGuard(examId: string): UseMultiTabGuardReturn {
  const [isDuplicate, setIsDuplicate] = useState(false);
  const [dismissed, setDismissed] = useState(false);

  useEffect(() => {
    const tabId = generateTabId();

    // 降级方案：不支持 BroadcastChannel 时使用 localStorage
    if (typeof BroadcastChannel === "undefined") {
      const storageKey = `exam-active-${examId}`;
      window.localStorage.setItem(
        storageKey,
        JSON.stringify({ tabId, ts: Date.now() }),
      );
      const onStorage = (e: StorageEvent): void => {
        if (e.key === storageKey && e.newValue) {
          try {
            const other = JSON.parse(e.newValue) as { tabId: string };
            if (other.tabId !== tabId && !dismissed) {
              setIsDuplicate(true);
            }
          } catch {
            // 解析失败忽略
          }
        }
      };
      window.addEventListener("storage", onStorage);
      return () => {
        window.localStorage.removeItem(storageKey);
        window.removeEventListener("storage", onStorage);
      };
    }

    // 主方案：BroadcastChannel
    const channel = new BroadcastChannel(CHANNEL_NAME);
    const msg: GuardMessage = {
      type: "tab-opened",
      examId,
      tabId,
      ts: Date.now(),
    };
    channel.postMessage(msg);

    const onMessage = (event: MessageEvent): void => {
      const data = event.data as GuardMessage;
      if (!data || data.tabId === tabId || data.examId !== examId) return;

      if (
        (data.type === "tab-opened" || data.type === "tab-exists") &&
        !dismissed
      ) {
        setIsDuplicate(true);
        // 回应：我也在作答
        channel.postMessage({
          type: "tab-exists",
          examId,
          tabId,
          ts: Date.now(),
        } satisfies GuardMessage);
      }
    };
    channel.addEventListener("message", onMessage);

    return () => {
      channel.postMessage({
        type: "tab-closed",
        examId,
        tabId,
        ts: Date.now(),
      } satisfies GuardMessage);
      channel.removeEventListener("message", onMessage);
      channel.close();
    };
  }, [examId, dismissed]);

  const dismissWarning = useCallback(() => {
    setDismissed(true);
    setIsDuplicate(false);
  }, []);

  return { isDuplicate, dismissWarning };
}
