import { useState, useEffect, useCallback } from 'react'
import { Folder, ChevronDown, ChevronRight, Plus, MoreVertical, Pencil, Trash2, FolderPlus, X } from 'lucide-react'
import { foldersApi } from '@/api/folders'
import { ConfirmDialog } from '@/components/common/ConfirmDialog'
import type { FolderListItem, FolderTreeItem } from '@/types'
import { cn } from '@/lib/utils'

interface FolderSidebarProps {
  selectedFolderId: string | null
  onFolderSelect: (folderId: string | null) => void
  onCreateFolder: (parentId?: string | null) => void
  onEditFolder: (folder: FolderListItem) => void
  mobileOpen?: boolean
  onMobileClose?: () => void
}

// Build tree structure from flat folder list
function buildFolderTree(folders: FolderListItem[]): FolderTreeItem[] {
  const folderMap = new Map<string, FolderTreeItem>()
  const rootFolders: FolderTreeItem[] = []

  // First pass: create all folder items
  folders.forEach((folder) => {
    folderMap.set(folder.id, {
      ...folder,
      children: [],
      isExpanded: true, // Default expanded
    })
  })

  // Second pass: build parent-child relationships
  folders.forEach((folder) => {
    const treeItem = folderMap.get(folder.id)!
    if (folder.parent_id && folderMap.has(folder.parent_id)) {
      const parent = folderMap.get(folder.parent_id)!
      parent.children.push(treeItem)
    } else {
      rootFolders.push(treeItem)
    }
  })

  // Sort children by display_order
  const sortChildren = (items: FolderTreeItem[]) => {
    items.sort((a, b) => a.display_order - b.display_order)
    items.forEach((item) => sortChildren(item.children))
  }
  sortChildren(rootFolders)

  return rootFolders
}

// Get all descendant IDs (for cascade delete warning)
function getDescendantIds(folders: FolderListItem[], folderId: string): string[] {
  const children = folders.filter((f) => f.parent_id === folderId)
  const descendantIds: string[] = []
  children.forEach((child) => {
    descendantIds.push(child.id)
    descendantIds.push(...getDescendantIds(folders, child.id))
  })
  return descendantIds
}

interface ContextMenuState {
  x: number
  y: number
  folder: FolderTreeItem
  canAddSubfolder: boolean
}

interface FolderItemProps {
  folder: FolderTreeItem
  depth: number
  selectedFolderId: string | null
  expandedIds: Set<string>
  menuOpenId: string | null
  onFolderSelect: (folderId: string) => void
  onToggleExpand: (folderId: string) => void
  onMenuToggle: (folderId: string | null) => void
  onEditFolder: (folder: FolderListItem) => void
  onAddSubfolder: (parentId: string) => void
  onDeleteFolder: (folderId: string, hasChildren: boolean) => void
  onContextMenu: (e: React.MouseEvent, folder: FolderTreeItem, canAddSubfolder: boolean) => void
  canAddSubfolder: boolean
}

