/**
 * 章节树 - 仿照 catalog 设计，支持篇、章、节拖拽排序
 * 整行可拖拽；节和章可跨篇
 */
import { useCallback, useState } from 'react'
import { ChevronRight, ChevronDown, BookOpen, Edit3, Trash2, GripVertical, Plus, Star } from 'lucide-react'
import { Button } from '@/components/ui/button'

const PART_LABELS = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十']

export interface SectionItem {
  id: string
  title: string
  price: number
  isFree?: boolean
  isNew?: boolean
  clickCount?: number
  payCount?: number
  hotScore?: number
  hotRank?: number
}

export interface ChapterItem {
  id: string
  title: string
  sections: SectionItem[]
}

export interface PartItem {
  id: string
  title: string
  chapters: ChapterItem[]
}

type DragType = 'part' | 'chapter' | 'section'

function parseDragData(data: string): { type: DragType; id: string } | null {
  if (data.startsWith('part:')) return { type: 'part', id: data.slice(5) }
  if (data.startsWith('chapter:')) return { type: 'chapter', id: data.slice(8) }
  if (data.startsWith('section:')) return { type: 'section', id: data.slice(8) }
  return null
}

interface ChapterTreeProps {
  parts: PartItem[]
  expandedParts: string[]
  onTogglePart: (partId: string) => void
  onReorder: (items: { id: string; partId: string; partTitle: string; chapterId: string; chapterTitle: string }[]) => Promise<void>
  onReadSection: (s: SectionItem) => void
  onDeleteSection: (s: SectionItem) => void
  onAddSectionInPart?: (part: PartItem) => void
  onAddChapterInPart?: (part: PartItem) => void
  onDeleteChapter?: (part: PartItem, chapter: ChapterItem) => void
  onEditPart?: (part: PartItem) => void
  onDeletePart?: (part: PartItem) => void
  onEditChapter?: (part: PartItem, chapter: ChapterItem) => void
  /** 批量移动：勾选章节 */
  selectedSectionIds?: string[]
  onToggleSectionSelect?: (sectionId: string) => void
  /** 查看某节的付款记录 */
  onShowSectionOrders?: (s: SectionItem) => void
  /** 置顶章节ID列表 */
  pinnedSectionIds?: string[]
}

