"use client"

import { useMemo, useState, useEffect, useRef, type ReactNode } from "react"
import { useQueryState, parseAsString } from "nuqs"
import { Tag, List, Share2, Menu, GraduationCap } from "lucide-react"
import { useTranslations } from "next-intl"
import { toast } from "sonner"
import Link from "next/link"

import type { Chapter, KnowledgePoint } from "../types"
import { updateChapterContentAction, getKnowledgePointsByChapterAction } from "../actions"
import { Permissions } from "@/shared/types/permissions"
import { usePermission } from "@/shared/hooks/use-permission"
import { ScrollArea } from "@/shared/components/ui/scroll-area"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/shared/components/ui/tabs"
import { Badge } from "@/shared/components/ui/badge"
import { Button } from "@/shared/components/ui/button"
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/shared/components/ui/alert-dialog"

import { ChapterSidebarList } from "./chapter-sidebar-list"
import { KnowledgeGraph } from "./knowledge-graph"
import { KnowledgePointList } from "./knowledge-point-list"
import { TextbookContentPanel } from "./textbook-content-panel"
import {
  KnowledgePointDialogs,
  type QuestionCreatorRenderProps,
} from "./knowledge-point-dialogs"
import { TextbookSectionErrorBoundary } from "./section-error-boundary"
import { EmptyState } from "@/shared/components/ui/empty-state"
import {
  Sheet,
  SheetContent,
  SheetHeader,
  SheetTitle,
} from "@/shared/components/ui/sheet"
import { ResizablePanel } from "@/shared/components/ui/resizable-panel"
import { useTextSelection } from "../hooks/use-text-selection"
import { useKnowledgePointActions } from "../hooks/use-knowledge-point-actions"
import { buildChapterIndex, highlightKnowledgePoints } from "../utils"

export interface TextbookReaderProps {
  chapters: Chapter[]
  /**
   * 教材 ID，用于按章节懒加载知识点（P2-3）。
   * 必传，否则知识点面板将始终为空。
   */
  textbookId: string
  /**
   * 题目创建器渲染函数（P0-1 解耦）。
   * 由页面层注入 questions 模块的 CreateQuestionDialog 实现。
   * 不传则不渲染题目创建入口。
   */
  renderQuestionCreator?: (props: QuestionCreatorRenderProps) => ReactNode
}

