"use client"

import { useEffect, useState, useCallback } from "react"
import { ChevronRight, ChevronDown, Folder, Loader2 } from "lucide-react"

interface DirNode {
  name: string
  path: string
  has_children: boolean
}

interface DirectoryTreeProps {
  currentPath: string
  onNavigate: (path: string) => void
}

interface TreeNodeProps {
  node: DirNode
  depth: number
  isActive: boolean
  isExpanded: boolean
  isLoading: boolean
  subdirs: DirNode[]
  basePath: string
  onExpand: (path: string) => void
  onNavigate: (path: string) => void
}

const TreeNode = ({
  node,
  depth,
  isActive,
  isExpanded,
  isLoading,
  subdirs,
  basePath,
  onExpand,
  onNavigate,
}: TreeNodeProps) => {
  return (
    <div>
      <div
        className={`flex items-center gap-1 px-2 py-1 rounded cursor-pointer transition-colors ${
          isActive ? "bg-accent text-accent-foreground" : "hover:bg-muted/50"
        }`}
        style={{ paddingLeft: `${depth * 16 + 8}px` }}
      >
        {node.has_children ? (
          <button
            onClick={() => onExpand(node.path)}
            className="p-0 w-4 h-4 flex items-center justify-center"
          >
            {isLoading ? (
              <Loader2 className="w-3 h-3 animate-spin" />
            ) : isExpanded ? (
              <ChevronDown className="w-3 h-3" />
            ) : (
              <ChevronRight className="w-3 h-3" />
            )}
          </button>
        ) : (
          <div className="w-4" />
        )}

        <Folder className="w-4 h-4 flex-shrink-0 text-muted-foreground" />
        <button
          onClick={() => {
            const fullPath = basePath === "/" ? "/" + node.path : basePath + "/" + node.path
            onNavigate(fullPath)
          }}
          className="text-sm truncate text-left"
        >
          {node.name}
        </button>
      </div>

      {isExpanded && subdirs.length > 0 && (
        <div>
          {subdirs.map((child) => (
            <TreeNode
              key={child.path}
              node={child}
              depth={depth + 1}
              isActive={isActive}
              isExpanded={false}
              isLoading={false}
              subdirs={[]}
              basePath={basePath}
              onExpand={onExpand}
              onNavigate={onNavigate}
            />
          ))}
        </div>
      )}
    </div>
  )
}

const BookmarkButton = ({
  label,
  path,
  onNavigate,
}: {
  label: string
  path: string
  onNavigate: (path: string) => void
}) => (
  <button
    onClick={() => onNavigate(path)}
    className="w-full text-left px-2 py-1.5 rounded text-xs hover:bg-muted/50 transition-colors"
  >
    {label}
  </button>
)

export function DirectoryTree({
  currentPath,
  onNavigate,
}: DirectoryTreeProps) {
  const [expanded, setExpanded] = useState<Set<string>>(new Set())
  const [childrenMap, setChildrenMap] = useState<Map<string, DirNode[]>>(
    new Map()
  )
  const [loading, setLoading] = useState<Set<string>>(new Set())

  const getAuthHeader = () => {
    const token = localStorage.getItem("access_token")
    return {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
    }
  }

  const getApiUrl = (path: string) => {
    const baseUrl = process.env.NEXT_PUBLIC_API_URL || ""
    return baseUrl + path
  }

  const fetchChildren = useCallback(
    async (path: string) => {
      // If already loaded, just toggle expand
      if (childrenMap.has(path)) {
        setExpanded((prev) => {
          const newSet = new Set(prev)
          if (newSet.has(path)) {
            newSet.delete(path)
          } else {
            newSet.add(path)
          }
          return newSet
        })
        return
      }

      // Fetch children
      setLoading((prev) => new Set(prev).add(path))

      try {
        const qs = `path=${encodeURIComponent(path)}&admin=true`
        const res = await fetch(getApiUrl(`/api/navigator/dirs?${qs}`), {
          headers: getAuthHeader(),
        })
        const data = await res.json()

        setChildrenMap((prev) => new Map(prev).set(path, data.dirs || []))
        setExpanded((prev) => new Set(prev).add(path))
      } catch (err) {
        console.error("Failed to fetch subdirectories:", err)
      } finally {
        setLoading((prev) => {
          const newSet = new Set(prev)
          newSet.delete(path)
          return newSet
        })
      }
    },
    [childrenMap]
  )

  // Auto-expand ancestors when currentPath changes
  useEffect(() => {
    if (!currentPath || currentPath === "/") return

    const parts = currentPath.replace(/^\//, "").split("/").filter(Boolean)
    for (let i = 0; i < parts.length; i++) {
      const ancestorPath = parts.slice(0, i).join("/")
      if (!childrenMap.has(ancestorPath)) {
        fetchChildren(ancestorPath)
      } else {
        setExpanded((prev) => new Set(prev).add(ancestorPath))
      }
    }
  }, [currentPath, childrenMap, fetchChildren])

  // Load root on mount
  useEffect(() => {
    fetchChildren("")
  }, [fetchChildren])

  const basePath = "/"
  const rootPath = ""
  const rootChildren = childrenMap.get(rootPath) || []

  return (
    <div className="space-y-3">
      {/* Bookmarks Section */}
      <div className="border-b border-border pb-2">
        <p className="text-xs font-semibold text-muted-foreground px-2 mb-1">
          Favoriten
        </p>
        <div className="space-y-0.5">
          <BookmarkButton label="Wurzel" path="/" onNavigate={onNavigate} />
          <BookmarkButton label="Home" path="/home" onNavigate={onNavigate} />
          <BookmarkButton label="Root" path="/root" onNavigate={onNavigate} />
          <BookmarkButton label="Tank" path="/tank" onNavigate={onNavigate} />
          <BookmarkButton
            label="Var/Log"
            path="/var/log"
            onNavigate={onNavigate}
          />
        </div>
      </div>

      {/* Directory Tree */}
      <div className="space-y-0.5">
        <p className="text-xs font-semibold text-muted-foreground px-2">
          Verzeichnisse
        </p>
        <div
          className="space-y-0.5"
          style={{ maxHeight: "calc(100vh - 14rem)", overflowY: "auto" }}
        >
          {rootChildren.length > 0 ? (
            rootChildren.map((node) => {
              const fullPath = basePath === "/" ? "/" + node.path : basePath + "/" + node.path
              return (
                <TreeNode
                  key={node.path}
                  node={node}
                  depth={0}
                  isActive={currentPath === fullPath}
                  isExpanded={expanded.has(node.path)}
                  isLoading={loading.has(node.path)}
                  subdirs={childrenMap.get(node.path) || []}
                  basePath={basePath}
                  onExpand={fetchChildren}
                  onNavigate={onNavigate}
                />
              )
            })
          ) : (
            <p className="text-xs text-muted-foreground px-2 py-1">
              {loading.has(rootPath) ? "Laden..." : "Keine Verzeichnisse"}
            </p>
          )}
        </div>
      </div>
    </div>
  )
}
