import React, { useState, useCallback, useRef, useEffect } from "react";
import Editor from "@monaco-editor/react";
import {
  FiFile,
  FiFolder,
  FiEdit3,
  FiTrash2,
  FiChevronRight,
  FiChevronDown,
  FiSearch,
  FiGitBranch,
  FiCheckCircle,
  FiMinus,
  FiAlertCircle,
} from "react-icons/fi";
import { MdClose, MdAdd } from "react-icons/md";
import { GoFile, GoTrash, GoKebabHorizontal } from "react-icons/go";

/* eslint react-refresh/only-export-components: "off" */

export interface FileNode {
  name: string;
  type: "file" | "folder";
  content?: string;
  children?: FileNode[];
  path?: string;
}

export const initialFiles: FileNode = {
  name: "my-project",
  type: "folder",
  children: [
    {
      name: "src",
      type: "folder",
      children: [
        {
          name: "main.py",
          type: "file",
          content:
            'print("Hello, World!")\n\ndef main():\n    print("Welcome!")\n\nif __name__ == "__main__":\n    main()',
        },
        {
          name: "utils.py",
          type: "file",
          content: "def helper():\n    return 42",
        },
      ],
    },
    {
      name: "README.md",
      type: "file",
      content: "# My Project\n\nWelcome!",
    },
  ],
};

const addPaths = (node: FileNode, parentPath: string = ""): FileNode => {
  const currentPath = parentPath ? `${parentPath}/${node.name}` : node.name;
  const newNode = { ...node, path: currentPath };
  if (newNode.children) {
    newNode.children = newNode.children.map((child) =>
      addPaths(child, currentPath),
    );
  }
  return newNode;
};

const getAllFolderPaths = (node: FileNode): string[] => {
  let paths: string[] = [];
  if (node.type === "folder") {
    paths.push(node.path || node.name);
    if (node.children) {
      node.children.forEach((child) => {
        paths = [...paths, ...getAllFolderPaths(child)];
      });
    }
  }
  return paths;
};

const findNode = (node: FileNode, path: string): FileNode | null => {
  if (node.path === path) return node;
  if (node.children) {
    for (const child of node.children) {
      const found = findNode(child, path);
      if (found) return found;
    }
  }
  return null;
};

const deleteNode = (node: FileNode, path: string): FileNode | null => {
  if (node.path === path) return null;

  if (node.children) {
    const filtered = node.children.filter((child) => child.path !== path);
    const mapped = filtered
      .map((child) => deleteNode(child, path))
      .filter((child): child is FileNode => child !== null);
    return { ...node, children: mapped };
  }
  return node;
};

const addNode = (
  node: FileNode,
  parentPath: string,
  newNode: FileNode,
): FileNode => {
  if (node.path === parentPath) {
    const newPath = addPaths(newNode, node.path);
    return { ...node, children: [...(node.children || []), newPath] };
  }
  if (node.children) {
    return {
      ...node,
      children: node.children.map((child) =>
        addNode(child, parentPath, newNode),
      ),
    };
  }
  return node;
};

const renameNode = (
  node: FileNode,
  oldPath: string,
  newName: string,
): FileNode | null => {
  if (node.path === oldPath) {
    const pathParts = node.path?.split("/") || [];
    pathParts[pathParts.length - 1] = newName;
    const newPath = pathParts.join("/");
    const renamedNode = { ...node, name: newName, path: newPath };

    if (renamedNode.children) {
      renamedNode.children = renamedNode.children.map((child) => {
        const oldChildPath = child.path || "";
        const newChildPath = oldChildPath.replace(oldPath, newPath);
        return (
          renameNode(
            child,
            oldChildPath,
            newChildPath.split("/").pop() || "",
          ) || child
        );
      });
    }
    return renamedNode;
  }

  if (node.children) {
    return {
      ...node,
      children: node.children.map(
        (child) => renameNode(child, oldPath, newName) || child,
      ),
    };
  }
  return node;
};

const ContextMenu: React.FC<{
  x: number;
  y: number;
  node: FileNode | null;
  onClose: () => void;
  onNewFile: () => void;
  onNewFolder: () => void;
  onRename: () => void;
  onDelete: () => void;
}> = ({ x, y, node, onClose, onNewFile, onNewFolder, onRename, onDelete }) => {
  useEffect(() => {
    const handleClick = () => onClose();
    document.addEventListener("click", handleClick);
    return () => document.removeEventListener("click", handleClick);
  }, [onClose]);

  return (
    <div
      style={{
        position: "fixed",
        top: y,
        left: x,
        backgroundColor: "#252526",
        border: "1px solid #3e3e42",
        borderRadius: "6px",
        boxShadow: "0 4px 12px rgba(0,0,0,0.4)",
        zIndex: 1000,
        minWidth: "180px",
        overflow: "hidden",
      }}
    >
      <MenuItem onClick={onNewFile}>
        <FiFile /> New File
      </MenuItem>
      <MenuItem onClick={onNewFolder}>
        <FiFolder /> New Folder
      </MenuItem>
      {node && (
        <>
          <div
            style={{
              height: "1px",
              backgroundColor: "#3e3e42",
              margin: "4px 0",
            }}
          />
          <MenuItem onClick={onRename}>
            <FiEdit3 /> Rename
          </MenuItem>
          <MenuItem onClick={onDelete} danger>
            <FiTrash2 /> Delete
          </MenuItem>
        </>
      )}
    </div>
  );
};

