"use client"

import { useEffect, useRef, useState, useCallback } from "react"
import { AlertTriangle, X } from "lucide-react"

import { Button } from "@/shared/components/ui/button"
import { recordProctoringEventAction } from "../actions"
import type { ProctoringEventType } from "../types"
import { PROCTORING_EVENT_LABELS } from "../types"

const IDLE_TIMEOUT_MS = 5 * 60 * 1000 // 5 分钟
const REPORT_THROTTLE_MS = 1500 // 同类事件最小上报间隔
const ACTIVITY_THROTTLE_MS = 1000 // 用户活动事件节流间隔（mousemove 等高频事件）

type AntiCheatMonitorProps = {
  examId: string
  submissionId: string
  /** 是否启用防作弊监控（通常 proctored 模式才启用） */
  enabled: boolean
  /** 是否强制全屏（proctored 模式下为 true） */
  forceFullscreen?: boolean
}

type WarningState = {
  visible: boolean
  message: string
  eventType?: ProctoringEventType
}

/**
 * 学生端防作弊监控组件
 * 监听各类异常行为并上报到服务端
 */
export function AntiCheatMonitor({
  examId,
  submissionId,
  enabled,
  forceFullscreen = false,
}: AntiCheatMonitorProps) {
  const [warning, setWarning] = useState<WarningState>({ visible: false, message: "" })
  const [isFullscreen, setIsFullscreen] = useState(false)
  const lastReportRef = useRef<Map<ProctoringEventType, number>>(new Map())
  const idleTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)

  const reportEvent = useCallback(
    async (eventType: ProctoringEventType, detail?: string) => {
      // 节流：同类事件在短时间内只上报一次
      const now = Date.now()
      const last = lastReportRef.current.get(eventType) ?? 0
      if (now - last < REPORT_THROTTLE_MS) return
      lastReportRef.current.set(eventType, now)

      try {
        const formData = new FormData()
        formData.set("submissionId", submissionId)
        formData.set("examId", examId)
        formData.set("eventType", eventType)
        if (detail) formData.set("eventDetail", detail)
        await recordProctoringEventAction(null, formData)
      } catch (error) {
        console.error("Failed to report proctoring event:", error)
      }
    },
    [examId, submissionId],
  )

  const showWarning = useCallback(
    (eventType: ProctoringEventType, message?: string) => {
      const text = message ?? PROCTORING_EVENT_LABELS[eventType]
      setWarning({ visible: true, message: text, eventType })
      reportEvent(eventType, message)
    },
    [reportEvent],
  )

  const resetIdleTimer = useCallback(() => {
    if (idleTimerRef.current) clearTimeout(idleTimerRef.current)
    idleTimerRef.current = setTimeout(() => {
      showWarning("idle_timeout", "空闲超时（5 分钟无操作）")
    }, IDLE_TIMEOUT_MS)
  }, [showWarning])

  // 进入/退出全屏
  const enterFullscreen = useCallback(() => {
    const elem = document.documentElement
    if (elem.requestFullscreen) {
      elem.requestFullscreen().catch(() => {
        // 全屏请求失败（如用户未交互），忽略
      })
    }
  }, [])

  const exitFullscreen = useCallback(() => {
    if (document.fullscreenElement) {
      document.exitFullscreen().catch(() => {})
    }
  }, [])

  // 主副作用：注册事件监听
  useEffect(() => {
    if (!enabled) return

    const handleVisibilityChange = () => {
      if (document.hidden) {
        showWarning("tab_switch", "切换到其他标签页或最小化窗口")
      }
    }

    const handleBlur = () => {
      showWarning("window_blur", "窗口失去焦点")
    }

    const handleCopy = (e: ClipboardEvent) => {
      e.preventDefault()
      showWarning("copy_attempt", "尝试复制内容")
    }

    const handlePaste = (e: ClipboardEvent) => {
      e.preventDefault()
      showWarning("paste_attempt", "尝试粘贴内容")
    }

    const handleContextMenu = (e: MouseEvent) => {
      e.preventDefault()
      showWarning("right_click", "尝试右键点击")
    }

    const handleKeyDown = (e: KeyboardEvent) => {
      // F12 / Ctrl+Shift+I / Ctrl+Shift+J / Ctrl+U
      const isDevtools =
        e.key === "F12" ||
        (e.ctrlKey && e.shiftKey && (e.key === "I" || e.key === "i" || e.key === "J" || e.key === "j")) ||
        (e.ctrlKey && (e.key === "U" || e.key === "u"))
      if (isDevtools) {
        e.preventDefault()
        showWarning("devtools_open", "尝试打开开发者工具")
      }
    }

    const handleFullscreenChange = () => {
      const fs = !!document.fullscreenElement
      setIsFullscreen(fs)
      if (!fs && forceFullscreen) {
        showWarning("fullscreen_exit", "退出了全屏模式")
      }
    }

    let lastActivityAt = 0
    const handleUserActivity = () => {
      // 节流：mousemove 等高频事件每秒最多触发一次 resetIdleTimer
      const now = Date.now()
      if (now - lastActivityAt < ACTIVITY_THROTTLE_MS) return
      lastActivityAt = now
      resetIdleTimer()
    }

    document.addEventListener("visibilitychange", handleVisibilityChange)
    window.addEventListener("blur", handleBlur)
    document.addEventListener("copy", handleCopy)
    document.addEventListener("paste", handlePaste)
    document.addEventListener("contextmenu", handleContextMenu)
    document.addEventListener("keydown", handleKeyDown)
    document.addEventListener("fullscreenchange", handleFullscreenChange)
    document.addEventListener("mousemove", handleUserActivity)
    document.addEventListener("keydown", handleUserActivity)
    document.addEventListener("click", handleUserActivity)

    resetIdleTimer()

    if (forceFullscreen) {
      enterFullscreen()
    }

    return () => {
      document.removeEventListener("visibilitychange", handleVisibilityChange)
      window.removeEventListener("blur", handleBlur)
      document.removeEventListener("copy", handleCopy)
      document.removeEventListener("paste", handlePaste)
      document.removeEventListener("contextmenu", handleContextMenu)
      document.removeEventListener("keydown", handleKeyDown)
      document.removeEventListener("fullscreenchange", handleFullscreenChange)
      document.removeEventListener("mousemove", handleUserActivity)
      document.removeEventListener("keydown", handleUserActivity)
      document.removeEventListener("click", handleUserActivity)
      if (idleTimerRef.current) clearTimeout(idleTimerRef.current)
      if (forceFullscreen) exitFullscreen()
    }
  }, [enabled, forceFullscreen, showWarning, resetIdleTimer, enterFullscreen, exitFullscreen])

  if (!enabled) return null

  return (
    <>
      {forceFullscreen && !isFullscreen && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-background/95 p-6">
          <div className="max-w-md space-y-4 text-center">
            <AlertTriangle className="mx-auto h-12 w-12 text-destructive" />
            <h2 className="text-xl font-semibold">请进入全屏模式继续考试</h2>
            <p className="text-sm text-muted-foreground">
              监考模式要求在全屏下进行考试。点击下方按钮重新进入全屏。
            </p>
            <Button onClick={enterFullscreen}>进入全屏</Button>
          </div>
        </div>
      )}

      {warning.visible && (
        <div className="fixed bottom-4 right-4 z-50 w-80 rounded-lg border border-destructive/50 bg-destructive/10 p-4 shadow-lg">
          <div className="flex items-start gap-2">
            <AlertTriangle className="mt-0.5 h-5 w-5 flex-shrink-0 text-destructive" />
            <div className="flex-1">
              <div className="font-medium text-destructive">监考警告</div>
              <div className="text-sm text-foreground">{warning.message}</div>
              <div className="mt-1 text-xs text-muted-foreground">
                该行为已被记录并上报监考教师
              </div>
            </div>
            <button
              type="button"
              onClick={() => setWarning((s) => ({ ...s, visible: false }))}
              className="text-muted-foreground hover:text-foreground"
              aria-label="关闭警告"
            >
              <X className="h-4 w-4" />
            </button>
          </div>
        </div>
      )}
    </>
  )
}
