"use client"

import { useState } from "react"
import { ChevronRight, FileText, Folder, Plus, Trash2, GripVertical } from "lucide-react"
import { toast } from "sonner"
import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors, DragEndEvent } from "@dnd-kit/core"
import { SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy, useSortable } from "@dnd-kit/sortable"
import { CSS } from "@dnd-kit/utilities"
import { Chapter } from "../types"
import {
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
} from "@/shared/components/ui/collapsible"
import { Button } from "@/shared/components/ui/button"
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/shared/components/ui/alert-dialog"
import { cn } from "@/shared/lib/utils"
import { CreateChapterDialog } from "./create-chapter-dialog"
import { deleteChapterAction, reorderChaptersAction } from "../actions"

interface SortableChapterItemProps {
  chapter: Chapter
  level: number
  selectedId?: string
  onSelect: (chapter: Chapter) => void
  textbookId: string
  onDelete: (chapter: Chapter) => void
  onCreateSub: (parentId: string) => void
  canEdit?: boolean
}

function SortableChapterItem({ chapter, level, selectedId, onSelect, textbookId, onDelete, onCreateSub, canEdit = true }: SortableChapterItemProps) {
  const [isOpen, setIsOpen] = useState(level === 0)
  const hasChildren = chapter.children && chapter.children.length > 0
  const isSelected = chapter.id === selectedId

  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({ id: chapter.id, disabled: !canEdit })

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
    zIndex: isDragging ? 10 : 1,
    position: "relative" as const,
  }

  return (
    <div ref={setNodeRef} style={style} className={cn(level > 0 && "ml-2 border-l border-muted/30 pl-2")}>
      <Collapsible open={isOpen} onOpenChange={setIsOpen}>
        <div className={cn(
            "flex items-center group py-1.5 px-2 rounded-md transition-colors cursor-pointer select-none",
            isSelected ? "bg-accent text-accent-foreground font-medium" : "hover:bg-muted/50 text-muted-foreground hover:text-foreground",
            isDragging && "opacity-50"
        )}>
          {canEdit && (
            <div {...attributes} {...listeners} className="mr-1 cursor-grab opacity-0 group-hover:opacity-100 transition-opacity p-1 hover:bg-muted rounded">
               <GripVertical className="h-3.5 w-3.5 text-muted-foreground/50" />
            </div>
          )}

          {hasChildren ? (
            <CollapsibleTrigger asChild>
              <Button
                variant="ghost"
                size="icon"
                className="h-5 w-5 shrink-0 p-0 mr-1 hover:bg-transparent text-muted-foreground/70"
                onClick={(e) => e.stopPropagation()} 
              >
                <ChevronRight
                  className={cn(
                    "h-3.5 w-3.5 transition-transform duration-200",
                    isOpen && "rotate-90"
                  )}
                />
                <span className="sr-only">Toggle</span>
              </Button>
            </CollapsibleTrigger>
          ) : (
            <div className="w-5 shrink-0 mr-1" />
          )}
          
          <div 
            className="flex-1 min-w-0 flex items-center gap-2"
            onClick={() => onSelect(chapter)}
          >
            {hasChildren ? (
              <Folder className={cn("h-4 w-4 shrink-0 transition-colors", isOpen || isSelected ? "text-blue-500/80" : "text-muted-foreground/50")} />
            ) : (
              <FileText className={cn("h-4 w-4 shrink-0 transition-colors", isSelected ? "text-blue-500/80" : "text-muted-foreground/50")} />
            )}
            <span className="truncate text-sm">{chapter.title}</span>
          </div>

          <div className={cn("flex items-center opacity-0 group-hover:opacity-100 transition-opacity ml-2", !canEdit && "hidden")}>
              <Button
                variant="ghost"
                size="icon"
                className="h-6 w-6 text-muted-foreground hover:text-foreground"
                onClick={(e) => {
                  e.stopPropagation()
                  onCreateSub(chapter.id)
                }}
                title="Add Subchapter"
              >
                <Plus className="h-3.5 w-3.5" />
              </Button>
              <Button
                variant="ghost"
                size="icon"
                className="h-6 w-6 text-muted-foreground hover:text-destructive"
                onClick={(e) => {
                  e.stopPropagation()
                  onDelete(chapter)
                }}
                title="Delete Chapter"
              >
                <Trash2 className="h-3.5 w-3.5" />
              </Button>
          </div>
        </div>
        
        <CollapsibleContent>
          <div className="pt-1">
             {hasChildren && (
                <RecursiveSortableList 
                    items={chapter.children!} 
                    level={level + 1}
                    selectedId={selectedId}
                    onSelect={onSelect}
                    textbookId={textbookId}
                    onDelete={onDelete}
                    onCreateSub={onCreateSub}
                    canEdit={canEdit}
                />
             )}
          </div>
        </CollapsibleContent>
      </Collapsible>
    </div>
  )
}