const MenuItem: React.FC<{
  onClick: () => void;
  danger?: boolean;
  children: React.ReactNode;
}> = ({ onClick, danger, children }) => (
  <div
    onClick={onClick}
    style={{
      padding: "8px 16px",
      cursor: "pointer",
      color: danger ? "#f48771" : "#cccccc",
      fontSize: "13px",
      transition: "background-color 0.1s",
      display: "flex",
      alignItems: "center",
      gap: "10px",
    }}
    onMouseEnter={(e) => {
      e.currentTarget.style.backgroundColor = "#2a2d2e";
    }}
    onMouseLeave={(e) => {
      e.currentTarget.style.backgroundColor = "transparent";
    }}
  >
    {children}
  </div>
);

const InputDialog: React.FC<{
  title: string;
  initialValue?: string;
  onConfirm: (value: string) => void;
  onCancel: () => void;
}> = ({ title, initialValue = "", onConfirm, onCancel }) => {
  const [value, setValue] = useState(initialValue);
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    inputRef.current?.focus();
    inputRef.current?.select();
  }, []);

  return (
    <div
      style={{
        position: "fixed",
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        backgroundColor: "rgba(0,0,0,0.6)",
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        zIndex: 2000,
      }}
      onClick={onCancel}
    >
      <div
        style={{
          backgroundColor: "#2d2d30",
          borderRadius: "8px",
          padding: "24px",
          minWidth: "320px",
          border: "1px solid #3e3e42",
          boxShadow: "0 8px 24px rgba(0,0,0,0.4)",
        }}
        onClick={(e) => e.stopPropagation()}
      >
        <h3
          style={{
            margin: "0 0 8px 0",
            color: "#fff",
            fontSize: "16px",
            fontWeight: 500,
          }}
        >
          {title}
        </h3>
        <p style={{ margin: "0 0 16px 0", color: "#858585", fontSize: "12px" }}>
          Enter a new name
        </p>
        <input
          ref={inputRef}
          type="text"
          value={value}
          onChange={(e) => setValue(e.target.value)}
          onKeyDown={(e) =>
            e.key === "Enter" && value.trim() && onConfirm(value.trim())
          }
          style={{
            width: "100%",
            padding: "10px",
            backgroundColor: "#3c3c3c",
            border: "1px solid #3e3e42",
            borderRadius: "6px",
            color: "#ccc",
            fontSize: "14px",
            marginBottom: "20px",
            outline: "none",
          }}
        />
        <div
          style={{ display: "flex", gap: "12px", justifyContent: "flex-end" }}
        >
          <button
            onClick={onCancel}
            style={{
              padding: "6px 16px",
              backgroundColor: "transparent",
              border: "1px solid #0e639c",
              borderRadius: "4px",
              color: "#0e639c",
              cursor: "pointer",
              fontSize: "12px",
            }}
          >
            Cancel
          </button>
          <button
            onClick={() => value.trim() && onConfirm(value.trim())}
            style={{
              padding: "6px 16px",
              backgroundColor: "#0e639c",
              border: "none",
              borderRadius: "4px",
              color: "#fff",
              cursor: "pointer",
              fontSize: "12px",
            }}
          >
            OK
          </button>
        </div>
      </div>
    </div>
  );
};

const filterTree = (node: FileNode, query: string): FileNode | null => {
  if (!query) return node;
  const lowerQuery = query.toLowerCase();

  if (node.type === "file") {
    if (node.name.toLowerCase().includes(lowerQuery)) return node;
    return null;
  }

  if (node.children) {
    const filteredChildren = node.children
      .map((child) => filterTree(child, query))
      .filter((child): child is FileNode => child !== null);

    if (filteredChildren.length > 0) {
      return { ...node, children: filteredChildren };
    }
  }

  if (node.name.toLowerCase().includes(lowerQuery)) return node;
  return null;
};

const collectPathsToExpand = (node: FileNode, query: string): Set<string> => {
  const paths = new Set<string>();
  if (!query) return paths;

  const lowerQuery = query.toLowerCase();

  const search = (n: FileNode, currentPath: string) => {
    if (n.name.toLowerCase().includes(lowerQuery)) {
      const pathParts = currentPath.split("/");
      for (let i = 1; i < pathParts.length; i++) {
        paths.add(pathParts.slice(0, i).join("/"));
      }
    }
    if (n.children) {
      n.children.forEach((child) => {
        const childPath = child.path || `${currentPath}/${child.name}`;
        search(child, childPath);
      });
    }
  };

  search(node, node.path || node.name);
  return paths;
};