export function ChapterTree({
  parts,
  expandedParts,
  onTogglePart,
  onReorder,
  onReadSection,
  onDeleteSection,
  onAddSectionInPart,
  onAddChapterInPart,
  onDeleteChapter,
  onEditPart,
  onDeletePart,
  onEditChapter,
  selectedSectionIds = [],
  onToggleSectionSelect,
  onShowSectionOrders,
  pinnedSectionIds = [],
}: ChapterTreeProps) {
  const [draggingItem, setDraggingItem] = useState<{ type: DragType; id: string } | null>(null)
  const [dragOverTarget, setDragOverTarget] = useState<{ type: DragType; id: string } | null>(null)

  const isDragging = (type: DragType, id: string) => draggingItem?.type === type && draggingItem?.id === id
  const isDragOver = (type: DragType, id: string) => dragOverTarget?.type === type && dragOverTarget?.id === id

  const buildSectionsList = useCallback(
    (): { id: string; partId: string; partTitle: string; chapterId: string; chapterTitle: string }[] => {
      const list: { id: string; partId: string; partTitle: string; chapterId: string; chapterTitle: string }[] = []
      for (const part of parts) {
        for (const ch of part.chapters) {
          for (const s of ch.sections) {
            list.push({
              id: s.id,
              partId: part.id,
              partTitle: part.title,
              chapterId: ch.id,
              chapterTitle: ch.title,
            })
          }
        }
      }
      return list
    },
    [parts],
  )

  const handleDrop = useCallback(
    async (e: React.DragEvent, toType: DragType, toId: string, toContext?: { partId: string; partTitle: string; chapterId: string; chapterTitle: string }) => {
      e.preventDefault()
      e.stopPropagation()
      const data = e.dataTransfer.getData('text/plain')
      const from = parseDragData(data)
      if (!from) return
      if (from.type === toType && from.id === toId) return

      const sections = buildSectionsList()
      const sectionMap = new Map(sections.map((x) => [x.id, x]))

      // 所有篇/章/节均可拖拽与作为落点（与后台顺序一致）
      if (from.type === 'part' && toType === 'part') {
        const partOrder = parts.map((p) => p.id)
        const fromIdx = partOrder.indexOf(from.id)
        const toIdx = partOrder.indexOf(toId)
        if (fromIdx === -1 || toIdx === -1) return
        const next = [...partOrder]
        next.splice(fromIdx, 1)
        next.splice(fromIdx < toIdx ? toIdx - 1 : toIdx, 0, from.id)
        const newList: typeof sections = []
        for (const pid of next) {
          const p = parts.find((x) => x.id === pid)
          if (!p) continue
          for (const ch of p.chapters) {
            for (const s of ch.sections) {
              const ctx = sectionMap.get(s.id)
              if (ctx) newList.push(ctx)
            }
          }
        }
        await onReorder(newList)
        return
      }

      if (from.type === 'chapter' && (toType === 'chapter' || toType === 'section' || toType === 'part')) {
        const srcPart = parts.find((p) => p.chapters.some((c) => c.id === from.id))
        const srcCh = srcPart?.chapters.find((c) => c.id === from.id)
        if (!srcPart || !srcCh) return

        let targetPartId: string
        let targetPartTitle: string
        let insertAfterId: string | null = null

        if (toType === 'section') {
          const ctx = sectionMap.get(toId)
          if (!ctx) return
          targetPartId = ctx.partId
          targetPartTitle = ctx.partTitle
          insertAfterId = toId
        } else if (toType === 'chapter') {
          const part = parts.find((p) => p.chapters.some((c) => c.id === toId))
          const ch = part?.chapters.find((c) => c.id === toId)
          if (!part || !ch) return
          targetPartId = part.id
          targetPartTitle = part.title
          const lastInCh = sections.filter((s) => s.chapterId === toId).pop()
          insertAfterId = lastInCh?.id ?? null
        } else {
          const part = parts.find((p) => p.id === toId)
          if (!part || !part.chapters[0]) return
          targetPartId = part.id
          targetPartTitle = part.title
          const firstChSections = sections.filter((s) => s.partId === part.id && s.chapterId === part.chapters[0].id)
          insertAfterId = firstChSections[firstChSections.length - 1]?.id ?? null
        }

        const movingIds = srcCh.sections.map((s) => s.id)
        const rest = sections.filter((s) => !movingIds.includes(s.id))

        let targetIdx = rest.length
        if (insertAfterId) {
          const idx = rest.findIndex((s) => s.id === insertAfterId)
          if (idx >= 0) targetIdx = idx + 1
        }

        const moving = movingIds.map((id) => {
          const s = sectionMap.get(id)!
          return {
            ...s,
            partId: targetPartId,
            partTitle: targetPartTitle,
            chapterId: srcCh.id,
            chapterTitle: srcCh.title,
          }
        })
        await onReorder([...rest.slice(0, targetIdx), ...moving, ...rest.slice(targetIdx)])
        return
      }

      if (from.type === 'section' && (toType === 'section' || toType === 'chapter' || toType === 'part')) {
        if (!toContext) return
        const { partId: targetPartId, partTitle: targetPartTitle, chapterId: targetChapterId, chapterTitle: targetChapterTitle } = toContext

        let toIdx: number
        if (toType === 'section') {
          toIdx = sections.findIndex((s) => s.id === toId)
        } else if (toType === 'chapter') {
          const lastInCh = sections.filter((s) => s.chapterId === toId).pop()
          toIdx = lastInCh ? sections.findIndex((s) => s.id === lastInCh.id) + 1 : sections.length
        } else {
          const part = parts.find((p) => p.id === toId)
          if (!part?.chapters[0]) return
          const firstChSections = sections.filter((s) => s.partId === part.id && s.chapterId === part.chapters[0].id)
          const last = firstChSections[firstChSections.length - 1]
          toIdx = last ? sections.findIndex((s) => s.id === last.id) + 1 : 0
        }

        const fromIdx = sections.findIndex((s) => s.id === from.id)
        if (fromIdx === -1) return

        const next = sections.filter((s) => s.id !== from.id)
        const insertIdx = fromIdx < toIdx ? toIdx - 1 : toIdx
        const moved = sections[fromIdx]
        const newItem = { ...moved, partId: targetPartId, partTitle: targetPartTitle, chapterId: targetChapterId, chapterTitle: targetChapterTitle }
        next.splice(insertIdx, 0, newItem)
        await onReorder(next)
      }
    },
    [parts, buildSectionsList, onReorder],
  )

  const droppableHandlers = (type: DragType, id: string, ctx?: { partId: string; partTitle: string; chapterId: string; chapterTitle: string }) => ({
    onDragEnter: (e: React.DragEvent) => {
      e.preventDefault()
      e.stopPropagation()
      e.dataTransfer.dropEffect = 'move'
      setDragOverTarget({ type, id })
    },
    onDragOver: (e: React.DragEvent) => {
      e.preventDefault()
      e.stopPropagation()
      e.dataTransfer.dropEffect = 'move'
      setDragOverTarget({ type, id })
    },
    onDragLeave: () => setDragOverTarget(null),
    onDrop: (e: React.DragEvent) => {
      setDragOverTarget(null)
      const from = parseDragData(e.dataTransfer.getData('text/plain'))
      if (!from) return
      if (type === 'section' && from.type === 'section' && from.id === id) return
      if (type === 'part') {
        if (from.type === 'part') handleDrop(e, 'part', id)
        else {
          const part = parts.find((p) => p.id === id)
          const firstCh = part?.chapters[0]
          if (firstCh && ctx) handleDrop(e, 'part', id, ctx)
        }
      } else if (type === 'chapter' && ctx) {
        if (from.type === 'section' || from.type === 'chapter') handleDrop(e, 'chapter', id, ctx)
      } else if (type === 'section' && ctx) {
        handleDrop(e, 'section', id, ctx)
      }
    },
  })

  const partLabel = (i: number) => PART_LABELS[i] ?? String(i + 1)

  return (
    <div className="space-y-3">
      {parts.map((part, partIndex) => {
        const isXuYan = part.title === '序言' || part.title.includes('序言')
        const isWeiSheng = part.title === '尾声' || part.title.includes('尾声')
        const isFuLu = part.title === '附录' || part.title.includes('附录')
        const partDragOver = isDragOver('part', part.id)
        const isExpanded = expandedParts.includes(part.id)
        const chapterCount = part.chapters.length
        const sectionCount = part.chapters.reduce((s, ch) => s + ch.sections.length, 0)

        // 序言：单行卡片，带六点拖拽、可拖可放
        if (isXuYan && part.chapters.length === 1 && part.chapters[0].sections.length === 1) {
          const sec = part.chapters[0].sections[0]
          const secDragOver = isDragOver('section', sec.id)
          const ctx = { partId: part.id, partTitle: part.title, chapterId: part.chapters[0].id, chapterTitle: part.chapters[0].title }
          return (
            <div
              key={part.id}
              draggable
              onDragStart={(e) => {
                e.stopPropagation()
                e.dataTransfer.setData('text/plain', 'section:' + sec.id)
                e.dataTransfer.effectAllowed = 'move'
                setDraggingItem({ type: 'section', id: sec.id })
              }}
              onDragEnd={() => { setDraggingItem(null); setDragOverTarget(null) }}
              className={`rounded-xl border border-gray-700/50 bg-[#1C1C1E] p-4 flex items-center justify-between hover:border-[#38bdac]/30 transition-colors cursor-grab active:cursor-grabbing select-none min-h-[40px] ${secDragOver ? 'bg-[#38bdac]/15 ring-2 ring-[#38bdac]/50' : ''} ${isDragging('section', sec.id) ? 'opacity-60 scale-[0.98] ring-2 ring-[#38bdac]' : ''}`}
              {...droppableHandlers('section', sec.id, ctx)}
            >
              <div className="flex items-center gap-3 flex-1 min-w-0 select-none">
                <GripVertical className="w-5 h-5 text-gray-500 shrink-0 opacity-60" />
                {onToggleSectionSelect && (
                  <label className="shrink-0 flex items-center" onClick={(e) => e.stopPropagation()}>
                    <input
                      type="checkbox"
                      checked={selectedSectionIds.includes(sec.id)}
                      onChange={() => onToggleSectionSelect(sec.id)}
                      className="w-4 h-4 rounded border-gray-600 bg-[#0a1628] text-[#38bdac] focus:ring-[#38bdac]"
                    />
                  </label>
                )}
                <div className="w-8 h-8 rounded-lg bg-gray-600/50 flex items-center justify-center shrink-0">
                  <BookOpen className="w-4 h-4 text-gray-400" />
                </div>
                <span className="font-medium text-gray-200 truncate">
                  {part.chapters[0].title} | {sec.title}
                </span>
                {pinnedSectionIds.includes(sec.id) && <span title="已置顶"><Star className="w-3.5 h-3.5 text-amber-400 fill-amber-400 shrink-0" /></span>}
              </div>
              <div
                className="flex items-center gap-2 shrink-0"
                onMouseDown={(e) => e.stopPropagation()}
                onClick={(e) => e.stopPropagation()}
              >
                {sec.price === 0 || sec.isFree ? (
                  <span className="px-2 py-1 bg-[#38bdac]/20 text-[#38bdac] text-[10px] font-medium rounded">免费</span>
                ) : (
                  <span className="text-xs text-gray-500">¥{sec.price}</span>
                )}
                <span className="text-[10px] text-gray-500">点击 {(sec.clickCount ?? 0)} · 付款 {(sec.payCount ?? 0)}</span>
                <span className="text-[10px] text-amber-400/90" title="热度积分与排名">热度 {(sec.hotScore ?? 0).toFixed(1)} · 第{(sec.hotRank && sec.hotRank > 0 ? sec.hotRank : '-')}名</span>
                {onShowSectionOrders && (
                  <Button draggable={false} variant="ghost" size="sm" onClick={() => onShowSectionOrders(sec)} className="text-[10px] text-gray-500 hover:text-[#38bdac] h-7 px-1.5">
                    付款记录
                  </Button>
                )}
                <div className="flex gap-1">
                  <Button draggable={false} variant="ghost" size="sm" onClick={() => onReadSection(sec)} className="text-gray-500 hover:text-[#38bdac] h-7 px-2" title="编辑">
                    <Edit3 className="w-3.5 h-3.5" />
                  </Button>
                  <Button draggable={false} variant="ghost" size="sm" onClick={() => onDeleteSection(sec)} className="text-gray-500 hover:text-red-400 h-7 px-2">
                    <Trash2 className="w-3.5 h-3.5" />
                  </Button>
                </div>
              </div>
            </div>
          )
        }

        // 2026每日派对干货：独立篇章，带六点拖拽、可拖可放
        const is2026Daily = part.title === '2026每日派对干货' || part.title.includes('2026每日派对干货')
        if (is2026Daily) {
          const partDragOver = isDragOver('part', part.id)
          return (
            <div
              key={part.id}
              className={`rounded-xl border overflow-hidden transition-all duration-200 ${partDragOver ? 'border-[#38bdac] ring-2 ring-[#38bdac]/40 bg-[#38bdac]/5' : 'border-gray-700/50 bg-[#1C1C1E]'}`}
              {...droppableHandlers('part', part.id, {
                partId: part.id,
                partTitle: part.title,
                chapterId: part.chapters[0]?.id ?? '',
                chapterTitle: part.chapters[0]?.title ?? '',
              })}
            >
              <div
                draggable
                onDragStart={(e) => {
                  e.stopPropagation()
                  e.dataTransfer.setData('text/plain', 'part:' + part.id)
                  e.dataTransfer.effectAllowed = 'move'
                  setDraggingItem({ type: 'part', id: part.id })
                }}
                onDragEnd={() => { setDraggingItem(null); setDragOverTarget(null) }}
                className={`flex items-center justify-between p-4 cursor-grab active:cursor-grabbing select-none transition-all duration-200 ${isDragging('part', part.id) ? 'opacity-60 scale-[0.98] ring-2 ring-[#38bdac]' : 'hover:bg-[#162840]/50'}`}
                onClick={() => onTogglePart(part.id)}
              >
                <div className="flex items-center gap-3 min-w-0">
                  <GripVertical className="w-5 h-5 text-gray-500 shrink-0 opacity-60" />
                  <div className="w-10 h-10 rounded-xl bg-[#38bdac]/80 flex items-center justify-center text-white font-bold shrink-0">
                    派
                  </div>
                  <div>
                    <h3 className="font-bold text-white text-base">{part.title}</h3>
                    <p className="text-xs text-gray-500 mt-0.5">共 {sectionCount} 节</p>
                  </div>
                </div>
                <div
                  className="flex items-center gap-2 shrink-0"
                  onMouseDown={(e) => e.stopPropagation()}
                  onClick={(e) => e.stopPropagation()}
                >
                  {onAddSectionInPart && (
                    <Button draggable={false} variant="ghost" size="sm" onClick={() => onAddSectionInPart(part)} className="text-gray-500 hover:text-[#38bdac] h-7 px-2" title="在本篇下新增章节">
                      <Plus className="w-3.5 h-3.5" />
                    </Button>
                  )}
                  {onEditPart && (
                    <Button draggable={false} variant="ghost" size="sm" onClick={() => onEditPart(part)} className="text-gray-500 hover:text-[#38bdac] h-7 px-2" title="编辑篇名">
                      <Edit3 className="w-3.5 h-3.5" />
                    </Button>
                  )}
                  {onDeletePart && (
                    <Button draggable={false} variant="ghost" size="sm" onClick={() => onDeletePart(part)} className="text-gray-500 hover:text-red-400 h-7 px-2" title="删除本篇">
                      <Trash2 className="w-3.5 h-3.5" />
                    </Button>
                  )}
                  <span className="text-xs text-gray-500">{chapterCount}章</span>
                  {isExpanded ? (
                    <ChevronDown className="w-5 h-5 text-gray-500" />
                  ) : (
                    <ChevronRight className="w-5 h-5 text-gray-500" />
                  )}
                </div>
              </div>
              {isExpanded && part.chapters.length > 0 && (
                <div className="border-t border-gray-700/50 pl-4 pr-4 pb-4 pt-3 space-y-4">
                  {part.chapters.map((chapter) => (
                    <div key={chapter.id} className="space-y-2">
                      <div className="flex items-center gap-2 w-full">
                        <p className="text-xs text-gray-500 pb-1 flex-1">{chapter.title}</p>
                        <div className="flex gap-0.5 shrink-0" onClick={(e) => e.stopPropagation()}>
                          {onEditChapter && (
                            <Button variant="ghost" size="sm" onClick={() => onEditChapter(part, chapter)} className="text-gray-500 hover:text-[#38bdac] h-7 px-1.5" title="编辑章节名称">
                              <Edit3 className="w-3.5 h-3.5" />
                            </Button>
                          )}
                          {onAddChapterInPart && (
                            <Button variant="ghost" size="sm" onClick={() => onAddChapterInPart(part)} className="text-gray-500 hover:text-[#38bdac] h-7 px-1.5" title="新增第X章">
                              <Plus className="w-3.5 h-3.5" />
                            </Button>
                          )}
                          {onDeleteChapter && (
                            <Button variant="ghost" size="sm" onClick={() => onDeleteChapter(part, chapter)} className="text-gray-500 hover:text-red-400 h-7 px-1.5" title="删除本章">
                              <Trash2 className="w-3.5 h-3.5" />
                            </Button>
                          )}
                        </div>
                      </div>
                      <div className="space-y-1 pl-2">
                        {chapter.sections.map((section) => {
                          const secDragOver = isDragOver('section', section.id)
                          return (
                            <div
                              key={section.id}
                              draggable
                              onDragStart={(e) => {
                                e.stopPropagation()
                                e.dataTransfer.setData('text/plain', 'section:' + section.id)
                                e.dataTransfer.effectAllowed = 'move'
                                setDraggingItem({ type: 'section', id: section.id })
                              }}
                              onDragEnd={() => { setDraggingItem(null); setDragOverTarget(null) }}
                              onClick={() => onReadSection(section)}
                              className={`flex items-center justify-between py-2 px-3 rounded-lg min-h-[40px] cursor-pointer select-none transition-all duration-200 ${secDragOver ? 'bg-[#38bdac]/15 ring-2 ring-[#38bdac]/50' : 'hover:bg-[#162840]/50'} ${isDragging('section', section.id) ? 'opacity-60 scale-[0.98] ring-2 ring-[#38bdac]' : ''}`}
                              {...droppableHandlers('section', section.id, {
                                partId: part.id,
                                partTitle: part.title,
                                chapterId: chapter.id,
                                chapterTitle: chapter.title,
                              })}
                            >
                              <div className="flex items-center gap-2 min-w-0 flex-1">
                                <GripVertical className="w-4 h-4 text-gray-500 shrink-0 opacity-50" />
                                {onToggleSectionSelect && (
                                  <label className="shrink-0 flex items-center" onClick={(e) => e.stopPropagation()}>
                                    <input
                                      type="checkbox"
                                      checked={selectedSectionIds.includes(section.id)}
                                      onChange={() => onToggleSectionSelect(section.id)}
                                      className="w-4 h-4 rounded border-gray-600 bg-[#0a1628] text-[#38bdac] focus:ring-[#38bdac]"
                                    />
                                  </label>
                                )}
                                <span className="text-sm text-gray-200 truncate">{section.id} {section.title}</span>
                                {pinnedSectionIds.includes(section.id) && <span title="已置顶"><Star className="w-3 h-3 text-amber-400 fill-amber-400 shrink-0" /></span>}
                              </div>
                              <div className="flex items-center gap-2 shrink-0" onClick={(e) => e.stopPropagation()}>
                                <span className="text-[10px] text-gray-500">点击 {(section.clickCount ?? 0)} · 付款 {(section.payCount ?? 0)}</span>
                                <span className="text-[10px] text-amber-400/90" title="热度积分与排名">热度 {(section.hotScore ?? 0).toFixed(1)} · 第{(section.hotRank && section.hotRank > 0 ? section.hotRank : '-')}名</span>
                                {onShowSectionOrders && (
                                  <Button variant="ghost" size="sm" onClick={() => onShowSectionOrders(section)} className="text-[10px] text-gray-500 hover:text-[#38bdac] h-7 px-1.5">
                                    付款记录
                                  </Button>
                                )}
                                <Button draggable={false} variant="ghost" size="sm" onClick={() => onReadSection(section)} className="text-gray-500 hover:text-[#38bdac] h-7 px-1.5" title="编辑">
                                  <Edit3 className="w-3.5 h-3.5" />
                                </Button>
                                <Button draggable={false} variant="ghost" size="sm" onClick={() => onDeleteSection(section)} className="text-gray-500 hover:text-red-400 h-7 px-1.5">
                                  <Trash2 className="w-3.5 h-3.5" />
                                </Button>
                              </div>
                            </div>
                          )
                        })}
                      </div>
                    </div>
                  ))}
                </div>
              )}
            </div>
          )
        }

        // 附录：平铺章节列表，每节带六点拖拽、可拖可放
        if (isFuLu) {
          return (
            <div key={part.id} className="rounded-xl border border-gray-700/50 bg-[#1C1C1E] p-5">
              <h3 className="text-sm font-medium text-gray-400 mb-4">附录</h3>
              <div className="space-y-3">
                {part.chapters.map((ch, chIdx) =>
                  ch.sections.length > 0
                    ? ch.sections.map((sec) => {
                        const secDragOver = isDragOver('section', sec.id)
                        return (
                          <div
                            key={sec.id}
                            draggable
                            onDragStart={(e) => {
                              e.stopPropagation()
                              e.dataTransfer.setData('text/plain', 'section:' + sec.id)
                              e.dataTransfer.effectAllowed = 'move'
                              setDraggingItem({ type: 'section', id: sec.id })
                            }}
                            onDragEnd={() => { setDraggingItem(null); setDragOverTarget(null) }}
                            className={`flex justify-between items-center py-2 select-none rounded px-2 -mx-2 group cursor-grab active:cursor-grabbing min-h-[40px] transition-all duration-200 ${secDragOver ? 'bg-[#38bdac]/15 ring-2 ring-[#38bdac]/50' : 'hover:bg-[#162840]/50'} ${isDragging('section', sec.id) ? 'opacity-60 scale-[0.98] ring-2 ring-[#38bdac]' : ''}`}
                            {...droppableHandlers('section', sec.id, {
                              partId: part.id,
                              partTitle: part.title,
                              chapterId: ch.id,
                              chapterTitle: ch.title,
                            })}
                          >
                            <div className="flex items-center gap-2 min-w-0 flex-1">
                              <GripVertical className="w-4 h-4 text-gray-500 shrink-0 opacity-50" />
                              {onToggleSectionSelect && (
                                <label className="shrink-0 flex items-center" onClick={(e) => e.stopPropagation()}>
                                  <input
                                    type="checkbox"
                                    checked={selectedSectionIds.includes(sec.id)}
                                    onChange={() => onToggleSectionSelect(sec.id)}
                                    className="w-4 h-4 rounded border-gray-600 bg-[#0a1628] text-[#38bdac] focus:ring-[#38bdac]"
                                  />
                                </label>
                              )}
                              <span className="text-sm text-gray-300 truncate">附录{chIdx + 1} | {ch.title} | {sec.title}</span>
                              {pinnedSectionIds.includes(sec.id) && <span title="已置顶"><Star className="w-3 h-3 text-amber-400 fill-amber-400 shrink-0" /></span>}
                            </div>
                            <div className="flex items-center gap-2 shrink-0">
                              <span className="text-[10px] text-gray-500">点击 {(sec.clickCount ?? 0)} · 付款 {(sec.payCount ?? 0)}</span>
                              <span className="text-[10px] text-amber-400/90" title="热度积分与排名">热度 {(sec.hotScore ?? 0).toFixed(1)} · 第{(sec.hotRank && sec.hotRank > 0 ? sec.hotRank : '-')}名</span>
                              {onShowSectionOrders && (
                                <Button variant="ghost" size="sm" onClick={() => onShowSectionOrders(sec)} className="text-[10px] text-gray-500 hover:text-[#38bdac] h-7 px-1.5">
                                  付款记录
                                </Button>
                              )}
                              <div className="flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
                              <Button variant="ghost" size="sm" onClick={() => onReadSection(sec)} className="text-gray-500 hover:text-[#38bdac] h-7 px-1.5" title="编辑">
                                <Edit3 className="w-3.5 h-3.5" />
                              </Button>
                              <Button variant="ghost" size="sm" onClick={() => onDeleteSection(sec)} className="text-gray-500 hover:text-red-400 h-7 px-1.5">
                                <Trash2 className="w-3.5 h-3.5" />
                              </Button>
                              </div>
                            </div>
                            <ChevronRight className="w-4 h-4 text-gray-500 shrink-0" />
                          </div>
                        )
                      })
                    : (
                        <div key={ch.id} className="flex justify-between items-center py-2 select-none hover:bg-[#162840]/50 rounded px-2 -mx-2">
                          <span className="text-sm text-gray-500">附录{chIdx + 1} | {ch.title}（空）</span>
                          <ChevronRight className="w-4 h-4 text-gray-500 shrink-0" />
                        </div>
                      ),
                )}
              </div>
            </div>
          )
        }

        // 尾声：单节，带六点拖拽、可拖可放
        if (isWeiSheng && part.chapters.length === 1 && part.chapters[0].sections.length === 1) {
          const sec = part.chapters[0].sections[0]
          const secDragOver = isDragOver('section', sec.id)
          const ctx = { partId: part.id, partTitle: part.title, chapterId: part.chapters[0].id, chapterTitle: part.chapters[0].title }
          return (
            <div
              key={part.id}
              draggable
              onDragStart={(e) => {
                e.stopPropagation()
                e.dataTransfer.setData('text/plain', 'section:' + sec.id)
                e.dataTransfer.effectAllowed = 'move'
                setDraggingItem({ type: 'section', id: sec.id })
              }}
              onDragEnd={() => { setDraggingItem(null); setDragOverTarget(null) }}
              className={`rounded-xl border border-gray-700/50 bg-[#1C1C1E] p-4 flex items-center justify-between hover:border-[#38bdac]/30 transition-colors cursor-grab active:cursor-grabbing select-none min-h-[40px] ${secDragOver ? 'bg-[#38bdac]/15 ring-2 ring-[#38bdac]/50' : ''} ${isDragging('section', sec.id) ? 'opacity-60 scale-[0.98] ring-2 ring-[#38bdac]' : ''}`}
              {...droppableHandlers('section', sec.id, ctx)}
            >
              <div className="flex items-center gap-3 flex-1 min-w-0 select-none">
                <GripVertical className="w-5 h-5 text-gray-500 shrink-0 opacity-60" />
                {onToggleSectionSelect && (
                  <label className="shrink-0 flex items-center" onClick={(e) => e.stopPropagation()}>
                    <input
                      type="checkbox"
                      checked={selectedSectionIds.includes(sec.id)}
                      onChange={() => onToggleSectionSelect(sec.id)}
                      className="w-4 h-4 rounded border-gray-600 bg-[#0a1628] text-[#38bdac] focus:ring-[#38bdac]"
                    />
                  </label>
                )}
                <div className="w-8 h-8 rounded-lg bg-gray-600/50 flex items-center justify-center shrink-0">
                  <BookOpen className="w-4 h-4 text-gray-400" />
                </div>
                <span className="font-medium text-gray-200 truncate">
                  {part.chapters[0].title} | {sec.title}
                </span>
              </div>
              <div
                className="flex items-center gap-2 shrink-0"
                onMouseDown={(e) => e.stopPropagation()}
                onClick={(e) => e.stopPropagation()}
              >
                {sec.price === 0 || sec.isFree ? (
                  <span className="px-2 py-1 bg-[#38bdac]/20 text-[#38bdac] text-[10px] font-medium rounded">免费</span>
                ) : (
                  <span className="text-xs text-gray-500">¥{sec.price}</span>
                )}
                <span className="text-[10px] text-gray-500">点击 {(sec.clickCount ?? 0)} · 付款 {(sec.payCount ?? 0)}</span>
                <span className="text-[10px] text-amber-400/90" title="热度积分与排名">热度 {(sec.hotScore ?? 0).toFixed(1)} · 第{(sec.hotRank && sec.hotRank > 0 ? sec.hotRank : '-')}名</span>
                {onShowSectionOrders && (
                  <Button draggable={false} variant="ghost" size="sm" onClick={() => onShowSectionOrders(sec)} className="text-[10px] text-gray-500 hover:text-[#38bdac] h-7 px-1.5">
                    付款记录
                  </Button>
                )}
                <div className="flex gap-1">
                  <Button draggable={false} variant="ghost" size="sm" onClick={() => onReadSection(sec)} className="text-gray-500 hover:text-[#38bdac] h-7 px-2" title="编辑">
                    <Edit3 className="w-3.5 h-3.5" />
                  </Button>
                  <Button draggable={false} variant="ghost" size="sm" onClick={() => onDeleteSection(sec)} className="text-gray-500 hover:text-red-400 h-7 px-2">
                    <Trash2 className="w-3.5 h-3.5" />
                  </Button>
                </div>
              </div>
            </div>
          )
        }
        if (isWeiSheng) {
          // 尾声多章节：平铺展示，每节带六点拖拽、可拖可放
          return (
            <div key={part.id} className="rounded-xl border border-gray-700/50 bg-[#1C1C1E] p-5">
              <h3 className="text-sm font-medium text-gray-400 mb-4">尾声</h3>
              <div className="space-y-3">
                {part.chapters.map((ch) =>
                  ch.sections.map((sec) => {
                    const secDragOver = isDragOver('section', sec.id)
                    return (
                      <div
                        key={sec.id}
                        draggable
                        onDragStart={(e) => {
                          e.stopPropagation()
                          e.dataTransfer.setData('text/plain', 'section:' + sec.id)
                          e.dataTransfer.effectAllowed = 'move'
                          setDraggingItem({ type: 'section', id: sec.id })
                        }}
                        onDragEnd={() => { setDraggingItem(null); setDragOverTarget(null) }}
                        className={`flex justify-between items-center py-2 select-none rounded px-2 -mx-2 cursor-grab active:cursor-grabbing min-h-[40px] transition-all duration-200 ${secDragOver ? 'bg-[#38bdac]/15 ring-2 ring-[#38bdac]/50' : 'hover:bg-[#162840]/50'} ${isDragging('section', sec.id) ? 'opacity-60 scale-[0.98] ring-2 ring-[#38bdac]' : ''}`}
                        {...droppableHandlers('section', sec.id, {
                          partId: part.id,
                          partTitle: part.title,
                          chapterId: ch.id,
                          chapterTitle: ch.title,
                        })}
                      >
                        <div className="flex items-center gap-2 min-w-0 flex-1">
                          <GripVertical className="w-4 h-4 text-gray-500 shrink-0 opacity-50" />
                          {onToggleSectionSelect && (
                            <label className="shrink-0 flex items-center" onClick={(e) => e.stopPropagation()}>
                              <input
                                type="checkbox"
                                checked={selectedSectionIds.includes(sec.id)}
                                onChange={() => onToggleSectionSelect(sec.id)}
                                className="w-4 h-4 rounded border-gray-600 bg-[#0a1628] text-[#38bdac] focus:ring-[#38bdac]"
                              />
                            </label>
                          )}
                          <span className="text-sm text-gray-300">{ch.title} | {sec.title}</span>
                        </div>
                        <div className="flex items-center gap-2 shrink-0">
                          <span className="text-[10px] text-gray-500">点击 {(sec.clickCount ?? 0)} · 付款 {(sec.payCount ?? 0)}</span>
                          <span className="text-[10px] text-amber-400/90" title="热度积分与排名">热度 {(sec.hotScore ?? 0).toFixed(1)} · 第{(sec.hotRank && sec.hotRank > 0 ? sec.hotRank : '-')}名</span>
                          {onShowSectionOrders && (
                            <Button draggable={false} variant="ghost" size="sm" onClick={() => onShowSectionOrders(sec)} className="text-[10px] text-gray-500 hover:text-[#38bdac] h-7 px-1.5">
                              付款记录
                            </Button>
                          )}
                          <div className="flex gap-1">
                          <Button draggable={false} variant="ghost" size="sm" onClick={() => onReadSection(sec)} className="text-gray-500 hover:text-[#38bdac] h-7 px-2" title="编辑">
                            <Edit3 className="w-3.5 h-3.5" />
                          </Button>
                          <Button draggable={false} variant="ghost" size="sm" onClick={() => onDeleteSection(sec)} className="text-gray-500 hover:text-red-400 h-7 px-2">
                            <Trash2 className="w-3.5 h-3.5" />
                          </Button>
                          </div>
                        </div>
                      </div>
                    )
                  }),
                )}
              </div>
            </div>
          )
        }

        // 普通篇：卡片 + 章/节
        return (
          <div
            key={part.id}
            className={`rounded-xl border bg-[#1C1C1E] overflow-hidden transition-all duration-200 ${partDragOver ? 'border-[#38bdac] ring-2 ring-[#38bdac]/40 bg-[#38bdac]/5' : 'border-gray-700/50'}`}
            {...droppableHandlers('part', part.id, {
              partId: part.id,
              partTitle: part.title,
              chapterId: part.chapters[0]?.id ?? '',
              chapterTitle: part.chapters[0]?.title ?? '',
            })}
          >
            <div
              draggable
              onDragStart={(e) => {
                e.stopPropagation()
                e.dataTransfer.setData('text/plain', 'part:' + part.id)
                e.dataTransfer.effectAllowed = 'move'
                setDraggingItem({ type: 'part', id: part.id })
              }}
              onDragEnd={() => { setDraggingItem(null); setDragOverTarget(null) }}
              className={`flex items-center justify-between p-4 cursor-grab active:cursor-grabbing select-none transition-all duration-200 ${isDragging('part', part.id) ? 'opacity-60 scale-[0.98] ring-2 ring-[#38bdac] rounded-xl shadow-xl shadow-[#38bdac]/20' : 'hover:bg-[#162840]/50'}`}
              onClick={() => onTogglePart(part.id)}
            >
              <div className="flex items-center gap-3 min-w-0">
                <GripVertical className="w-5 h-5 text-gray-500 shrink-0 opacity-60" />
                <div className="w-10 h-10 rounded-xl bg-[#38bdac] flex items-center justify-center text-white font-bold shadow-lg shadow-[#38bdac]/30 shrink-0">
                  {partLabel(partIndex)}
                </div>
                <div>
                  <h3 className="font-bold text-white text-base">{part.title}</h3>
                  <p className="text-xs text-gray-500 mt-0.5">共 {sectionCount} 节</p>
                </div>
              </div>
              <div
                className="flex items-center gap-2 shrink-0"
                onMouseDown={(e) => e.stopPropagation()}
                onClick={(e) => e.stopPropagation()}
              >
                {onAddSectionInPart && (
                  <Button draggable={false} variant="ghost" size="sm" onClick={() => onAddSectionInPart(part)} className="text-gray-500 hover:text-[#38bdac] h-7 px-2" title="在本篇下新增章节">
                    <Plus className="w-3.5 h-3.5" />
                  </Button>
                )}
                {onEditPart && (
                  <Button draggable={false} variant="ghost" size="sm" onClick={() => onEditPart(part)} className="text-gray-500 hover:text-[#38bdac] h-7 px-2" title="编辑篇名">
                    <Edit3 className="w-3.5 h-3.5" />
                  </Button>
                )}
                {onDeletePart && (
                  <Button draggable={false} variant="ghost" size="sm" onClick={() => onDeletePart(part)} className="text-gray-500 hover:text-red-400 h-7 px-2" title="删除本篇">
                    <Trash2 className="w-3.5 h-3.5" />
                  </Button>
                )}
                <span className="text-xs text-gray-500">{chapterCount}章</span>
                {isExpanded ? (
                  <ChevronDown className="w-5 h-5 text-gray-500" />
                ) : (
                  <ChevronRight className="w-5 h-5 text-gray-500" />
                )}
              </div>
            </div>

            {isExpanded && (
              <div className="border-t border-gray-700/50 pl-4 pr-4 pb-4 pt-3 space-y-4">
                {part.chapters.map((chapter) => {
                  const chDragOver = isDragOver('chapter', chapter.id)
                  return (
                  <div key={chapter.id} className="space-y-2">
                    <div className="flex items-center gap-2 w-full">
                    <div
                      draggable
                      onDragStart={(e) => {
                        e.stopPropagation()
                        e.dataTransfer.setData('text/plain', 'chapter:' + chapter.id)
                        e.dataTransfer.effectAllowed = 'move'
                        setDraggingItem({ type: 'chapter', id: chapter.id })
                      }}
                      onDragEnd={() => { setDraggingItem(null); setDragOverTarget(null) }}
                      onDragEnter={(e) => {
                        e.preventDefault()
                        e.stopPropagation()
                        e.dataTransfer.dropEffect = 'move'
                        setDragOverTarget({ type: 'chapter', id: chapter.id })
                      }}
                      onDragOver={(e) => {
                        e.preventDefault()
                        e.stopPropagation()
                        e.dataTransfer.dropEffect = 'move'
                        setDragOverTarget({ type: 'chapter', id: chapter.id })
                      }}
                      onDragLeave={() => setDragOverTarget(null)}
                      onDrop={(e) => {
                        setDragOverTarget(null)
                        const from = parseDragData(e.dataTransfer.getData('text/plain'))
                        if (!from) return
                        const ctx = { partId: part.id, partTitle: part.title, chapterId: chapter.id, chapterTitle: chapter.title }
                        if (from.type === 'section') handleDrop(e, 'chapter', chapter.id, ctx)
                        else if (from.type === 'chapter') handleDrop(e, 'chapter', chapter.id, ctx)
                      }}
                      className={`flex-1 min-w-0 py-2 px-2 rounded cursor-grab active:cursor-grabbing select-none -mx-2 transition-all duration-200 flex items-center gap-2 ${chDragOver ? 'bg-[#38bdac]/15 ring-1 ring-[#38bdac]/50' : ''} ${isDragging('chapter', chapter.id) ? 'opacity-60 scale-[0.98] ring-2 ring-[#38bdac]' : 'hover:bg-[#162840]/30'}`}
                    >
                      <GripVertical className="w-4 h-4 text-gray-500 shrink-0 opacity-50" />
                      <p className="text-xs text-gray-500 pb-1 flex-1">{chapter.title}</p>
                    </div>
                    <div className="flex gap-0.5 shrink-0" onClick={(e) => e.stopPropagation()}>
                      {onEditChapter && (
                        <Button variant="ghost" size="sm" onClick={() => onEditChapter(part, chapter)} className="text-gray-500 hover:text-[#38bdac] h-7 px-1.5" title="编辑章节名称">
                          <Edit3 className="w-3.5 h-3.5" />
                        </Button>
                      )}
                      {onAddChapterInPart && (
                        <Button variant="ghost" size="sm" onClick={() => onAddChapterInPart(part)} className="text-gray-500 hover:text-[#38bdac] h-7 px-1.5" title="新增第X章">
                          <Plus className="w-3.5 h-3.5" />
                        </Button>
                      )}
                      {onDeleteChapter && (
                        <Button variant="ghost" size="sm" onClick={() => onDeleteChapter(part, chapter)} className="text-gray-500 hover:text-red-400 h-7 px-1.5" title="删除本章">
                          <Trash2 className="w-3.5 h-3.5" />
                        </Button>
                      )}
                    </div>
                    </div>
                    <div className="space-y-1 pl-2">
                      {chapter.sections.map((section) => {
                        const secDragOver = isDragOver('section', section.id)
                        return (
                        <div
                          key={section.id}
                          draggable
                          onDragStart={(e) => {
                            e.stopPropagation()
                            e.dataTransfer.setData('text/plain', 'section:' + section.id)
                            e.dataTransfer.effectAllowed = 'move'
                            setDraggingItem({ type: 'section', id: section.id })
                          }}
                          onDragEnd={() => { setDraggingItem(null); setDragOverTarget(null) }}
                          className={`flex items-center justify-between py-2 px-3 rounded-lg group cursor-grab active:cursor-grabbing select-none min-h-[40px] transition-all duration-200 ${secDragOver ? 'bg-[#38bdac]/15 ring-2 ring-[#38bdac]/50' : ''} ${isDragging('section', section.id) ? 'opacity-60 scale-[0.98] ring-2 ring-[#38bdac] shadow-lg' : 'hover:bg-[#162840]/50'}`}
                          {...droppableHandlers('section', section.id, {
                            partId: part.id,
                            partTitle: part.title,
                            chapterId: chapter.id,
                            chapterTitle: chapter.title,
                          })}
                        >
                          <div className="flex items-center gap-3 min-w-0 flex-1">
                            {onToggleSectionSelect && (
                              <label className="shrink-0 flex items-center" onClick={(e) => e.stopPropagation()}>
                                <input
                                  type="checkbox"
                                  checked={selectedSectionIds.includes(section.id)}
                                  onChange={() => onToggleSectionSelect(section.id)}
                                  className="w-4 h-4 rounded border-gray-600 bg-[#0a1628] text-[#38bdac] focus:ring-[#38bdac]"
                                />
                              </label>
                            )}
                            <GripVertical className="w-4 h-4 text-gray-500 shrink-0 opacity-50" />
                            <div
                              className={`w-2 h-2 rounded-full shrink-0 ${section.price === 0 || section.isFree ? 'border-2 border-[#38bdac] bg-transparent' : 'bg-gray-500'}`}
                            />
                            <span className="text-sm text-gray-200 truncate">
                              {section.id} {section.title}
                            </span>
                            {pinnedSectionIds.includes(section.id) && <span title="已置顶"><Star className="w-3 h-3 text-amber-400 fill-amber-400 shrink-0" /></span>}
                          </div>
                          <div
                            className="flex items-center gap-2 shrink-0"
                            onMouseDown={(e) => e.stopPropagation()}
                            onClick={(e) => e.stopPropagation()}
                          >
                            {section.isNew && (
                              <span className="px-2 py-1 bg-[#38bdac]/20 text-[#38bdac] text-[10px] font-medium rounded">NEW</span>
                            )}
                            {section.price === 0 || section.isFree ? (
                              <span className="px-2 py-1 bg-[#38bdac]/20 text-[#38bdac] text-[10px] font-medium rounded">免费</span>
                            ) : (
                              <span className="text-xs text-gray-500">¥{section.price}</span>
                            )}
                            <span className="text-[10px] text-gray-500" title="点击次数 · 付款笔数">点击 {(section.clickCount ?? 0)} · 付款 {(section.payCount ?? 0)}</span>
                            <span className="text-[10px] text-amber-400/90" title="热度积分与排名">热度 {(section.hotScore ?? 0).toFixed(1)} · 第{(section.hotRank && section.hotRank > 0 ? section.hotRank : '-')}名</span>
                            {onShowSectionOrders && (
                              <Button variant="ghost" size="sm" onClick={() => onShowSectionOrders(section)} className="text-[10px] text-gray-500 hover:text-[#38bdac] h-7 px-1.5 shrink-0">
                                付款记录
                              </Button>
                            )}
                            <div className="flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity">
                              <Button draggable={false} variant="ghost" size="sm" onClick={() => onReadSection(section)} className="text-gray-500 hover:text-[#38bdac] h-7 px-1.5" title="编辑">
                                <Edit3 className="w-3.5 h-3.5" />
                              </Button>
                              <Button draggable={false} variant="ghost" size="sm" onClick={() => onDeleteSection(section)} className="text-gray-500 hover:text-red-400 h-7 px-1.5">
                                <Trash2 className="w-3.5 h-3.5" />
                              </Button>
                            </div>
                          </div>
                        </div>
                        )
                      })}
                    </div>
                  </div>
                )
                })}
              </div>
            )}
          </div>
        )
      })}
    </div>
  )
}
