import { useState, useRef } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import IconButton from "@mui/material/IconButton";
import CircularProgress from "@mui/material/CircularProgress";
import { projectFilesOptions } from "../lib/queries/projects";
import { useAlert } from "../context/AlertContext";
import {
  Card,
  Button,
  TextField,
  ConfirmDialog,
  EmptyState,
  LoadingState,
  DataTable,
  type DataColumn,
} from "../ui";
import apiFetch from "../utils/api";

const API_BASE = "/api/admin";

interface ProjectFileManagerProps {
  projectId: number;
  projectNumber: string | null;
  hasPermission: (perm: string) => boolean;
  hasNasFolder: boolean;
}

interface FileItem {
  name: string;
  type: "file" | "folder";
  size?: number;
  size_formatted?: string;
  modified?: string;
  extension?: string;
  item_count?: number;
  is_symlink?: boolean;
  link_target?: string;
}

function getFileIcon(type: string, extension?: string) {
  if (type === "folder") {
    return (
      <svg
        width="18"
        height="18"
        viewBox="0 0 24 24"
        fill="none"
        stroke="#e6a817"
        strokeWidth="1.5"
      >
        <path
          d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"
          fill="rgba(230, 168, 23, 0.15)"
        />
      </svg>
    );
  }

  const ext = (extension || "").toLowerCase();
  const iconMap: Record<string, { color: string; path: string }> = {
    pdf: {
      color: "#e74c3c",
      path: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z",
    },
    doc: {
      color: "#3498db",
      path: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z",
    },
    docx: {
      color: "#3498db",
      path: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z",
    },
    xls: {
      color: "#27ae60",
      path: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z",
    },
    xlsx: {
      color: "#27ae60",
      path: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z",
    },
    ppt: {
      color: "#e67e22",
      path: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z",
    },
    pptx: {
      color: "#e67e22",
      path: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z",
    },
    jpg: {
      color: "#3498db",
      path: "M19 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z",
    },
    jpeg: {
      color: "#3498db",
      path: "M19 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z",
    },
    png: {
      color: "#3498db",
      path: "M19 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z",
    },
    gif: {
      color: "#3498db",
      path: "M19 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z",
    },
    zip: {
      color: "#e67e22",
      path: "M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z",
    },
    rar: {
      color: "#e67e22",
      path: "M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z",
    },
    "7z": {
      color: "#e67e22",
      path: "M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z",
    },
    dwg: {
      color: "#8e44ad",
      path: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z",
    },
    dxf: {
      color: "#8e44ad",
      path: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z",
    },
    step: {
      color: "#8e44ad",
      path: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z",
    },
    stp: {
      color: "#8e44ad",
      path: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z",
    },
  };

  const cfg = iconMap[ext] || {
    color: "var(--mui-palette-text-secondary)",
    path: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z",
  };

  return (
    <svg
      width="18"
      height="18"
      viewBox="0 0 24 24"
      fill="none"
      stroke={cfg.color}
      strokeWidth="1.5"
    >
      <path d={cfg.path} />
      <polyline points="14 2 14 8 20 8" />
    </svg>
  );
}

function SymlinkBadge({ target }: { target?: string }) {
  return (
    <Box
      component="span"
      title={target || "Odkaz"}
      sx={{
        display: "inline-flex",
        alignItems: "center",
        ml: 0.5,
        color: "text.secondary",
      }}
    >
      <svg
        width="12"
        height="12"
        viewBox="0 0 24 24"
        fill="none"
        stroke="currentColor"
        strokeWidth="2"
      >
        <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" />
        <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />
      </svg>
    </Box>
  );
}

