"use client"

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

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 { 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
  /**
   * 是否可编辑。已废弃——改由内部 usePermission() 自动判断。
   * 保留 prop 仅为向后兼容，传入值会被忽略。
   * @deprecated 改用权限系统自动判断
   */
  canEdit?: boolean
  /**
   * 题目创建器渲染函数（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 [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)
    await handleCreateKnowledgePoint(formData)
    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("Failed to save content")
    } 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])

  useEffect(() => {
    if (!highlightedKpId) return
    const el = document.querySelector(`[data-kp-id="${highlightedKpId}"]`)
    if (!el) return

    el.scrollIntoView({ behavior: "smooth", block: "center" })
    el.classList.add("ring-2", "ring-primary", "ring-offset-2")
    const timer = setTimeout(() => {
      el.classList.remove("ring-2", "ring-primary", "ring-offset-2")
    }, 2000)
    return () => {
      clearTimeout(timer)
    }
  }, [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")}
            {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>
  )

  return (
    <div className="grid grid-cols-1 gap-6 lg:grid-cols-12 h-full">
      {/* P2-4 桌面端侧栏：lg 及以上内联显示 */}
      <div className="hidden lg:flex lg:col-span-4 lg:border-r lg:pr-6 flex-col min-h-0">
        {sidebarContent}
      </div>

      {/* P2-4 移动端侧栏：lg 以下用 Sheet 抽屉式展示 */}
      <Sheet open={mobileSidebarOpen} onOpenChange={setMobileSidebarOpen}>
        <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>

      <div className="lg:col-span-8 flex flex-col min-h-0 relative">
        {/* P2-4 移动端侧栏触发按钮 */}
        <div className="lg:hidden flex items-center gap-2 mb-3 px-2 shrink-0">
          <Button
            variant="outline"
            size="sm"
            onClick={() => setMobileSidebarOpen(true)}
            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">
              {selected.title}
            </span>
          )}
        </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
            selected={selected}
            isEditing={isEditing}
            editContent={editContent}
            setEditContent={setEditContent}
            canEdit={canEdit}
            highlightedKpId={highlightedKpId}
            onHighlight={setHighlightedKpId}
            onSwitchToKnowledgeTab={() => setActiveTab("knowledge")}
            contentRef={contentRef}
            onPointerDown={handleContentPointerDown}
            onContextMenuChange={handleContextMenuChange}
            selectedText={selectedText}
            setCreateDialogOpen={setCreateDialogOpen}
            startEditing={startEditing}
            cancelEditing={() => setIsEditing(false)}
            saveContent={handleSaveContent}
            isSaving={isSaving}
            processedContent={processedContent}
          />
        </TextbookSectionErrorBoundary>
      </div>
    </div>
  )
}