function RecursiveSortableList({ items, level, selectedId, onSelect, textbookId, onDelete, onCreateSub, canEdit = true }: { 
    items: Chapter[], 
    level: number, 
    selectedId?: string, 
    onSelect: (c: Chapter) => void,
    textbookId: string,
    onDelete: (c: Chapter) => void,
    onCreateSub: (pid: string) => void,
    canEdit?: boolean
}) {
    return (
        <SortableContext items={items.map(i => i.id)} strategy={verticalListSortingStrategy}>
            {items.map((chapter) => (
                <SortableChapterItem 
                    key={chapter.id} 
                    chapter={chapter} 
                    level={level}
                    selectedId={selectedId}
                    onSelect={onSelect}
                    textbookId={textbookId}
                    onDelete={onDelete}
                    onCreateSub={onCreateSub}
                    canEdit={canEdit}
                />
            ))}
        </SortableContext>
    )
}

interface ChapterSidebarListProps {
  chapters: Chapter[]
  selectedChapterId?: string
  onSelectChapter: (chapter: Chapter) => void
  textbookId: string
  canEdit?: boolean
}

export function ChapterSidebarList({ chapters, selectedChapterId, onSelectChapter, textbookId, canEdit = true }: ChapterSidebarListProps) {
  const [showCreateDialog, setShowCreateDialog] = useState(false)
  const [createParentId, setCreateParentId] = useState<string | undefined>(undefined)
  
  const [showDeleteDialog, setShowDeleteDialog] = useState(false)
  const [deleteTarget, setDeleteTarget] = useState<Chapter | null>(null)
  const [isDeleting, setIsDeleting] = useState(false)

  const sensors = useSensors(
      useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
      useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
  )

  const handleDragEnd = async (event: DragEndEvent) => {
      const { active, over } = event
      if (!over || active.id === over.id) return

      // Find which list the items belong to
      // Since we only support sibling reordering for now, we assume active and over are in the same list
      // We need a helper to find the parent of an item in the tree
      const findParent = (items: Chapter[], id: string): Chapter | null => {
          for (const item of items) {
              if (item.children?.some(c => c.id === id)) return item
              if (item.children) {
                  const found = findParent(item.children, id)
                  if (found) return found
              }
          }
          return null
      }

      const activeParent = findParent(chapters, active.id as string)
      const overParent = findParent(chapters, over.id as string)
      
      // If parents don't match (and neither is root), we can't reorder easily in this simplified version
      // But actually, we need to check if they are in the same list.
      // If both are root items (activeParent is null), they are siblings.
      
      const getSiblings = (parentId: string | null) => {
          if (!parentId) return chapters
          const parent = chapters.find(c => c.id === parentId) // This only finds root parents, we need recursive find
          
          const findNode = (nodes: Chapter[], id: string): Chapter | null => {
              for (const node of nodes) {
                  if (node.id === id) return node
                  if (node.children) {
                      const found = findNode(node.children, id)
                      if (found) return found
                  }
              }
              return null
          }
          
          return findNode(chapters, parentId)?.children || []
      }

      // Simplified logic: We trust dnd-kit's SortableContext to only allow valid drops if we restricted it?
      // No, dnd-kit allows dropping anywhere by default unless restricted.
      
      // We need to find the list that contains the 'active' item
      // And the list that contains the 'over' item.
      // If they are the same list, we reorder.
      
      let activeList: Chapter[] = chapters
      let activeParentId: string | null = null
      
      if (activeParent) {
          activeList = activeParent.children || []
          activeParentId = activeParent.id
      } else {
           // Check if active is in root
           if (!chapters.some(c => c.id === active.id)) {
               // Should not happen if tree is consistent
               return 
           }
      }
      
      // Check if over is in the same list
      if (activeList.some(c => c.id === over.id)) {
          const oldIndex = activeList.findIndex((item) => item.id === active.id)
          const newIndex = activeList.findIndex((item) => item.id === over.id)
          
          await reorderChaptersAction(active.id as string, newIndex, activeParentId, textbookId)
          toast.success("Order updated")
      }
  }

  const handleDelete = async () => {
    if (!deleteTarget) return
    setIsDeleting(true)
    const res = await deleteChapterAction(deleteTarget.id, textbookId)
    setIsDeleting(false)
    if (res.success) {
      toast.success(res.message)
      setShowDeleteDialog(false)
      setDeleteTarget(null)
    } else {
      toast.error(res.message)
    }
  }

  const handleDeleteRequest = (chapter: Chapter) => {
      if (chapter.children && chapter.children.length > 0) {
          toast.error("Cannot delete chapter with subchapters")
          return
      }
      setDeleteTarget(chapter)
      setShowDeleteDialog(true)
  }

  const handleCreateSubRequest = (parentId: string) => {
      setCreateParentId(parentId)
      setShowCreateDialog(true)
  }

  // If not editable, we can skip dnd logic
  if (!canEdit) {
     return (
        <RecursiveSortableList 
            items={chapters} 
            level={0} 
            selectedId={selectedChapterId}
            onSelect={onSelectChapter}
            textbookId={textbookId}
            onDelete={handleDeleteRequest}
            onCreateSub={handleCreateSubRequest}
            canEdit={false}
        />
     )
  }

  return (
    <DndContext id="chapter-sidebar-dnd" sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
        <RecursiveSortableList 
            items={chapters} 
            level={0} 
            selectedId={selectedChapterId}
            onSelect={onSelectChapter}
            textbookId={textbookId}
            onDelete={handleDeleteRequest}
            onCreateSub={handleCreateSubRequest}
            canEdit={true}
        />

        <CreateChapterDialog 
            textbookId={textbookId} 
            parentId={createParentId}
            open={showCreateDialog}
            onOpenChange={(open) => {
                setShowCreateDialog(open)
                if (!open) setCreateParentId(undefined)
            }}
        />
        
        <AlertDialog open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>
            <AlertDialogContent>
            <AlertDialogHeader>
                <AlertDialogTitle>Delete Chapter?</AlertDialogTitle>
                <AlertDialogDescription>
                This will permanently delete <span className="font-medium text-foreground">{deleteTarget?.title}</span>.
                This action cannot be undone.
                </AlertDialogDescription>
            </AlertDialogHeader>
            <AlertDialogFooter>
                <AlertDialogCancel>Cancel</AlertDialogCancel>
                <AlertDialogAction onClick={handleDelete} className="bg-destructive text-destructive-foreground hover:bg-destructive/90" disabled={isDeleting}>
                {isDeleting ? "Deleting..." : "Delete"}
                </AlertDialogAction>
            </AlertDialogFooter>
            </AlertDialogContent>
        </AlertDialog>
    </DndContext>
  )
}