const FileTreeItem: React.FC<{
  node: FileNode;
  level: number;
  onFileSelect: (node: FileNode) => void;
  selectedFile: string | null;
  onContextMenu: (e: React.MouseEvent, node: FileNode) => void;
  expandedFolders: Set<string>;
  onToggleFolder: (path: string) => void;
  onDelete: (node: FileNode) => void;
  isRoot?: boolean;
  searchQuery?: string;
}> = ({
  node,
  level,
  onFileSelect,
  selectedFile,
  onContextMenu,
  expandedFolders,
  onToggleFolder,
  onDelete,
  isRoot,
  searchQuery,
}) => {
  const isFolder = node.type === "folder";
  const isSelected = selectedFile === node.path && !isFolder;
  const isExpanded = expandedFolders.has(node.path || node.name);
  const [hovered, setHovered] = useState(false);

  const handleClick = () => {
    if (isFolder) {
      onToggleFolder(node.path || node.name);
    } else {
      onFileSelect(node);
    }
  };

  const handleDelete = (e: React.MouseEvent) => {
    e.stopPropagation();
    onDelete(node);
  };

  const highlightText = (text: string, query: string) => {
    if (!query) return text;
    const idx = text.toLowerCase().indexOf(query.toLowerCase());
    if (idx === -1) return text;
    return (
      <>
        {text.slice(0, idx)}
        <span style={{ backgroundColor: "#613214", color: "#f9f9a4" }}>
          {text.slice(idx, idx + query.length)}
        </span>
        {text.slice(idx + query.length)}
      </>
    );
  };

  return (
    <div>
      <div
        onClick={handleClick}
        onContextMenu={(e) => onContextMenu(e, node)}
        onMouseEnter={() => setHovered(true)}
        onMouseLeave={() => setHovered(false)}
        style={{
          paddingLeft: isRoot ? "8px" : `${level * 16 + 8}px`,
          paddingTop: "4px",
          paddingBottom: "4px",
          cursor: "pointer",
          display: "flex",
          alignItems: "center",
          gap: "6px",
          backgroundColor: isSelected ? "#094771" : "transparent",
          color: isSelected ? "#fff" : "#cccccc",
          fontSize: "13px",
          transition: "background-color 0.1s",
          userSelect: "none",
          minHeight: "28px",
        }}
      >
        <span
          style={{
            fontSize: "14px",
            width: "16px",
            textAlign: "center",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            flexShrink: 0,
          }}
        >
          {isFolder ? (
            isExpanded ? (
              <FiChevronDown />
            ) : (
              <FiChevronRight />
            )
          ) : (
            <GoFile />
          )}
        </span>
        <span
          style={{
            flex: 1,
            overflow: "hidden",
            textOverflow: "ellipsis",
            whiteSpace: "nowrap",
          }}
        >
          {searchQuery ? highlightText(node.name, searchQuery) : node.name}
        </span>
        {hovered && !isRoot && (
          <button
            onClick={handleDelete}
            title={`Delete ${node.name}`}
            style={{
              background: "none",
              border: "none",
              color: "#858585",
              cursor: "pointer",
              padding: "2px",
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              borderRadius: "3px",
              flexShrink: 0,
              width: "20px",
              height: "20px",
            }}
            onMouseEnter={(e) => {
              e.currentTarget.style.color = "#f48771";
              e.currentTarget.style.backgroundColor = "#3e3e42";
            }}
            onMouseLeave={(e) => {
              e.currentTarget.style.color = "#858585";
              e.currentTarget.style.backgroundColor = "transparent";
            }}
          >
            <FiTrash2 size={13} />
          </button>
        )}
      </div>
      {isFolder && isExpanded && node.children && (
        <div>
          {node.children.map((child, idx) => (
            <FileTreeItem
              key={idx}
              node={child}
              level={level + 1}
              onFileSelect={onFileSelect}
              selectedFile={selectedFile}
              onContextMenu={onContextMenu}
              expandedFolders={expandedFolders}
              onToggleFolder={onToggleFolder}
              onDelete={onDelete}
              searchQuery={searchQuery}
            />
          ))}
        </div>
      )}
    </div>
  );
};