function FolderItem({
  folder,
  depth,
  selectedFolderId,
  expandedIds,
  menuOpenId,
  onFolderSelect,
  onToggleExpand,
  onMenuToggle,
  onEditFolder,
  onAddSubfolder,
  onDeleteFolder,
  onContextMenu,
  canAddSubfolder,
}: FolderItemProps) {
  const isExpanded = expandedIds.has(folder.id)
  const hasSubfolders = folder.children.length > 0

  const handleContextMenu = (e: React.MouseEvent) => {
    e.preventDefault()
    e.stopPropagation()
    onContextMenu(e, folder, canAddSubfolder)
  }

  return (
    <div>
      <div className="group relative" onContextMenu={handleContextMenu}>
        <button
          onClick={() => onFolderSelect(folder.id)}
          className={cn(
            'flex w-full items-center gap-1 rounded-md py-1.5 text-sm',
            'transition-colors hover:bg-accent',
            selectedFolderId === folder.id && 'bg-accent text-foreground font-medium'
          )}
          style={{ paddingLeft: `${8 + depth * 16}px`, paddingRight: '8px' }}
        >
          {/* Expand/collapse toggle */}
          {hasSubfolders ? (
            <button
              onClick={(e) => {
                e.stopPropagation()
                onToggleExpand(folder.id)
              }}
              className="shrink-0 p-0.5 hover:bg-accent rounded"
            >
              {isExpanded ? (
                <ChevronDown className="h-3 w-3" />
              ) : (
                <ChevronRight className="h-3 w-3" />
              )}
            </button>
          ) : (
            <span className="w-4" /> // Spacer for alignment
          )}
          <Folder className="h-4 w-4 shrink-0" style={{ color: folder.color }} />
          <span className="flex-1 truncate text-left">{folder.name}</span>
          <span className="text-xs text-muted-foreground group-hover:hidden">{folder.tree_count}</span>
        </button>

        {/* Folder menu button - replaces tree count on hover */}
        <button
          onClick={(e) => {
            e.stopPropagation()
            onMenuToggle(menuOpenId === folder.id ? null : folder.id)
          }}
          className={cn(
            'absolute right-1 top-1/2 -translate-y-1/2 rounded p-1',
            'hidden group-hover:block',
            'hover:bg-accent'
          )}
        >
          <MoreVertical className="h-3 w-3" />
        </button>

        {/* Dropdown menu */}
        {menuOpenId === folder.id && (
          <div
            className={cn(
              'absolute right-0 top-full z-10 mt-1 w-40 rounded-md border border-border',
              'bg-card backdrop-blur-sm py-1 shadow-lg'
            )}
          >
            <button
              onClick={(e) => {
                e.stopPropagation()
                onEditFolder(folder)
                onMenuToggle(null)
              }}
              className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
            >
              <Pencil className="h-3 w-3" />
              Edit
            </button>
            {canAddSubfolder && (
              <button
                onClick={(e) => {
                  e.stopPropagation()
                  onAddSubfolder(folder.id)
                  onMenuToggle(null)
                }}
                className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
              >
                <FolderPlus className="h-3 w-3" />
                Add Subfolder
              </button>
            )}
            <button
              onClick={(e) => {
                e.stopPropagation()
                onDeleteFolder(folder.id, hasSubfolders)
                onMenuToggle(null)
              }}
              className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-red-400 hover:bg-red-400/10"
            >
              <Trash2 className="h-3 w-3" />
              Delete
            </button>
          </div>
        )}
      </div>

      {/* Children */}
      {isExpanded && hasSubfolders && (
        <div>
          {folder.children.map((child) => (
            <FolderItem
              key={child.id}
              folder={child}
              depth={depth + 1}
              selectedFolderId={selectedFolderId}
              expandedIds={expandedIds}
              menuOpenId={menuOpenId}
              onFolderSelect={onFolderSelect}
              onToggleExpand={onToggleExpand}
              onMenuToggle={onMenuToggle}
              onEditFolder={onEditFolder}
              onAddSubfolder={onAddSubfolder}
              onDeleteFolder={onDeleteFolder}
              onContextMenu={onContextMenu}
              canAddSubfolder={depth + 1 < 2} // Max depth is 3, so can add at depth 0, 1 (not 2)
            />
          ))}
        </div>
      )}
    </div>
  )
}