export function TextbookReader({
  chapters,
  textbookId,
  renderQuestionCreator,
}: TextbookReaderProps) {
  const t = useTranslations("textbooks")
  const { hasPermission } = usePermission()

  // P0-2 前端权限改由 usePermission 判断，不再接受外部 canEdit 硬编码
  const canEdit = hasPermission(Permissions.TEXTBOOK_UPDATE)
  const canCreateQuestion = hasPermission(Permissions.QUESTION_CREATE)
  const canCreateLessonPlan = hasPermission(Permissions.LESSON_PLAN_CREATE)

  const [chapterId, setChapterId] = useQueryState("chapterId", parseAsString.withDefault(""))
  const [activeTab, setActiveTab] = useState("chapters")
  const [highlightedKpId, setHighlightedKpId] = useState<string | null>(null)
  // P2-4 移动端抽屉式侧栏
  const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false)

  const [isEditing, setIsEditing] = useState(false)
  const [editContent, setEditContent] = useState("")
  const [isSaving, setIsSaving] = useState(false)

  const {
    selectedText,
    setSelectedText,
    contentRef,
    createDialogOpen,
    setCreateDialogOpen,
    isCreating,
    setIsCreating,
    handleContentPointerDown,
    handleContextMenuChange,
  } = useTextSelection()

  const index = useMemo(() => buildChapterIndex(chapters), [chapters])
  const selected = chapterId ? index.get(chapterId) ?? null : null
  const selectedId = selected?.id ?? null

  // P2-3 知识点懒加载：按章节通过 Server Action 按需加载，避免一次性拉取全部知识点
  // 使用缓存 + 派生值模式，避免在 effect 主体中同步 setState
  // v2-P2: textbookId 变化时通过页面层 key={textbookId} 重置整个 reader，无需手动清理缓存
  const [kpsByChapter, setKpsByChapter] = useState<Record<string, KnowledgePoint[]>>({})
  const requestedChaptersRef = useRef<Set<string>>(new Set())
  // 用 useMemo 包裹以稳定引用，避免下游 useMemo 因 [] 引用变化而重复计算
  const currentChapterKPs = useMemo<KnowledgePoint[]>(
    () => (selectedId ? kpsByChapter[selectedId] ?? [] : []),
    [selectedId, kpsByChapter]
  )
  // 加载状态派生：选中了章节但缓存中尚无数据时视为加载中
  const isLoadingKPs = selectedId !== null && kpsByChapter[selectedId] === undefined

  useEffect(() => {
    if (!selectedId || !textbookId) {
      return
    }
    // 已请求过的章节不重复请求（缓存命中）
    if (requestedChaptersRef.current.has(selectedId)) {
      return
    }
    requestedChaptersRef.current.add(selectedId)
    let cancelled = false
    getKnowledgePointsByChapterAction(selectedId, textbookId)
      .then((result) => {
        if (cancelled) return
        const data = result.success ? result.data : undefined
        setKpsByChapter((prev) => ({ ...prev, [selectedId]: data ?? [] }))
      })
      .catch(() => {
        if (!cancelled) setKpsByChapter((prev) => ({ ...prev, [selectedId]: [] }))
      })
    return () => {
      cancelled = true
    }
  }, [selectedId, textbookId])

  const {
    editingKp,
    setEditingKp,
    editKpDialogOpen,
    setEditKpDialogOpen,
    isUpdatingKp,
    questionDialogOpen,
    setQuestionDialogOpen,
    targetKpForQuestion,
    setTargetKpForQuestion,
    deleteConfirmOpen,
    setDeleteConfirmOpen,
    handleCreateKnowledgePoint,
    requestDeleteKnowledgePoint,
    confirmDeleteKnowledgePoint,
    handleUpdateKnowledgePoint,
  } = useKnowledgePointActions(
    textbookId,
    selectedId,
    selected?.textbookId,
    highlightedKpId,
    setHighlightedKpId,
    () => {
      setCreateDialogOpen(false)
      setActiveTab("knowledge")
      setSelectedText("")
    },
  )

  const [localContent, setLocalContent] = useState<string | null>(null)

  const onCreateKnowledgePoint = async (formData: FormData) => {
    setIsCreating(true)
    try {
      await handleCreateKnowledgePoint(formData)
    } finally {
      setIsCreating(false)
    }
  }

  const handleSaveContent = async () => {
    if (!selectedId || !textbookId) return
    setIsSaving(true)
    try {
      const result = await updateChapterContentAction(selectedId, editContent, textbookId)

      if (result.success) {
        toast.success(result.message)
        setIsEditing(false)
        setLocalContent(editContent)
      } else {
        toast.error(result.message)
      }
    } catch (e) {
      console.error("Failed to save chapter content", e)
      toast.error(t("reader.saveFailed"))
    } finally {
      setIsSaving(false)
    }
  }

  const startEditing = () => {
    if (selected) {
      setEditContent(selected.content || "")
      setIsEditing(true)
    }
  }

  const handleSelect = (chapter: Chapter) => {
    setChapterId(chapter.id)
    setIsEditing(false)
    setLocalContent(null)
    // P2-4 移动端选择章节后关闭抽屉
    setMobileSidebarOpen(false)
  }

  const effectiveContent = localContent ?? selected?.content

  // P2-2 性能优化：单遍 alternation 正则替换，避免 O(n×m) 多遍扫描
  const processedContent = useMemo(() => {
    if (!effectiveContent) return ""
    return highlightKnowledgePoints(effectiveContent, currentChapterKPs)
  }, [effectiveContent, currentChapterKPs])

  // P2 状态驱动：仅保留 scrollIntoView（滚动无法声明式实现），
  // 视觉高亮已由 TextbookContentPanel 中 isHighlighted 状态驱动，无需命令式 classList 操作
  useEffect(() => {
    if (!highlightedKpId) return
    const el = document.querySelector(`[data-kp-id="${highlightedKpId}"]`)
    if (!el) return
    el.scrollIntoView({ behavior: "smooth", block: "center" })
  }, [highlightedKpId])

  // P2-4 侧边栏内容（章节/知识点/图谱 Tabs），桌面端内联、移动端抽屉复用同一份
  const sidebarContent = (
    <Tabs value={activeTab} onValueChange={setActiveTab} className="flex flex-col h-full">
      <div className="flex items-center justify-between mb-4 px-2 shrink-0">
        <TabsList className="grid w-full grid-cols-3">
          <TabsTrigger value="chapters" className="gap-2">
            <List className="h-4 w-4" />
            {t("reader.tabs.chapters")}
          </TabsTrigger>
          <TabsTrigger value="knowledge" className="gap-2" disabled={!selectedId}>
            <Tag className="h-4 w-4" />
            {t("reader.tabs.knowledge")}
            {/* 任意值 text-[10px]：紧凑徽章，text-xs(12px) 在标签栏中过大 */}
            {currentChapterKPs.length > 0 && (
              <Badge variant="secondary" className="ml-1 px-1 py-0 h-5 text-[10px]">
                {currentChapterKPs.length}
              </Badge>
            )}
          </TabsTrigger>
          <TabsTrigger value="graph" className="gap-2">
            <Share2 className="h-4 w-4" />
            {t("reader.tabs.graph")}
          </TabsTrigger>
        </TabsList>
      </div>

      <TabsContent value="chapters" className="flex-1 min-h-0 mt-0">
        <TextbookSectionErrorBoundary
          fallbackTitle={t("error.loadFailed")}
          fallbackDescription={t("error.loadFailedDesc")}
          retryLabel={t("error.retry")}
        >
          <ScrollArea className="flex-1 h-full px-2">
            <div className="space-y-1 pb-4">
              <ChapterSidebarList
                chapters={chapters}
                selectedChapterId={selectedId || undefined}
                onSelectChapter={handleSelect}
                textbookId={textbookId || ""}
                canEdit={canEdit}
              />
            </div>
          </ScrollArea>
        </TextbookSectionErrorBoundary>
      </TabsContent>

      <TabsContent value="knowledge" className="flex-1 min-h-0 mt-0">
        <TextbookSectionErrorBoundary
          fallbackTitle={t("error.loadFailed")}
          fallbackDescription={t("error.loadFailedDesc")}
          retryLabel={t("error.retry")}
        >
          {!selectedId ? (
            <EmptyState
              icon={Tag}
              title={t("reader.selectChapterKnowledge")}
              description={t("reader.selectChapterKnowledgeDesc")}
              className="h-full border-none shadow-none bg-transparent"
            />
          ) : isLoadingKPs ? (
            <div className="h-full flex items-center justify-center text-sm text-muted-foreground">
              {t("reader.loadingKnowledge")}
            </div>
          ) : (
            <KnowledgePointList
              knowledgePoints={currentChapterKPs}
              canEdit={canEdit}
              canCreateQuestion={canCreateQuestion}
              highlightedKpId={highlightedKpId}
              onHighlight={setHighlightedKpId}
              onEdit={(kp) => {
                setEditingKp(kp)
                setEditKpDialogOpen(true)
              }}
              onDelete={requestDeleteKnowledgePoint}
              onCreateQuestion={(kp) => {
                setTargetKpForQuestion(kp)
                setQuestionDialogOpen(true)
              }}
            />
          )}
        </TextbookSectionErrorBoundary>
      </TabsContent>

      <TabsContent value="graph" className="flex-1 min-h-0 mt-0">
        <TextbookSectionErrorBoundary
          fallbackTitle={t("error.loadFailed")}
          fallbackDescription={t("error.loadFailedDesc")}
          retryLabel={t("error.retry")}
        >
          <KnowledgeGraph textbookId={textbookId} />
        </TextbookSectionErrorBoundary>
      </TabsContent>
    </Tabs>
  )

  // 图谱 tab 时侧栏（图谱）占更大比例，其他 tab 时侧栏（目录/知识点）占较小比例
  const sidebarInitialPct = activeTab === "graph" ? 60 : 35

  const contentPanel = (
    <div className="flex flex-col h-full min-h-0 relative">
      {/* 移动端侧栏触发按钮 + 为此课文备课按钮 */}
      <div className="flex items-center gap-2 mb-3 px-2 shrink-0">
        <Button
          variant="outline"
          size="sm"
          onClick={() => setMobileSidebarOpen(true)}
          className="lg:hidden"
          aria-expanded={mobileSidebarOpen}
          aria-controls="mobile-sidebar-sheet"
        >
          <Menu className="mr-2 h-4 w-4" />
          {t("reader.openSidebar")}
        </Button>
        {selected && (
          <span className="text-sm text-muted-foreground truncate hidden lg:inline">
            {selected.title}
          </span>
        )}
        {selected && canCreateLessonPlan && (
          <Button asChild variant="default" size="sm" className="ml-auto">
            <Link
              href={`/teacher/lesson-plans/new?textbookId=${encodeURIComponent(textbookId)}&chapterId=${encodeURIComponent(selected.id)}`}
            >
              <GraduationCap className="mr-2 h-4 w-4" />
              {t("reader.prepareLesson")}
            </Link>
          </Button>
        )}
      </div>

      <AlertDialog open={deleteConfirmOpen} onOpenChange={setDeleteConfirmOpen}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>{t("dialog.knowledge.deleteTitle")}</AlertDialogTitle>
            <AlertDialogDescription>{t("dialog.knowledge.deleteDesc")}</AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>{t("dialog.knowledge.cancel")}</AlertDialogCancel>
            <AlertDialogAction onClick={confirmDeleteKnowledgePoint}>
              {t("dialog.knowledge.delete")}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      <KnowledgePointDialogs
        createDialogOpen={createDialogOpen}
        setCreateDialogOpen={setCreateDialogOpen}
        selectedText={selectedText}
        isCreating={isCreating}
        onCreateKnowledgePoint={onCreateKnowledgePoint}
        editKpDialogOpen={editKpDialogOpen}
        setEditKpDialogOpen={setEditKpDialogOpen}
        editingKp={editingKp}
        isUpdatingKp={isUpdatingKp}
        onUpdateKnowledgePoint={handleUpdateKnowledgePoint}
        questionDialogOpen={questionDialogOpen}
        setQuestionDialogOpen={setQuestionDialogOpen}
        targetKpForQuestion={targetKpForQuestion}
        renderQuestionCreator={canCreateQuestion ? renderQuestionCreator : undefined}
      />

      <TextbookSectionErrorBoundary
        fallbackTitle={t("error.loadFailed")}
        fallbackDescription={t("error.loadFailedDesc")}
        retryLabel={t("error.retry")}
      >
        <TextbookContentPanel
          chapter={{ selected, processedContent }}
          editing={{
            isEditing,
            editContent,
            setEditContent,
            isSaving,
            startEditing,
            cancelEditing: () => setIsEditing(false),
            saveContent: handleSaveContent,
          }}
          selection={{
            contentRef,
            onPointerDown: handleContentPointerDown,
            onContextMenuChange: handleContextMenuChange,
            selectedText,
            setCreateDialogOpen,
          }}
          highlight={{
            highlightedKpId,
            onHighlight: setHighlightedKpId,
            onSwitchToKnowledgeTab: () => setActiveTab("knowledge"),
          }}
          canEdit={canEdit}
        />
      </TextbookSectionErrorBoundary>
    </div>
  )

  return (
    <div className="flex flex-col h-full lg:h-full">
      {/* 移动端：单列布局 + Sheet 抽屉侧栏 */}
      <div className="lg:hidden flex-1 min-h-0">{contentPanel}</div>
      <Sheet open={mobileSidebarOpen} onOpenChange={setMobileSidebarOpen}>
        {/* 任意值 w-[85vw]：移动端抽屉占视口宽度，max-w-sm 防止超宽屏过大 */}
        <SheetContent side="left" className="w-[85vw] max-w-sm p-0 flex flex-col">
          <SheetHeader className="px-4 py-3 border-b shrink-0">
            <SheetTitle className="text-left">{t("reader.sidebar")}</SheetTitle>
          </SheetHeader>
          <div className="flex-1 min-h-0 p-2">{sidebarContent}</div>
        </SheetContent>
      </Sheet>

      {/* 桌面端：可拖拽分栏，左侧侧栏 + 右侧正文，切换 tab 时重置比例 */}
      <div className="hidden lg:flex h-full min-h-0">
        <ResizablePanel
          key={activeTab}
          initialLeft={sidebarInitialPct}
          minLeft={20}
          minRight={25}
          left={<div className="h-full pr-3 border-r">{sidebarContent}</div>}
          right={<div className="h-full pl-3">{contentPanel}</div>}
        />
      </div>
    </div>
  )
}