const TabBar: React.FC<{
  openFiles: FileNode[];
  activeFile: FileNode | null;
  onSelectFile: (file: FileNode) => void;
  onCloseFile: (file: FileNode) => void;
  onCloseAll: () => void;
  onCloseOthers: (file: FileNode) => void;
}> = ({
  openFiles,
  activeFile,
  onSelectFile,
  onCloseFile,
  onCloseAll,
  onCloseOthers,
}) => {
  const [showContextMenu, setShowContextMenu] = useState<{
    x: number;
    y: number;
    file: FileNode;
  } | null>(null);

  const handleContextMenu = (e: React.MouseEvent, file: FileNode) => {
    e.preventDefault();
    setShowContextMenu({ x: e.clientX, y: e.clientY, file });
  };

  return (
    <>
      <div
        style={{
          display: "flex",
          alignItems: "center",
          backgroundColor: "#1e1e1e",
          borderBottom: "1px solid #3e3e42",
          overflowX: "auto",
          minHeight: "40px",
        }}
      >
        <div
          style={{
            display: "flex",
            padding: "0 12px",
            gap: "8px",
            borderRight: "1px solid #3e3e42",
            height: "100%",
            alignItems: "center",
          }}
        >
          <button
            onClick={onCloseAll}
            style={{
              background: "transparent",
              border: "none",
              color: "#cccccc",
              cursor: "pointer",
              fontSize: "14px",
              padding: "6px 8px",
              borderRadius: "4px",
              display: "flex",
              alignItems: "center",
              gap: "6px",
              transition: "all 0.1s",
            }}
            onMouseEnter={(e) => {
              e.currentTarget.style.backgroundColor = "#2a2d2e";
            }}
            onMouseLeave={(e) => {
              e.currentTarget.style.backgroundColor = "transparent";
            }}
            title="Close All"
          >
            <MdClose size={14} />
            <span style={{ fontSize: "11px" }}>Close All</span>
          </button>
        </div>
        {openFiles.map((file) => (
          <div
            key={file.path}
            onClick={() => onSelectFile(file)}
            onContextMenu={(e) => handleContextMenu(e, file)}
            style={{
              display: "flex",
              alignItems: "center",
              padding: "8px 16px",
              backgroundColor:
                activeFile?.path === file.path ? "#1e1e1e" : "#2d2d30",
              color: activeFile?.path === file.path ? "#fff" : "#cccccc",
              borderRight: "1px solid #3e3e42",
              cursor: "pointer",
              fontSize: "13px",
              gap: "10px",
              whiteSpace: "nowrap",
              transition: "all 0.1s",
              borderTop:
                activeFile?.path === file.path
                  ? "2px solid #0e639c"
                  : "2px solid transparent",
            }}
          >
            <GoFile />
            <span>{file.name}</span>
            <button
              onClick={(e) => {
                e.stopPropagation();
                onCloseFile(file);
              }}
              style={{
                background: "none",
                border: "none",
                color: "#858585",
                cursor: "pointer",
                fontSize: "16px",
                padding: "0 4px",
                borderRadius: "4px",
              }}
              onMouseEnter={(e) => {
                e.currentTarget.style.color = "#fff";
                e.currentTarget.style.backgroundColor = "#3e3e42";
              }}
              onMouseLeave={(e) => {
                e.currentTarget.style.color = "#858585";
                e.currentTarget.style.backgroundColor = "transparent";
              }}
            >
              <MdClose size={14} />
            </button>
          </div>
        ))}
      </div>
      {showContextMenu && (
        <div
          style={{
            position: "fixed",
            top: showContextMenu.y,
            left: showContextMenu.x,
            backgroundColor: "#252526",
            border: "1px solid #3e3e42",
            borderRadius: "6px",
            boxShadow: "0 4px 12px rgba(0,0,0,0.4)",
            zIndex: 1000,
            minWidth: "160px",
            overflow: "hidden",
          }}
        >
          <div
            onClick={() => {
              onCloseOthers(showContextMenu.file);
              setShowContextMenu(null);
            }}
            style={{
              padding: "8px 16px",
              cursor: "pointer",
              color: "#cccccc",
              fontSize: "13px",
            }}
            onMouseEnter={(e) => {
              e.currentTarget.style.backgroundColor = "#2a2d2e";
            }}
            onMouseLeave={(e) => {
              e.currentTarget.style.backgroundColor = "transparent";
            }}
          >
            Close Others
          </div>
          <div
            onClick={() => {
              onCloseAll();
              setShowContextMenu(null);
            }}
            style={{
              padding: "8px 16px",
              cursor: "pointer",
              color: "#cccccc",
              fontSize: "13px",
            }}
            onMouseEnter={(e) => {
              e.currentTarget.style.backgroundColor = "#2a2d2e";
            }}
            onMouseLeave={(e) => {
              e.currentTarget.style.backgroundColor = "transparent";
            }}
          >
            Close All
          </div>
        </div>
      )}
    </>
  );
};

const TitleBar: React.FC = () => {
  return (
    <div
      style={{
        height: "32px",
        backgroundColor: "#2d2d30",
        display: "flex",
        alignItems: "center",
        justifyContent: "space-between",
        padding: "0 12px",
        borderBottom: "1px solid #3e3e42",
      }}
    >
      <div style={{ display: "flex", alignItems: "center", gap: "12px" }}>
        <div style={{ display: "flex", gap: "8px" }}>
          <div
            style={{
              width: "12px",
              height: "12px",
              borderRadius: "50%",
              backgroundColor: "#ed6a5e",
            }}
          />
          <div
            style={{
              width: "12px",
              height: "12px",
              borderRadius: "50%",
              backgroundColor: "#f5bd4f",
            }}
          />
          <div
            style={{
              width: "12px",
              height: "12px",
              borderRadius: "50%",
              backgroundColor: "#61c454",
            }}
          />
        </div>
        <span style={{ color: "#cccccc", fontSize: "12px", fontWeight: 500 }}>
          Web VS Code
        </span>
      </div>
      <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
        <FiGitBranch size={12} color="#858585" />
        <span style={{ color: "#858585", fontSize: "11px" }}>main</span>
        <FiCheckCircle size={12} color="#61c454" />
      </div>
    </div>
  );
};