export function FolderSidebar({
  selectedFolderId,
  onFolderSelect,
  onCreateFolder,
  onEditFolder,
  mobileOpen = false,
  onMobileClose,
}: FolderSidebarProps) {
  const [folders, setFolders] = useState<FolderListItem[]>([])
  const [folderTree, setFolderTree] = useState<FolderTreeItem[]>([])
  const [isExpanded, setIsExpanded] = useState(true)
  const [isLoading, setIsLoading] = useState(true)
  const [menuOpenId, setMenuOpenId] = useState<string | null>(null)
  const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set())
  const [contextMenu, setContextMenu] = useState<ContextMenuState | null>(null)
  const [pendingDelete, setPendingDelete] = useState<{ id: string; message: string } | null>(null)

  const loadFolders = useCallback(async () => {
    setIsLoading(true)
    try {
      const data = await foldersApi.list()
      setFolders(data)
      setFolderTree(buildFolderTree(data))
      // Expand all by default
      setExpandedIds(new Set(data.map((f) => f.id)))
    } catch (err) {
      console.error('Failed to load folders:', err)
    } finally {
      setIsLoading(false)
    }
  }, [])

  useEffect(() => {
    loadFolders()
  }, [loadFolders])

  const handleToggleExpand = (folderId: string) => {
    setExpandedIds((prev) => {
      const next = new Set(prev)
      if (next.has(folderId)) {
        next.delete(folderId)
      } else {
        next.add(folderId)
      }
      return next
    })
  }

  const handleDeleteFolder = (folderId: string, folderHasChildren: boolean) => {
    const descendantCount = getDescendantIds(folders, folderId).length
    const message = folderHasChildren
      ? `Are you sure you want to delete this folder and its ${descendantCount} subfolder(s)? The trees in them will not be deleted.`
      : 'Are you sure you want to delete this folder? The trees in it will not be deleted.'

    setPendingDelete({ id: folderId, message })
  }

  const confirmDeleteFolder = async () => {
    if (!pendingDelete) return
    const folderId = pendingDelete.id
    setPendingDelete(null)
    try {
      await foldersApi.delete(folderId)
      // Remove folder and all descendants from local state
      const idsToRemove = new Set([folderId, ...getDescendantIds(folders, folderId)])
      const updatedFolders = folders.filter((f) => !idsToRemove.has(f.id))
      setFolders(updatedFolders)
      setFolderTree(buildFolderTree(updatedFolders))
      if (selectedFolderId && idsToRemove.has(selectedFolderId)) {
        onFolderSelect(null)
      }
    } catch (err) {
      console.error('Failed to delete folder:', err)
    }
  }

  const handleAddSubfolder = (parentId: string) => {
    onCreateFolder(parentId)
  }

  const handleContextMenu = (e: React.MouseEvent, folder: FolderTreeItem, canAddSubfolder: boolean) => {
    setContextMenu({
      x: e.clientX,
      y: e.clientY,
      folder,
      canAddSubfolder,
    })
    setMenuOpenId(null) // Close any open hover menu
  }

  const closeContextMenu = () => {
    setContextMenu(null)
  }

  // Refresh folders when a folder is edited or created
  useEffect(() => {
    const handleFolderChange = () => loadFolders()
    window.addEventListener('folder-changed', handleFolderChange)
    return () => window.removeEventListener('folder-changed', handleFolderChange)
  }, [loadFolders])

  // Close hover menu when clicking outside
  useEffect(() => {
    if (!menuOpenId) return
    const handleClickOutside = () => setMenuOpenId(null)
    document.addEventListener('click', handleClickOutside)
    return () => document.removeEventListener('click', handleClickOutside)
  }, [menuOpenId])

  // Close context menu on click outside, right-click elsewhere, or Escape
  useEffect(() => {
    if (!contextMenu) return
    const close = () => setContextMenu(null)
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === 'Escape') close()
    }
    document.addEventListener('click', close)
    document.addEventListener('contextmenu', close)
    document.addEventListener('keydown', handleKeyDown)
    return () => {
      document.removeEventListener('click', close)
      document.removeEventListener('contextmenu', close)
      document.removeEventListener('keydown', handleKeyDown)
    }
  }, [contextMenu])

  return (
    <>
    {/* Mobile backdrop */}
    {mobileOpen && (
      <div
        className="fixed inset-0 z-40 bg-black/80 backdrop-blur-sm md:hidden"
        onClick={onMobileClose}
        aria-hidden="true"
      />
    )}
    <div className={cn(
      'w-56 shrink-0 border-r border-border bg-transparent',
      'hidden md:block',
      mobileOpen && 'fixed inset-y-0 left-0 z-50 block animate-slide-in-left md:relative md:animate-none'
    )}>
      <div className="p-4">
        {/* Mobile close button */}
        {mobileOpen && (
          <div className="mb-3 flex items-center justify-between md:hidden">
            <span className="text-sm font-medium text-foreground">Folders</span>
            <button
              onClick={onMobileClose}
              className="rounded-md p-1.5 text-muted-foreground hover:bg-accent"
              aria-label="Close folders"
            >
              <X className="h-4 w-4" />
            </button>
          </div>
        )}
        <button
          onClick={() => setIsExpanded(!isExpanded)}
          className="flex w-full items-center gap-2 text-sm font-medium text-foreground"
        >
          {isExpanded ? (
            <ChevronDown className="h-4 w-4" />
          ) : (
            <ChevronRight className="h-4 w-4" />
          )}
          <span>FOLDERS</span>
        </button>

        {isExpanded && (
          <div className="mt-3 space-y-0.5">
            {/* All Trees */}
            <button
              onClick={() => onFolderSelect(null)}
              className={cn(
                'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm',
                'transition-colors hover:bg-accent',
                selectedFolderId === null && 'bg-accent text-foreground font-medium'
              )}
            >
              <Folder className="h-4 w-4" />
              <span>All Trees</span>
            </button>

            {/* Loading state */}
            {isLoading ? (
              <div className="px-2 py-1.5 text-sm text-muted-foreground">Loading...</div>
            ) : (
              <>
                {/* User folders (hierarchical) */}
                {folderTree.map((folder) => (
                  <FolderItem
                    key={folder.id}
                    folder={folder}
                    depth={0}
                    selectedFolderId={selectedFolderId}
                    expandedIds={expandedIds}
                    menuOpenId={menuOpenId}
                    onFolderSelect={onFolderSelect}
                    onToggleExpand={handleToggleExpand}
                    onMenuToggle={setMenuOpenId}
                    onEditFolder={onEditFolder}
                    onAddSubfolder={handleAddSubfolder}
                    onDeleteFolder={handleDeleteFolder}
                    onContextMenu={handleContextMenu}
                    canAddSubfolder={true} // Root folders can have subfolders
                  />
                ))}
              </>
            )}

            {/* Create folder button */}
            <button
              onClick={() => onCreateFolder(null)}
              className={cn(
                'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm',
                'text-muted-foreground transition-colors hover:bg-accent hover:text-foreground'
              )}
            >
              <Plus className="h-4 w-4" />
              <span>New Folder</span>
            </button>
          </div>
        )}
      </div>
    </div>

    {/* Right-click context menu */}
    {contextMenu && (
      <div
        className={cn(
          'fixed z-50 w-44 rounded-md border border-border',
          'bg-card backdrop-blur-sm py-1 shadow-lg'
        )}
        style={{ left: contextMenu.x, top: contextMenu.y }}
        onClick={(e) => e.stopPropagation()}
      >
        <button
          onClick={() => {
            onEditFolder(contextMenu.folder)
            closeContextMenu()
          }}
          className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
        >
          <Pencil className="h-3 w-3" />
          Edit
        </button>
        {contextMenu.canAddSubfolder && (
          <button
            onClick={() => {
              handleAddSubfolder(contextMenu.folder.id)
              closeContextMenu()
            }}
            className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
          >
            <FolderPlus className="h-3 w-3" />
            Add Subfolder
          </button>
        )}
        <button
          onClick={() => {
            handleDeleteFolder(contextMenu.folder.id, contextMenu.folder.children.length > 0)
            closeContextMenu()
          }}
          className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-red-400 hover:bg-red-400/10"
        >
          <Trash2 className="h-3 w-3" />
          Delete
        </button>
      </div>
    )}

    <ConfirmDialog
      isOpen={!!pendingDelete}
      onClose={() => setPendingDelete(null)}
      onConfirm={confirmDeleteFolder}
      title="Delete Folder"
      message={pendingDelete?.message || ''}
      confirmLabel="Delete"
    />
    </>
  )
}

export default FolderSidebar