function FileNameCell({
  item,
  onFolderClick,
}: {
  item: FileItem;
  onFolderClick: (name: string) => void;
}) {
  if (item.type === "folder") {
    return (
      <Box
        component="span"
        sx={{ display: "inline-flex", alignItems: "center", gap: 0.5 }}
      >
        <Box
          component="button"
          type="button"
          onClick={() => onFolderClick(item.name)}
          sx={{
            background: "none",
            border: "none",
            p: 0,
            font: "inherit",
            color: "primary.main",
            cursor: "pointer",
            textAlign: "left",
            "&:hover": { textDecoration: "underline" },
          }}
        >
          {item.name}
        </Box>
        {item.is_symlink && <SymlinkBadge target={item.link_target} />}
        {item.item_count !== undefined && (
          <Box
            component="span"
            sx={{
              fontSize: ".7rem",
              color: "text.secondary",
              bgcolor: "action.hover",
              borderRadius: 1,
              px: 0.75,
            }}
          >
            {item.item_count}
          </Box>
        )}
      </Box>
    );
  }
  return (
    <Box
      component="span"
      sx={{ display: "inline-flex", alignItems: "center", gap: 0.5 }}
    >
      <Box component="span">{item.name}</Box>
      {item.is_symlink && <SymlinkBadge target={item.link_target} />}
    </Box>
  );
}