const FileExplorer: React.FC<{
  files: FileNode;
  onFileSelect: (node: FileNode) => void;
  selectedFile: string | null;
  onRefresh: (newFiles: FileNode | null, newFile?: FileNode) => void;
  expandedFolders: Set<string>;
  onToggleFolder: (path: string) => void;
  onExpandAll: () => void;
  onCollapseAll: () => void;
  onDeleteRoot: () => void;
  searchQuery: string;
  onSearchChange: (query: string) => void;
  onAutoExpand: (paths: Set<string>) => void;
}> = ({
  files,
  onFileSelect,
  selectedFile,
  onRefresh,
  expandedFolders,
  onToggleFolder,
  onExpandAll,
  onCollapseAll,
  onDeleteRoot,
  searchQuery,
  onSearchChange,
  onAutoExpand,
}) => {
  const [contextMenu, setContextMenu] = useState<{
    x: number;
    y: number;
    node: FileNode | null;
  } | null>(null);
  const [dialog, setDialog] = useState<{
    type: "newFile" | "newFolder" | "rename";
    node: FileNode | null;
  } | null>(null);
  const [showSearch, setShowSearch] = useState(false);

  // Для контекстного меню на пустом месте (фон эксплорера)
  const handleEmptyContextMenu = (e: React.MouseEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setContextMenu({ x: e.clientX, y: e.clientY, node: null });
  };

  // Для контекстного меню на элементе (передаётся из FileTreeItem)
  const handleNodeContextMenu = (e: React.MouseEvent, node: FileNode) => {
    e.preventDefault();
    e.stopPropagation(); // ВАЖНО: предотвращаем всплытие
    setContextMenu({ x: e.clientX, y: e.clientY, node });
  };

  const handleDelete = (node: FileNode) => {
    const isRootNode = node.path === files.path;
    if (isRootNode) {
      onDeleteRoot();
    } else if (window.confirm(`Delete "${node.name}"?`)) {
      const newFiles = deleteNode(files, node.path || node.name);
      if (newFiles) onRefresh(newFiles);
    }
  };

  const filteredFiles = searchQuery ? filterTree(files, searchQuery) : files;

  useEffect(() => {
    if (searchQuery && files) {
      const pathsToExpand = collectPathsToExpand(files, searchQuery);
      if (pathsToExpand.size > 0) {
        onAutoExpand(pathsToExpand);
      }
    }
  }, [searchQuery, files, onAutoExpand]);

  const handleDialogConfirm = (value: string) => {
    if (!dialog) return;

    if (dialog.type === "rename" && dialog.node) {
      const parentPath =
        dialog.node.path?.split("/").slice(0, -1).join("/") || "";
      const parentNode = parentPath ? findNode(files, parentPath) : files;
      if (
        parentNode?.children?.some(
          (c) =>
            c.name.toLowerCase() === value.toLowerCase() &&
            c.path !== dialog.node?.path,
        )
      ) {
        alert(`"${value}" already exists.`);
        return;
      }
      const newFiles = renameNode(
        files,
        dialog.node.path || dialog.node.name,
        value,
      );
      if (newFiles) {
        onRefresh(newFiles);
      }
      setDialog(null);
      return;
    }

    let parentPath: string;

    if (!dialog.node) {
      parentPath = files.path || files.name;
    } else if (dialog.node.type === "folder") {
      parentPath = dialog.node.path || dialog.node.name;
    } else {
      const pathParts = (dialog.node.path || dialog.node.name).split("/");
      pathParts.pop();
      parentPath = pathParts.join("/") || files.path || files.name;
    }

    const parentNode = findNode(files, parentPath);
    if (
      parentNode?.children?.some(
        (c) => c.name.toLowerCase() === value.toLowerCase(),
      )
    ) {
      alert(`"${value}" already exists in this folder.`);
      setDialog(null);
      return;
    }

    let newFiles: FileNode | null = null;
    let createdNode: FileNode | null = null;

    if (dialog.type === "newFile") {
      createdNode = { name: value, type: "file", content: "" };
      newFiles = addNode(files, parentPath, createdNode);
    } else if (dialog.type === "newFolder") {
      createdNode = { name: value, type: "folder", children: [] };
      newFiles = addNode(files, parentPath, createdNode);
    }

    if (newFiles) {
      const allParentPaths: string[] = [];
      let current = parentPath;
      while (current) {
        allParentPaths.push(current);
        const parts = current.split("/");
        parts.pop();
        current = parts.join("/");
      }
      allParentPaths.forEach((p) => {
        if (!expandedFolders.has(p)) {
          onToggleFolder(p);
        }
      });
      onAutoExpand(new Set(allParentPaths));

      if (createdNode && createdNode.type === "file") {
        const findAndOpen = (node: FileNode, name: string): FileNode | null => {
          if (node.name === name && node.type === "file") return node;
          if (node.children) {
            for (const child of node.children) {
              const found = findAndOpen(child, name);
              if (found) return found;
            }
          }
          return null;
        };
        const openedFile = findAndOpen(newFiles, value);
        onRefresh(newFiles, openedFile || undefined);
      } else {
        onRefresh(newFiles);
      }
    }
    setDialog(null);
  };

  return (
    <div
      style={{
        height: "100%",
        display: "flex",
        flexDirection: "column",
        backgroundColor: "#252526",
      }}
      onContextMenu={handleEmptyContextMenu}
    >
      <div
        style={{
          padding: "0 8px",
          height: "35px",
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          borderBottom: "1px solid #3e3e42",
        }}
      >
        <span
          style={{
            color: "#bbbbbb",
            fontWeight: 500,
            fontSize: "11px",
            letterSpacing: "0.8px",
          }}
        >
          EXPLORER
        </span>
        <div style={{ display: "flex", gap: "2px", alignItems: "center" }}>
          <button
            onClick={() => setShowSearch(!showSearch)}
            style={{
              background: "transparent",
              border: "none",
              color: showSearch ? "#cccccc" : "#858585",
              cursor: "pointer",
              padding: "4px",
              borderRadius: "4px",
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              transition: "all 0.1s",
            }}
            onMouseEnter={(e) => {
              e.currentTarget.style.backgroundColor = "#2a2d2e";
            }}
            onMouseLeave={(e) => {
              e.currentTarget.style.backgroundColor = "transparent";
            }}
            title="Search in files"
          >
            <FiSearch size={14} />
          </button>
          <button
            onClick={onCollapseAll}
            style={{
              background: "transparent",
              border: "none",
              color: "#858585",
              cursor: "pointer",
              padding: "4px",
              borderRadius: "4px",
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              transition: "all 0.1s",
            }}
            onMouseEnter={(e) => {
              e.currentTarget.style.backgroundColor = "#2a2d2e";
              e.currentTarget.style.color = "#cccccc";
            }}
            onMouseLeave={(e) => {
              e.currentTarget.style.backgroundColor = "transparent";
              e.currentTarget.style.color = "#858585";
            }}
            title="Collapse All"
          >
            <FiMinus size={14} />
          </button>
          <button
            onClick={onExpandAll}
            style={{
              background: "transparent",
              border: "none",
              color: "#858585",
              cursor: "pointer",
              padding: "4px",
              borderRadius: "4px",
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              transition: "all 0.1s",
            }}
            onMouseEnter={(e) => {
              e.currentTarget.style.backgroundColor = "#2a2d2e";
              e.currentTarget.style.color = "#cccccc";
            }}
            onMouseLeave={(e) => {
              e.currentTarget.style.backgroundColor = "transparent";
              e.currentTarget.style.color = "#858585";
            }}
            title="Expand All"
          >
            <GoKebabHorizontal size={14} />
          </button>
        </div>
      </div>

      <div
        style={{
          padding: "6px 12px",
          display: "flex",
          alignItems: "center",
          gap: "6px",
          borderBottom: "1px solid #3e3e42",
        }}
      >
        <FiFolder size={14} color="#858585" />
        <span
          style={{
            color: "#cccccc",
            fontWeight: 600,
            fontSize: "11px",
            letterSpacing: "0.3px",
            flex: 1,
          }}
        >
          {files.name}
        </span>
      </div>

      {showSearch && (
        <div style={{ padding: "6px 8px", borderBottom: "1px solid #3e3e42" }}>
          <div
            style={{
              display: "flex",
              alignItems: "center",
              backgroundColor: "#3c3c3c",
              border: searchQuery
                ? "1px solid #007acc"
                : "1px solid transparent",
              borderRadius: "4px",
              padding: "0 6px",
              transition: "border-color 0.1s",
            }}
          >
            <FiSearch size={13} color="#858585" />
            <input
              type="text"
              value={searchQuery}
              onChange={(e) => onSearchChange(e.target.value)}
              placeholder="Search..."
              autoFocus
              style={{
                flex: 1,
                padding: "5px 6px",
                backgroundColor: "transparent",
                border: "none",
                color: "#cccccc",
                fontSize: "12px",
                outline: "none",
              }}
            />
            {searchQuery && (
              <button
                onClick={() => onSearchChange("")}
                style={{
                  background: "none",
                  border: "none",
                  color: "#858585",
                  cursor: "pointer",
                  padding: "2px",
                  display: "flex",
                  alignItems: "center",
                }}
              >
                <MdClose size={12} />
              </button>
            )}
          </div>
        </div>
      )}

      <div style={{ flex: 1, overflowY: "auto" }}>
        {filteredFiles ? (
          <FileTreeItem
            node={filteredFiles}
            level={0}
            onFileSelect={onFileSelect}
            selectedFile={selectedFile}
            onContextMenu={handleNodeContextMenu}
            expandedFolders={expandedFolders}
            onToggleFolder={onToggleFolder}
            onDelete={handleDelete}
            isRoot
            searchQuery={searchQuery}
          />
        ) : (
          <div
            style={{
              padding: "16px",
              color: "#858585",
              fontSize: "13px",
              textAlign: "center",
            }}
          >
            No results found
          </div>
        )}
      </div>

      {contextMenu && (
        <ContextMenu
          x={contextMenu.x}
          y={contextMenu.y}
          node={contextMenu.node}
          onClose={() => setContextMenu(null)}
          onNewFile={() => {
            setDialog({ type: "newFile", node: contextMenu.node });
            setContextMenu(null);
          }}
          onNewFolder={() => {
            setDialog({ type: "newFolder", node: contextMenu.node });
            setContextMenu(null);
          }}
          onRename={() => {
            setDialog({ type: "rename", node: contextMenu.node });
            setContextMenu(null);
          }}
          onDelete={() => {
            if (contextMenu.node) {
              handleDelete(contextMenu.node);
            }
            setContextMenu(null);
          }}
        />
      )}

      {dialog && (
        <InputDialog
          title={
            dialog.type === "newFile"
              ? "New File"
              : dialog.type === "newFolder"
                ? "New Folder"
                : "Rename"
          }
          initialValue={
            dialog.type === "rename" && dialog.node ? dialog.node.name : ""
          }
          onConfirm={handleDialogConfirm}
          onCancel={() => setDialog(null)}
        />
      )}
    </div>
  );
};

