"use client"

import { useEffect, useState } from "react"
import type { Editor } from "@tiptap/react"
import {
  Box,
  Brackets,
  CircleSlash,
  FileText,
  Heading,
  Layers,
  Underline,
} from "lucide-react"

import { cn } from "@/shared/lib/utils"
import { Button } from "@/shared/components/ui/button"
import type { QuestionBlockType } from "./extensions/question-block"

interface SelectionToolbarProps {
  editor: Editor | null
  /** 当前选区所在题目块类型(用于显示状态) */
  activeQuestionType?: QuestionBlockType
  className?: string
}

interface ToolbarButtonProps {
  onClick: () => void
  icon: React.ElementType
  label: string
  active?: boolean
}

function ToolbarButton({ onClick, icon: Icon, label, active }: ToolbarButtonProps) {
  return (
    <Button
      type="button"
      variant={active ? "secondary" : "ghost"}
      size="sm"
      className={cn(
        "h-7 gap-1 px-2 text-xs",
        active && "bg-primary/15 text-primary hover:bg-primary/20"
      )}
      onMouseDown={(e) => {
        // 防止点击按钮时编辑器失焦
        e.preventDefault()
      }}
      onClick={(e) => {
        e.preventDefault()
        onClick()
      }}
      title={label}
    >
      <Icon className="h-3.5 w-3.5" />
      <span>{label}</span>
    </Button>
  )
}

/**
 * 选区标记浮层 —— 选中文本时浮现,提供"标记为题目/分组/加点字/填空"等快捷操作。
 * 跟随选区位置定位,使用 getBoundingClientRect 计算坐标。
 */
export function SelectionToolbar({
  editor,
  activeQuestionType,
  className,
}: SelectionToolbarProps) {
  const [coords, setCoords] = useState<{ top: number; left: number } | null>(null)
  const [hasSelection, setHasSelection] = useState(false)

  useEffect(() => {
    if (!editor) return

    const updatePosition = () => {
      const { from, to, empty } = editor.state.selection
      if (empty || from === to) {
        setCoords(null)
        setHasSelection(false)
        return
      }

      // 检查选区是否在 questionBlock/groupBlock 内部
      const $from = editor.state.selection.$from
      const depth = $from.depth
      let inBlock = false
      for (let d = depth; d > 0; d--) {
        const node = $from.node(d)
        if (node.type.name === "questionBlock" || node.type.name === "groupBlock") {
          inBlock = true
          break
        }
      }

      // 即使不在块内也允许显示(可标记为题目/分组)
      void inBlock

      const view = editor.view
      const start = view.coordsAtPos(from)
      const end = view.coordsAtPos(to)
      const top = Math.min(start.top, end.top) - 44 // 浮在选区上方
      const left = (start.left + end.right) / 2
      setCoords({ top, left })
      setHasSelection(true)
    }

    editor.on("selectionUpdate", updatePosition)
    editor.on("blur", () => {
      // 延迟以允许点击工具栏按钮
      setTimeout(() => {
        if (!editor.isFocused) {
          setCoords(null)
          setHasSelection(false)
        }
      }, 200)
    })

    return () => {
      editor.off("selectionUpdate", updatePosition)
    }
  }, [editor])

  if (!editor || !hasSelection || !coords) return null

  const { from, to, empty } = editor.state.selection
  const hasTextSelection = !empty && from !== to

  const insertQuestion = (type: QuestionBlockType) => {
    const chain = editor.chain().focus()
    if (hasTextSelection) {
      // 选中文本时:包裹为题目块
      chain.wrapInQuestion({ type, score: type === "composite" ? 5 : 2 }).run()
    } else {
      // 未选中文本时:插入空题目块
      chain.insertQuestion({ type, score: type === "composite" ? 5 : 2 }).run()
    }
  }

  const insertGroup = () => {
    const chain = editor.chain().focus()
    if (hasTextSelection) {
      chain.wrapInGroup("一、选择题", "").run()
    } else {
      chain.insertGroup("一、选择题", "").run()
    }
  }

  const insertSection = () => {
    const chain = editor.chain().focus()
    if (hasTextSelection) {
      chain.wrapInSection("第Ⅰ卷 选择题", 1).run()
    } else {
      chain.insertSection("第Ⅰ卷 选择题", 1).run()
    }
  }

  const toggleDotted = () => {
    editor.chain().focus().toggleDotted().run()
  }

  const insertBlank = () => {
    editor.chain().focus().insertBlank().run()
  }

  const insertImage = () => {
    // 触发隐藏的文件输入
    const input = document.createElement("input")
    input.type = "file"
    input.accept = "image/*"
    input.onchange = async () => {
      const file = input.files?.[0]
      if (!file) return
      const formData = new FormData()
      formData.append("file", file)
      formData.append("targetType", "exam")
      try {
        const res = await fetch("/api/upload", { method: "POST", body: formData })
        const data = await res.json()
        if (data?.success && data?.url) {
          editor.chain().focus().setImage({ src: data.url, fileId: data.id }).run()
        }
      } catch (e) {
        console.error("[SelectionToolbar] upload failed", e)
      }
    }
    input.click()
  }

  return (
    <div
      role="toolbar"
      aria-label="选区标记工具栏"
      className={cn(
        "fixed z-50 flex items-center gap-0.5 rounded-md border bg-popover/95 p-1 shadow-md backdrop-blur",
        className
      )}
      style={{
        top: `${Math.max(8, coords.top)}px`,
        left: `${coords.left}px`,
        transform: "translateX(-50%)",
      }}
    >
      <ToolbarButton onClick={insertSection} icon={Layers} label="分卷" />
      <ToolbarButton onClick={insertGroup} icon={Heading} label="大题" />
      <ToolbarButton
        onClick={() => insertQuestion("single_choice")}
        icon={CircleSlash}
        label="单选"
        active={activeQuestionType === "single_choice"}
      />
      <ToolbarButton
        onClick={() => insertQuestion("text")}
        icon={FileText}
        label="填空/简答"
        active={activeQuestionType === "text"}
      />
      <ToolbarButton
        onClick={() => insertQuestion("composite")}
        icon={Brackets}
        label="复合"
        active={activeQuestionType === "composite"}
      />
      <div className="mx-1 h-5 w-px bg-border" />
      <ToolbarButton onClick={toggleDotted} icon={Underline} label="加点字" />
      <ToolbarButton onClick={insertBlank} icon={Box} label="填空" />
      <ToolbarButton onClick={insertImage} icon={FileText} label="图片" />
    </div>
  )
}