export default function ProjectFileManager({
  projectId,
  projectNumber,
  hasPermission,
  hasNasFolder,
}: ProjectFileManagerProps) {
  const alert = useAlert();
  const queryClient = useQueryClient();
  const fileInputRef = useRef<HTMLInputElement>(null);
  const isCancelling = useRef(false);
  // dragenter/dragleave fire on every child boundary crossed during a drag.
  // Counting enter/leave events keeps the overlay steady instead of flickering
  // as the cursor moves over nested elements; the overlay only hides when the
  // depth returns to 0 (the cursor truly left the drop zone).
  const dragDepth = useRef(0);

  const [currentPath, setCurrentPath] = useState("");

  const [dragOver, setDragOver] = useState(false);
  const [uploading, setUploading] = useState(false);

  const [newFolderMode, setNewFolderMode] = useState(false);
  const [newFolderName, setNewFolderName] = useState("");
  const [creatingFolder, setCreatingFolder] = useState(false);

  const [renamingItem, setRenamingItem] = useState<string | null>(null);
  const [renameValue, setRenameValue] = useState("");

  const [deleteTarget, setDeleteTarget] = useState<FileItem | null>(null);
  const [deleting, setDeleting] = useState(false);

  const canManage = hasPermission("projects.files");

  const {
    data: filesData,
    isPending: filesLoading,
    error: filesError,
  } = useQuery(projectFilesOptions(projectId, currentPath));
  const items = filesData?.items ?? [];
  const breadcrumb = filesData?.breadcrumb ?? [""];
  const fullPath = filesData?.full_path ?? "";
  const errorMessage = filesError
    ? filesError.message || "Nepodařilo se načíst soubory"
    : null;

  const navigateTo = (path: string) => {
    setNewFolderMode(false);
    setRenamingItem(null);
    setCurrentPath(path);
  };

  const handleBreadcrumbClick = (index: number) => {
    if (index === 0) {
      navigateTo("");
      return;
    }
    const path = breadcrumb.slice(1, index + 1).join("/");
    navigateTo(path);
  };

  const handleFolderClick = (folderName: string) => {
    const path = currentPath ? `${currentPath}/${folderName}` : folderName;
    navigateTo(path);
  };

  const handleUpload = async (files: FileList | null) => {
    if (!files || files.length === 0) return;

    setUploading(true);
    let successCount = 0;
    let errorMsg: string | null = null;

    for (const file of Array.from(files)) {
      const formData = new FormData();
      formData.append("file", file);

      const params = new URLSearchParams({
        action: "upload",
        project_id: String(projectId),
      });
      if (currentPath) {
        params.set("path", currentPath);
      }

      try {
        const res = await apiFetch(
          `${API_BASE}/project-files/upload?${params}`,
          {
            method: "POST",
            body: formData,
          },
        );
        const data = await res.json();
        if (data.success) {
          successCount++;
        } else {
          errorMsg = data.error || "Chyba při nahrávání";
        }
      } catch (e) {
        console.error("ProjectFileManager: upload failed", e);
        errorMsg = "Chyba připojení";
      }
    }

    setUploading(false);

    if (successCount > 0) {
      const msg =
        successCount === 1
          ? "Soubor byl nahrán"
          : `Nahráno ${successCount} souborů`;
      alert.success(msg);
      queryClient.invalidateQueries({
        queryKey: ["projects", String(projectId), "files"],
      });
    }
    if (errorMsg) {
      alert.error(errorMsg);
    }
  };

  const handleFileInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    handleUpload(e.target.files);
    e.target.value = "";
  };

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    dragDepth.current = 0;
    setDragOver(false);
    if (!canManage) return;
    handleUpload(e.dataTransfer.files);
  };

  const handleDragEnter = (e: React.DragEvent) => {
    e.preventDefault();
    if (!canManage) return;
    dragDepth.current += 1;
    setDragOver(true);
  };

  const handleDragOver = (e: React.DragEvent) => {
    // Must preventDefault on dragover too, otherwise the browser rejects the
    // drop. The overlay state is driven by enter/leave (see dragDepth).
    e.preventDefault();
  };

  const handleDragLeave = (e: React.DragEvent) => {
    e.preventDefault();
    if (!canManage) return;
    dragDepth.current = Math.max(0, dragDepth.current - 1);
    if (dragDepth.current === 0) {
      setDragOver(false);
    }
  };

  const handleCreateFolder = async () => {
    const name = newFolderName.trim();
    if (!name) return;

    setCreatingFolder(true);
    try {
      const params = new URLSearchParams({
        action: "create_folder",
        project_id: String(projectId),
      });
      const res = await apiFetch(`${API_BASE}/project-files?${params}`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ path: currentPath, folder_name: name }),
      });
      const data = await res.json();
      if (data.success) {
        alert.success("Složka byla vytvořena");
        setNewFolderMode(false);
        setNewFolderName("");
        queryClient.invalidateQueries({
          queryKey: ["projects", String(projectId), "files"],
        });
      } else {
        alert.error(data.error || "Nepodařilo se vytvořit složku");
      }
    } catch (e) {
      console.error("ProjectFileManager: create folder failed", e);
      alert.error("Chyba připojení");
    } finally {
      setCreatingFolder(false);
    }
  };

  const handleDownload = async (item: FileItem) => {
    const filePath = currentPath ? `${currentPath}/${item.name}` : item.name;
    const params = new URLSearchParams({
      action: "download",
      project_id: String(projectId),
      path: filePath,
    });
    try {
      const res = await apiFetch(`${API_BASE}/project-files?${params}`);
      if (!res.ok) {
        const err = await res.json().catch(() => null);
        alert.error(err?.error || "Chyba při stahování");
        return;
      }
      const blob = await res.blob();
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = item.name;
      document.body.appendChild(a);
      a.click();
      a.remove();
      URL.revokeObjectURL(url);
    } catch (e) {
      console.error("ProjectFileManager: download failed", e);
      alert.error("Chyba připojení");
    }
  };

  const handleDelete = async () => {
    if (!deleteTarget) return;

    setDeleting(true);
    const filePath = currentPath
      ? `${currentPath}/${deleteTarget.name}`
      : deleteTarget.name;
    try {
      const params = new URLSearchParams({
        project_id: String(projectId),
        path: filePath,
      });
      const res = await apiFetch(`${API_BASE}/project-files?${params}`, {
        method: "DELETE",
      });
      const data = await res.json();
      if (data.success) {
        alert.success(
          deleteTarget.type === "folder"
            ? "Složka byla smazána"
            : "Soubor byl smazán",
        );
        queryClient.invalidateQueries({
          queryKey: ["projects", String(projectId), "files"],
        });
      } else {
        alert.error(data.error || "Nepodařilo se smazat");
      }
    } catch (e) {
      console.error("ProjectFileManager: delete failed", e);
      alert.error("Chyba připojení");
    } finally {
      setDeleting(false);
      setDeleteTarget(null);
    }
  };

  const handleRename = async (item: FileItem) => {
    const newName = renameValue.trim();
    if (!newName || newName === item.name) {
      setRenamingItem(null);
      return;
    }

    const fromPath = currentPath ? `${currentPath}/${item.name}` : item.name;
    const toPath = currentPath ? `${currentPath}/${newName}` : newName;

    try {
      const params = new URLSearchParams({
        action: "move",
        project_id: String(projectId),
      });
      const res = await apiFetch(`${API_BASE}/project-files?${params}`, {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ from_path: fromPath, to_path: toPath }),
      });
      const data = await res.json();
      if (data.success) {
        alert.success("Přejmenováno");
        queryClient.invalidateQueries({
          queryKey: ["projects", String(projectId), "files"],
        });
      } else {
        alert.error(data.error || "Nepodařilo se přejmenovat");
      }
    } catch (e) {
      console.error("ProjectFileManager: rename failed", e);
      alert.error("Chyba připojení");
    } finally {
      setRenamingItem(null);
    }
  };

  const startRename = (item: FileItem) => {
    setRenamingItem(item.name);
    setRenameValue(item.name);
  };

  if (filesLoading && items.length === 0 && !errorMessage) {
    return <LoadingState />;
  }

  if (errorMessage) {
    return (
      <Card>
        <Typography variant="h6" sx={{ mb: 2 }}>
          Soubory
        </Typography>
        <EmptyState
          icon={
            <svg
              width="32"
              height="32"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="1.5"
            >
              <circle cx="12" cy="12" r="10" />
              <line x1="12" y1="8" x2="12" y2="12" />
              <line x1="12" y1="16" x2="12.01" y2="16" />
            </svg>
          }
          title={errorMessage}
        />
      </Card>
    );
  }

  const columns: DataColumn<FileItem>[] = [
    {
      key: "icon",
      header: "",
      width: 30,
      align: "left",
      render: (item) => (
        <Box sx={{ textAlign: "center" }}>
          {getFileIcon(item.type, item.extension)}
        </Box>
      ),
    },
    {
      key: "name",
      header: "Název",
      render: (item) =>
        renamingItem === item.name ? (
          <TextField
            value={renameValue}
            onChange={(e) => setRenameValue(e.target.value)}
            autoFocus
            sx={{ maxWidth: 300 }}
            onKeyDown={(e) => {
              if (e.key === "Enter") {
                e.preventDefault();
                handleRename(item);
              }
              if (e.key === "Escape") {
                e.preventDefault();
                isCancelling.current = true;
                setRenamingItem(null);
                setRenameValue(item.name);
                setTimeout(() => {
                  isCancelling.current = false;
                }, 0);
              }
            }}
            onBlur={() => {
              if (isCancelling.current) {
                return;
              }
              handleRename(item);
            }}
          />
        ) : (
          <FileNameCell item={item} onFolderClick={handleFolderClick} />
        ),
    },
    {
      key: "size",
      header: "Velikost",
      width: 90,
      render: (item) => (
        <Typography variant="caption" color="text.secondary">
          {item.type === "file" ? item.size_formatted : "—"}
        </Typography>
      ),
    },
    {
      key: "modified",
      header: "Změněno",
      width: 120,
      render: (item) => (
        <Typography variant="caption" color="text.secondary">
          {item.modified || "—"}
        </Typography>
      ),
    },
    ...(canManage
      ? [
          {
            key: "actions",
            header: "Akce",
            width: 100,
            align: "right" as const,
            render: (item: FileItem) => (
              <Box
                sx={{
                  display: "flex",
                  gap: 0.5,
                  justifyContent: "flex-end",
                }}
              >
                {item.type === "file" && (
                  <IconButton
                    size="small"
                    title="Stáhnout"
                    aria-label="Stáhnout"
                    onClick={() => handleDownload(item)}
                  >
                    <svg
                      width="14"
                      height="14"
                      viewBox="0 0 24 24"
                      fill="none"
                      stroke="currentColor"
                      strokeWidth="2"
                    >
                      <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
                      <polyline points="7 10 12 15 17 10" />
                      <line x1="12" y1="15" x2="12" y2="3" />
                    </svg>
                  </IconButton>
                )}
                <IconButton
                  size="small"
                  title="Přejmenovat"
                  aria-label="Přejmenovat"
                  onClick={() => startRename(item)}
                >
                  <svg
                    width="14"
                    height="14"
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    strokeWidth="2"
                  >
                    <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
                    <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
                  </svg>
                </IconButton>
                <IconButton
                  size="small"
                  color="error"
                  title="Smazat"
                  aria-label="Smazat"
                  onClick={() => setDeleteTarget(item)}
                >
                  <svg
                    width="14"
                    height="14"
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    strokeWidth="2"
                  >
                    <polyline points="3 6 5 6 21 6" />
                    <path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" />
                    <path d="M10 11v6M14 11v6" />
                  </svg>
                </IconButton>
              </Box>
            ),
          },
        ]
      : []),
  ];

  return (
    <Card>
      <Typography variant="h6" sx={{ mb: 2 }}>
        Soubory
      </Typography>

      {/* Toolbar */}
      <Box
        sx={{
          display: "flex",
          alignItems: "center",
          flexWrap: "wrap",
          gap: 1,
          mb: 2,
        }}
      >
        <Box
          sx={{
            display: "flex",
            alignItems: "center",
            flexWrap: "wrap",
            gap: 0.25,
          }}
        >
          {breadcrumb.map((segment, i) => (
            <Box
              component="span"
              key={i}
              sx={{ display: "inline-flex", alignItems: "center" }}
            >
              {i > 0 && (
                <Box component="span" sx={{ mx: 0.25, color: "text.disabled" }}>
                  /
                </Box>
              )}
              <Box
                component="button"
                type="button"
                onClick={() => handleBreadcrumbClick(i)}
                sx={{
                  background: "none",
                  border: "none",
                  p: 0,
                  font: "inherit",
                  cursor: "pointer",
                  color:
                    i === breadcrumb.length - 1
                      ? "text.primary"
                      : "primary.main",
                  fontWeight: i === breadcrumb.length - 1 ? 600 : 400,
                  "&:hover": { textDecoration: "underline" },
                }}
              >
                {i === 0 ? projectNumber : segment}
              </Box>
            </Box>
          ))}
        </Box>

        {fullPath && (
          <Typography
            variant="caption"
            color="text.secondary"
            title={fullPath}
            sx={{
              maxWidth: 320,
              overflow: "hidden",
              textOverflow: "ellipsis",
              whiteSpace: "nowrap",
            }}
          >
            {fullPath}
          </Typography>
        )}

        {canManage && (
          <Box sx={{ display: "flex", gap: 1, ml: "auto" }}>
            <Button
              size="small"
              variant="outlined"
              color="inherit"
              onClick={() => {
                setNewFolderMode(!newFolderMode);
                setNewFolderName("");
              }}
              startIcon={
                <svg
                  width="14"
                  height="14"
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth="2"
                >
                  <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" />
                  <line x1="12" y1="11" x2="12" y2="17" />
                  <line x1="9" y1="14" x2="15" y2="14" />
                </svg>
              }
            >
              Složka
            </Button>
            <Button
              size="small"
              onClick={() => fileInputRef.current?.click()}
              disabled={uploading}
              startIcon={
                uploading ? (
                  <CircularProgress size={14} color="inherit" />
                ) : (
                  <svg
                    width="14"
                    height="14"
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    strokeWidth="2"
                  >
                    <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
                    <polyline points="17 8 12 3 7 8" />
                    <line x1="12" y1="3" x2="12" y2="15" />
                  </svg>
                )
              }
            >
              {uploading ? "Nahrávání..." : "Nahrát"}
            </Button>
            <input
              ref={fileInputRef}
              type="file"
              multiple
              style={{ display: "none" }}
              onChange={handleFileInputChange}
            />
          </Box>
        )}
      </Box>

      {/* New folder input */}
      {newFolderMode && (
        <Box
          sx={{
            display: "flex",
            alignItems: "center",
            gap: 1,
            mb: 2,
          }}
        >
          <TextField
            value={newFolderName}
            onChange={(e) => setNewFolderName(e.target.value)}
            placeholder="Název složky..."
            autoFocus
            sx={{ maxWidth: 320 }}
            onKeyDown={(e) => {
              if (e.key === "Enter") handleCreateFolder();
              if (e.key === "Escape") {
                setNewFolderMode(false);
                setNewFolderName("");
              }
            }}
          />
          <Button
            size="small"
            onClick={handleCreateFolder}
            disabled={creatingFolder || !newFolderName.trim()}
          >
            {creatingFolder ? (
              <CircularProgress size={14} color="inherit" />
            ) : (
              "Vytvořit"
            )}
          </Button>
          <Button
            size="small"
            variant="outlined"
            color="inherit"
            onClick={() => {
              setNewFolderMode(false);
              setNewFolderName("");
            }}
          >
            Zrušit
          </Button>
        </Box>
      )}

      {/* Drop zone + table */}
      <Box
        onDrop={handleDrop}
        onDragEnter={handleDragEnter}
        onDragOver={handleDragOver}
        onDragLeave={handleDragLeave}
        sx={{
          position: "relative",
          borderRadius: 2,
          ...(dragOver
            ? {
                outline: "2px dashed",
                outlineColor: "primary.main",
                outlineOffset: -4,
              }
            : {}),
        }}
      >
        {dragOver && (
          <Box
            sx={{
              position: "absolute",
              inset: 0,
              zIndex: 2,
              display: "flex",
              flexDirection: "column",
              alignItems: "center",
              justifyContent: "center",
              gap: 1,
              bgcolor: "action.hover",
              color: "primary.main",
              borderRadius: 2,
              pointerEvents: "none",
            }}
          >
            <svg
              width="32"
              height="32"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="1.5"
            >
              <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
              <polyline points="17 8 12 3 7 8" />
              <line x1="12" y1="3" x2="12" y2="15" />
            </svg>
            <span>Přetáhněte soubory sem</span>
          </Box>
        )}

        {items.length === 0 && !filesLoading ? (
          <EmptyState
            icon={
              <svg
                width="32"
                height="32"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                strokeWidth="1.5"
              >
                <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" />
              </svg>
            }
            title={
              hasNasFolder
                ? "Složka je prázdná"
                : "Složka projektu zatím neexistuje"
            }
            description={
              canManage && !hasNasFolder
                ? "Nahrání souboru ji automaticky vytvoří"
                : undefined
            }
          />
        ) : (
          <DataTable
            columns={columns}
            rows={items}
            rowKey={(item) => item.name}
          />
        )}
      </Box>

      <ConfirmDialog
        isOpen={deleteTarget !== null}
        onClose={() => setDeleteTarget(null)}
        onConfirm={handleDelete}
        title={
          deleteTarget?.type === "folder" ? "Smazat složku" : "Smazat soubor"
        }
        message={`Opravdu chcete smazat "${deleteTarget?.name}"?${deleteTarget?.type === "folder" ? " Složka bude smazána včetně veškerého obsahu." : ""}`}
        confirmText="Smazat"
        cancelText="Zrušit"
        confirmVariant="danger"
        loading={deleting}
      />
    </Card>
  );
}