const CodeEditor: React.FC<{
  filePath: string;
  content: string;
  onChange: (content: string) => void;
}> = ({ filePath, content, onChange }) => {
  const getLanguage = (path: string) => {
    const ext = path.split(".").pop();
    const map: Record<string, string> = {
      py: "python",
      js: "javascript",
      ts: "typescript",
      jsx: "javascript",
      tsx: "typescript",
      json: "json",
      md: "markdown",
      css: "css",
      html: "html",
    };
    return map[ext || ""] || "plaintext";
  };

  return (
    <div
      style={{
        height: "100%",
        display: "flex",
        flexDirection: "column",
        backgroundColor: "#1e1e1e",
      }}
    >
      <div style={{ flex: 1 }}>
        {filePath ? (
          <Editor
            height="100%"
            language={getLanguage(filePath)}
            value={content}
            onChange={(value) => onChange(value || "")}
            theme="vs-dark"
            options={{
              minimap: { enabled: false },
              fontSize: 14,
              fontFamily: "'Cascadia Code', 'Fira Code', monospace",
              tabSize: 4,
              wordWrap: "on",
              lineNumbers: "on",
              automaticLayout: true,
              renderWhitespace: "selection",
              smoothScrolling: true,
            }}
          />
        ) : (
          <div
            style={{
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              height: "100%",
              color: "#858585",
              textAlign: "center",
            }}
          >
            <div>
              <div
                style={{
                  marginBottom: "24px",
                  display: "flex",
                  justifyContent: "center",
                  opacity: 0.5,
                }}
              >
                <FiFolder size={64} />
              </div>
              <div
                style={{
                  fontSize: "18px",
                  marginBottom: "12px",
                  color: "#cccccc",
                }}
              >
                Welcome to Web VS Code
              </div>
              <div style={{ fontSize: "13px", marginBottom: "8px" }}>
                Right-click on a folder to create files
              </div>
              <div style={{ fontSize: "12px", color: "#0e639c" }}>
                Or right-click anywhere in the explorer
              </div>
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

export const TestPage: React.FC = () => {
  const [files, setFiles] = useState<FileNode | null>(() =>
    addPaths(initialFiles),
  );
  const [openFiles, setOpenFiles] = useState<FileNode[]>([]);
  const [activeFile, setActiveFile] = useState<FileNode | null>(null);
  const [expandedFolders, setExpandedFolders] = useState<Set<string>>(
    new Set(["my-project"]),
  );
  const [searchQuery, setSearchQuery] = useState("");

  const handleFileSelect = useCallback(
    (node: FileNode) => {
      if (node.type === "file") {
        if (!openFiles.find((f) => f.path === node.path)) {
          setOpenFiles((prev) => [...prev, node]);
        }
        setActiveFile(node);
      }
    },
    [openFiles],
  );

  const handleContentChange = useCallback(
    (newContent: string) => {
      if (activeFile && files) {
        const updatedActiveFile = { ...activeFile, content: newContent };
        setActiveFile(updatedActiveFile);
        setOpenFiles((prev) =>
          prev.map((f) => (f.path === activeFile.path ? updatedActiveFile : f)),
        );
      }
    },
    [activeFile, files],
  );

  const handleCloseFile = useCallback(
    (file: FileNode) => {
      const newOpenFiles = openFiles.filter((f) => f.path !== file.path);
      setOpenFiles(newOpenFiles);

      if (activeFile?.path === file.path) {
        setActiveFile(newOpenFiles[newOpenFiles.length - 1] || null);
      }
    },
    [openFiles, activeFile],
  );

  const handleCloseAll = useCallback(() => {
    setOpenFiles([]);
    setActiveFile(null);
  }, []);

  const handleCloseOthers = useCallback((file: FileNode) => {
    setOpenFiles([file]);
    setActiveFile(file);
  }, []);

  const handleRefresh = useCallback(
    (newFiles: FileNode | null, newFile?: FileNode) => {
      setFiles(newFiles);

      if (!newFiles) {
        setOpenFiles([]);
        setActiveFile(null);
        return;
      }

      const updatedOpenFiles = openFiles
        .map((f) => {
          const found = findNode(newFiles, f.path || "");
          return found && found.type === "file" ? found : null;
        })
        .filter((f): f is FileNode => f !== null);

      setOpenFiles(updatedOpenFiles);

      if (newFile) {
        handleFileSelect(newFile);
      } else if (activeFile) {
        const stillExists = findNode(newFiles, activeFile.path || "");
        if (!stillExists) {
          setActiveFile(updatedOpenFiles[updatedOpenFiles.length - 1] || null);
        } else if (stillExists.type === "file") {
          setActiveFile(stillExists);
        }
      }
    },
    [openFiles, activeFile, handleFileSelect],
  );

  const handleToggleFolder = useCallback((path: string) => {
    setExpandedFolders((prev) => {
      const newSet = new Set(prev);
      if (newSet.has(path)) {
        newSet.delete(path);
      } else {
        newSet.add(path);
      }
      return newSet;
    });
  }, []);

  const handleExpandAll = useCallback(() => {
    if (files) {
      const allPaths = getAllFolderPaths(files);
      setExpandedFolders(new Set(allPaths));
    }
  }, [files]);

  const handleCollapseAll = useCallback(() => {
    setExpandedFolders(new Set());
  }, []);

  const handleDeleteRoot = useCallback(() => {
    setFiles(null);
    setOpenFiles([]);
    setActiveFile(null);
    setExpandedFolders(new Set());
  }, []);

  const handleCreateNewProject = useCallback(() => {
    const newProject = addPaths(initialFiles);
    setFiles(newProject);
    setExpandedFolders(new Set([newProject.path || newProject.name]));
    setSearchQuery("");
  }, []);

  if (!files) {
    return (
      <div
        style={{
          height: "100vh",
          display: "flex",
          flexDirection: "column",
          backgroundColor: "#1e1e1e",
          fontFamily:
            "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
        }}
      >
        <TitleBar />
        <div
          style={{
            flex: 1,
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
          }}
        >
          <div style={{ textAlign: "center" }}>
            <div
              style={{
                marginBottom: "24px",
                display: "flex",
                justifyContent: "center",
                opacity: 0.3,
              }}
            >
              <GoTrash size={72} />
            </div>
            <div
              style={{
                fontSize: "22px",
                marginBottom: "12px",
                color: "#cccccc",
                fontWeight: 300,
              }}
            >
              No project open
            </div>
            <div
              style={{
                fontSize: "13px",
                marginBottom: "32px",
                color: "#858585",
              }}
            >
              Create a new project to get started
            </div>
            <button
              onClick={handleCreateNewProject}
              style={{
                padding: "10px 24px",
                backgroundColor: "#0e639c",
                border: "none",
                borderRadius: "4px",
                color: "#fff",
                cursor: "pointer",
                fontSize: "13px",
                fontWeight: 500,
                transition: "background-color 0.1s",
              }}
              onMouseEnter={(e) => {
                e.currentTarget.style.backgroundColor = "#1177bb";
              }}
              onMouseLeave={(e) => {
                e.currentTarget.style.backgroundColor = "#0e639c";
              }}
            >
              <MdAdd size={14} /> New Project
            </button>
          </div>
        </div>
        <div
          style={{
            height: "22px",
            backgroundColor: "#007acc",
            display: "flex",
            alignItems: "center",
            justifyContent: "space-between",
            padding: "0 12px",
            fontSize: "12px",
            color: "#ffffff",
            userSelect: "none",
            flexShrink: 0,
          }}
        >
          <div style={{ display: "flex", gap: "16px", alignItems: "center" }}>
            <span style={{ display: "flex", alignItems: "center", gap: "4px" }}>
              <FiGitBranch size={12} /> main
            </span>
            <span style={{ display: "flex", alignItems: "center", gap: "8px" }}>
              <FiCheckCircle size={12} /> 0 <FiAlertCircle size={12} /> 0
            </span>
          </div>
          <div style={{ display: "flex", gap: "16px", alignItems: "center" }}>
            {activeFile && (
              <span>
                Ln 1, Col 1 | Spaces: 4 | UTF-8 |{" "}
                {activeFile.path?.split(".").pop()?.toUpperCase() || "TXT"}
              </span>
            )}
            <span>Web VS Code</span>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div
      style={{
        height: "100vh",
        display: "flex",
        flexDirection: "column",
        overflow: "hidden",
        backgroundColor: "#1e1e1e",
        fontFamily:
          "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
      }}
    >
      <div
        style={{
          height: "30px",
          backgroundColor: "#323233",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          borderBottom: "1px solid #1e1e1e",
          fontSize: "12px",
          color: "#cccccc",
          userSelect: "none",
          flexShrink: 0,
        }}
      >
        <span style={{ fontWeight: 400 }}>
          {activeFile ? `${activeFile.name} - ` : ""}
          {files.name}
        </span>
      </div>
      <div style={{ display: "flex", flex: 1, overflow: "hidden" }}>
        <div style={{ width: "260px", flexShrink: 0 }}>
          <FileExplorer
            files={files}
            onFileSelect={handleFileSelect}
            selectedFile={activeFile?.path || null}
            onRefresh={handleRefresh}
            expandedFolders={expandedFolders}
            onToggleFolder={handleToggleFolder}
            onExpandAll={handleExpandAll}
            onCollapseAll={handleCollapseAll}
            onDeleteRoot={handleDeleteRoot}
            searchQuery={searchQuery}
            onSearchChange={setSearchQuery}
            onAutoExpand={(paths) =>
              setExpandedFolders((prev) => new Set([...prev, ...paths]))
            }
          />
        </div>
        <div
          style={{
            flex: 1,
            display: "flex",
            flexDirection: "column",
            overflow: "hidden",
          }}
        >
          <TabBar
            openFiles={openFiles}
            activeFile={activeFile}
            onSelectFile={setActiveFile}
            onCloseFile={handleCloseFile}
            onCloseAll={handleCloseAll}
            onCloseOthers={handleCloseOthers}
          />
          <CodeEditor
            filePath={activeFile?.path || ""}
            content={activeFile?.content || ""}
            onChange={handleContentChange}
          />
        </div>
      </div>
      <div
        style={{
          height: "22px",
          backgroundColor: "#007acc",
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          padding: "0 12px",
          fontSize: "12px",
          color: "#ffffff",
          userSelect: "none",
          flexShrink: 0,
        }}
      >
        <div style={{ display: "flex", gap: "16px", alignItems: "center" }}>
          <span style={{ display: "flex", alignItems: "center", gap: "4px" }}>
            <FiGitBranch size={12} /> main
          </span>
          <span style={{ display: "flex", alignItems: "center", gap: "8px" }}>
            <FiCheckCircle size={12} /> 0 <FiAlertCircle size={12} /> 0
          </span>
        </div>
        <div style={{ display: "flex", gap: "16px", alignItems: "center" }}>
          {activeFile && (
            <span>
              Ln 1, Col 1 | Spaces: 4 | UTF-8 |{" "}
              {activeFile.path?.split(".").pop()?.toUpperCase() || "TXT"}
            </span>
          )}
          <span>Web VS Code</span>
        </div>
      </div>
    </div>
  );
};
