import { render } from 'solid-js/web';
import { createSignal, onMount, For, Show, onCleanup, createEffect } from 'solid-js';

import hljs from 'highlight.js/lib/core';
import javascript_hljs from 'highlight.js/lib/languages/javascript';
import typescript_hljs from 'highlight.js/lib/languages/typescript';
import json_hljs from 'highlight.js/lib/languages/json';
import xml_hljs from 'highlight.js/lib/languages/xml';
import css_hljs from 'highlight.js/lib/languages/css';
import bash_hljs from 'highlight.js/lib/languages/bash';
import markdown_hljs from 'highlight.js/lib/languages/markdown';
import sql_hljs from 'highlight.js/lib/languages/sql';

import { EditorView, keymap, lineNumbers } from '@codemirror/view';
import { EditorState, Compartment } from '@codemirror/state';
import { defaultKeymap, history, historyKeymap } from '@codemirror/commands';
import { syntaxHighlighting, defaultHighlightStyle, foldGutter, foldKeymap } from '@codemirror/language';
import { lintGutter } from "@codemirror/lint";
import { oneDark } from '@codemirror/theme-one-dark';

import { javascript } from '@codemirror/lang-javascript';
import { json } from '@codemirror/lang-json';
import { html } from '@codemirror/lang-html';
import { css } from '@codemirror/lang-css';
import { markdown } from '@codemirror/lang-markdown';

hljs.registerLanguage('javascript', javascript_hljs);
hljs.registerLanguage('typescript', typescript_hljs);
hljs.registerLanguage('json', json_hljs);
hljs.registerLanguage('html', xml_hljs);
hljs.registerLanguage('css', css_hljs);
hljs.registerLanguage('bash', bash_hljs);
hljs.registerLanguage('markdown', markdown_hljs);
hljs.registerLanguage('sql', sql_hljs);

function App() {
  const [loading, setLoading] = createSignal(true);
  const [status, setStatus] = createSignal('');
  const [notifications, setNotifications] = createSignal([]);
  const [userData, setUserData] = createSignal(null);
  const [files, setFiles] = createSignal([]);
  const [selectedFile, setSelectedFile] = createSignal(null);
  const [fileContent, setFileContent] = createSignal('');
  const [newFileName, setNewFileName] = createSignal('');
  const [newFolderName, setNewFolderName] = createSignal('');
  const [openFolders, setOpenFolders] = createSignal({});
  const [contextMenu, setContextMenu] = createSignal({
    visible: false,
    x: 0,
    y: 0,
    file: null,
  });
  const [isMobileView, setIsMobileView] = createSignal(false);
  const [isEditingFile, setIsEditingFile] = createSignal(true);
  const [initialLoadComplete, setInitialLoadComplete] = createSignal(false);

  const [renameContainerInfo, setRenameContainerInfo] = createSignal({
    visible: false,
    file: null,
    newName: '',
  });
  const [createItemModalInfo, setCreateItemModalInfo] = createSignal({
    visible: false,
    parentPath: null,
    isDir: false,
    itemName: '',
  });

  let renameInputRef;
  let codeRef;
  let createItemInputRef;
  let editorRef;
  let editorViewInstance = null;

  const languageCompartment = new Compartment();
  const themeCompartment = new Compartment();
  const editableCompartment = new Compartment();

  const linkManager = '/private/server/exocore/web/file';

  const getToken = () => localStorage.getItem('exocore-token') || '';
  const getCookies = () => localStorage.getItem('exocore-cookies') || '';

  const addNotification = (message, type = 'info', duration = 4000) => {
    const id = Date.now();
    setNotifications(prev => [...prev, { id, message, type }]);
    setTimeout(() => {
      setNotifications(prev => prev.filter(n => n.id !== id));
    }, duration);
  };

  function sortFileSystemItems(items) {
    if (!Array.isArray(items)) return [];

    const specialOrder = ['.git', 'package.json', 'package-lock.json'];
    const nodeModulesName = 'node_modules';

    const regularItems = items.filter(item => !specialOrder.includes(item.name) && item.name !== nodeModulesName);
    const specialItemsOnList = items.filter(item => specialOrder.includes(item.name));
    const nodeModulesItem = items.find(item => item.name === nodeModulesName);

    regularItems.sort((a, b) => {
        if (a.isDir && !b.isDir) return -1;
        if (!a.isDir && b.isDir) return 1;
        return a.name.localeCompare(b.name);
    });
    specialItemsOnList.sort((a, b) => specialOrder.indexOf(a.name) - specialOrder.indexOf(b.name));

    const sortedItems = [...regularItems, ...specialItemsOnList];
    if (nodeModulesItem) {
      sortedItems.push(nodeModulesItem);
    }
    return sortedItems;
  }

  async function fetchUserInfo() {
    setLoading(true);
    const token = getToken();
    const cookies = getCookies();

    if (!token || !cookies) {
      setLoading(false);
      setInitialLoadComplete(true);
      window.location.href = '/private/server/exocore/web/public/login';
      return;
    }

    try {
      const res = await fetch('/private/server/exocore/web/userinfo', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ token, cookies }),
      });

      if (!res.ok) {
        let errorMsg = `Server error: ${res.status}`;
        try {
          const errorData = await res.json();
          errorMsg = errorData.message || errorMsg;
        } catch (parseError) {}
        throw new Error(errorMsg);
      }

      const data = await res.json();

      if (data.data?.user && data.data.user.verified === 'success') {
        setUserData(data.data.user);
        await fetchFiles('');
      } else {
        setUserData(null);
        const redirectMsg = data.message || 'User verification failed. Redirecting to login...';
        setStatus(redirectMsg);
        localStorage.removeItem('exocore-token');
        localStorage.removeItem('exocore-cookies');
        setTimeout(() => {
          window.location.href = '/private/server/exocore/web/public/login';
        }, 2500);
      }
    } catch (err) {
      setUserData(null);
      const errorMessage = err instanceof Error ? err.message : String(err);
      const redirectMsg = 'Failed to fetch user info: ' + errorMessage + '. Redirecting to login...';
      setStatus(redirectMsg);
      localStorage.removeItem('exocore-token');
      localStorage.removeItem('exocore-cookies');
      setTimeout(() => {
          window.location.href = '/private/server/exocore/web/public/login';
      }, 2500);
    } finally {
      setLoading(false);
      setInitialLoadComplete(true);
    }
  }

  async function fetchFiles(currentPath = '') {
    setLoading(true);
    let endpoint = '';
    let bodyPayload = {};
    if (currentPath) {
      endpoint = `${linkManager}/open-folder`;
      bodyPayload = {
        folder: currentPath,
      };
    } else {
      endpoint = `${linkManager}/list`;
      bodyPayload = {};
    }
    try {
      const res = await fetch(endpoint, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(bodyPayload),
      });
      const responseText = await res.text();
      if (!res.ok) {
        let errorMsg = responseText;
        try {
          const errData = JSON.parse(responseText);
          errorMsg = errData.message || errData.error || responseText;
        } catch (e) {}
        throw new Error(errorMsg || `HTTP error! status: ${res.status}`);
      }
      const data = JSON.parse(responseText);
      if (currentPath) {
        if (data && Array.isArray(data.items)) {
          setOpenFolders((prev) => ({
            ...prev,
            [currentPath]: sortFileSystemItems(data.items),
          }));
        } else {
          setOpenFolders((prev) => ({ ...prev, [currentPath]: [] }));
          addNotification(`Error: Could not load content for folder ${currentPath}.`, 'error');
        }
      } else {
        if (Array.isArray(data)) {
          setFiles(sortFileSystemItems(data));
        } else {
          setFiles([]);
          addNotification(`Error: Could not load root directory.`, 'error');
        }
      }
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : String(err);
      addNotification(`Failed to list ${currentPath || 'root'}: ${errorMessage}`, 'error');
      if (currentPath) {
        setOpenFolders((prev) => ({ ...prev, [currentPath]: undefined }));
      }
    } finally {
      setLoading(false);
    }
  }

  async function openFile(file) {
    setLoading(true);
    try {
      const res = await fetch(`${linkManager}/open`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          file,
        }),
      });
      const text = await res.text();
      if (!res.ok) throw new Error(text || `HTTP error! status: ${res.status}`);
      setSelectedFile(file);
      setFileContent(text);
      setIsEditingFile(true);
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : String(err);
      addNotification('Failed to open file: ' + errorMessage, 'error');
    } finally {
      setLoading(false);
    }
  }

  function closeFileEditor() {
    setSelectedFile(null);
    setFileContent('');
  }

  async function saveFile() {
    if (!selectedFile()) return;
    setLoading(true);
    try {
      const res = await fetch(`${linkManager}/save`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          file: selectedFile(),
          content: fileContent(),
        }),
      });
      const message = await res.text();
      if (!res.ok) throw new Error(message || `HTTP error! status: ${res.status}`);
      addNotification(message, 'success');
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : String(err);
      addNotification('Failed to save file: ' + errorMessage, 'error');
    } finally {
      setLoading(false);
    }
  }

  async function refreshFileSystem(affectedItemPath = '') {
    let parentPath = '';
    if (affectedItemPath) {
      const lastSlashIndex = affectedItemPath.lastIndexOf('/');
      if (lastSlashIndex !== -1) {
        parentPath = affectedItemPath.substring(0, lastSlashIndex);
      }
    }
    await fetchFiles();
    if (parentPath && openFolders()[parentPath]) {
      await fetchFiles(parentPath);
    }
  }

  function fileOrFolderNameIsDirectory(path) {
    if (openFolders()[path] !== undefined) return true;
    const checkList = (list, currentBuildPath = '') => {
      for (const item of list) {
        const itemFullPath = currentBuildPath ? `${currentBuildPath}/${item.name}` : item.name;
        if (itemFullPath === path) return item.isDir;
        if (item.isDir && openFolders()[itemFullPath]) {
          const foundInSub = checkList(openFolders()[itemFullPath], itemFullPath);
          if (foundInSub !== undefined) return foundInSub;
        }
      }
      return undefined;
    };
    return checkList(files()) || false;
  }

  async function createFile() {
    const name = newFileName().trim();
    if (!name) {
      addNotification('Please enter a file name.', 'error');
      return;
    }
    setLoading(true);
    try {
      const res = await fetch(`${linkManager}/create`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ file: name }),
      });
      const message = await res.text();
      if (!res.ok) throw new Error(message || `HTTP error! status: ${res.status}`);
      setNewFileName('');
      await refreshFileSystem(name);
      addNotification(`File "${name}" created successfully.`, 'success');
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : String(err);
      addNotification('Failed to create file: ' + errorMessage, 'error');
    } finally {
      setLoading(false);
    }
  }

  async function createFolder() {
    const name = newFolderName().trim();
    if (!name) {
      addNotification('Please enter a folder name.', 'error');
      return;
    }
    setLoading(true);
    try {
      const res = await fetch(`${linkManager}/create-folder`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ folder: name }),
      });
      const message = await res.text();
      if (!res.ok) throw new Error(message || `HTTP error! status: ${res.status}`);
      setNewFolderName('');
      await refreshFileSystem(name);
      addNotification(`Folder "${name}" created successfully.`, 'success');
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : String(err);
      addNotification('Failed to create folder: ' + errorMessage, 'error');
    } finally {
      setLoading(false);
    }
  }

  async function uploadFile(e) {
    const fileToUpload = e.target.files[0];
    if (!fileToUpload) return;
    const targetPathForUpload = fileToUpload.name;
    const form = new FormData();
    form.append('file', fileToUpload);
    setLoading(true);
    try {
      const res = await fetch(`${linkManager}/upload`, {
        method: 'POST',
        body: form,
      });
      const message = await res.text();
      if (!res.ok) throw new Error(message || `HTTP error! status: ${res.status}`);
      await refreshFileSystem(targetPathForUpload);
      addNotification(`File "${fileToUpload.name}" uploaded successfully.`, 'success');
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : String(err);
      addNotification('Failed to upload file: ' + errorMessage, 'error');
    } finally {
      setLoading(false);
      e.target.value = null;
    }
  }

  function download(file) {
    const form = document.createElement('form');
    form.method = 'POST';
    form.action = `${linkManager}/download`;
    form.style.display = 'none';
    const input = document.createElement('input');
    input.name = 'file';
    input.value = file;
    input.type = 'hidden';
    form.appendChild(input);
    document.body.appendChild(form);
    form.submit();
    document.body.removeChild(form);
    addNotification(`Downloading "${file}"...`, 'info');
  }

  function toggleFolder(folderPath) {
    if (openFolders()[folderPath]) {
      setOpenFolders((prev) => {
        const updated = { ...prev };
        delete updated[folderPath];
        Object.keys(updated).forEach(key => {
          if (key.startsWith(folderPath + '/')) {
            delete updated[key];
          }
        });
        return updated;
      });
    } else {
      fetchFiles(folderPath);
    }
  }

  function handleFileClick(file, fullPath) {
    if (file.isDir) {
      toggleFolder(fullPath);
    } else {
      openFile(fullPath);
    }
  }

  function handleContextMenu(e, file, fullPath) {
    e.preventDefault();
    e.stopPropagation();
    setContextMenu({
      visible: true,
      x: e.clientX,
      y: e.clientY,
      file: { ...file, path: fullPath },
    });
  }

  function handleOpenFolderFromContextMenu() {
    const folderToOpen = contextMenu().file;
    if (folderToOpen && folderToOpen.isDir) {
      if (!openFolders()[folderToOpen.path]) {
        fetchFiles(folderToOpen.path);
      }
    }
    setContextMenu({ visible: false, x: 0, y: 0, file: null });
  }

  function handleDownloadSelected() {
    if (contextMenu().file && !contextMenu().file.isDir) {
      download(contextMenu().file.path);
    }
    setContextMenu({ visible: false, x: 0, y: 0, file: null });
  }

  async function handleUnzipSelected() {
    const fileToUnzip = contextMenu().file;
    if (!fileToUnzip || fileToUnzip.isDir || !fileToUnzip.name.toLowerCase().endsWith('.zip')) {
      setContextMenu({ visible: false, x: 0, y: 0, file: null });
      return;
    }

    const zipFilePath = fileToUnzip.path;
    setLoading(true);
    setContextMenu({ visible: false, x: 0, y: 0, file: null });

    try {
      const res = await fetch(`${linkManager}/unzip`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          zipFilePath: zipFilePath,
          overwrite: true,
          destinationPath: '',
        }),
      });
      const message = await res.text();
      if (!res.ok) {
        let errorMsg = message;
        try {
          const errData = JSON.parse(message);
          errorMsg = errData.message || errData.error || message;
        } catch (e) { }
        throw new Error(errorMsg || `HTTP error! status: ${res.status}`);
      }
      addNotification(message, 'success');
      await refreshFileSystem(zipFilePath);

    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : String(err);
      addNotification(`Failed to unzip "${fileToUnzip.name}": ${errorMessage}`, 'error');
    } finally {
      setLoading(false);
    }
  }

  function handleRenameClick() {
    if (contextMenu().file) {
      setRenameContainerInfo({
        visible: true,
        file: contextMenu().file,
        newName: contextMenu().file.name,
      });
    }
    setContextMenu({ visible: false, x: 0, y: 0, file: null });
  }

  async function handleDeleteSelected() {
    const fileToDelete = contextMenu().file;
    if (!fileToDelete) return;

    const confirmation = window.confirm(`Are you sure you want to delete "${fileToDelete.name}"? This action cannot be undone.`);
    if (!confirmation) {
      setContextMenu({ visible: false, x: 0, y: 0, file: null });
      return;
    }

    setLoading(true);
    setContextMenu({ visible: false, x: 0, y: 0, file: null });

    try {
      const res = await fetch(`${linkManager}/delete`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ path: fileToDelete.path }),
      });
      const message = await res.text();
      if (!res.ok) {
        let errorMsg = message;
        try {
          const errData = JSON.parse(message);
          errorMsg = errData.message || errData.error || message;
        } catch (e) { }
        throw new Error(errorMsg || `HTTP error! status: ${res.status}`);
      }
      addNotification(message || `Successfully deleted "${fileToDelete.name}".`, 'success');

      if (selectedFile() && selectedFile().startsWith(fileToDelete.path)) {
        closeFileEditor();
      }
      if (fileToDelete.isDir) {
        setOpenFolders((prev) => {
          const updated = { ...prev };
          delete updated[fileToDelete.path];
          Object.keys(updated).forEach(key => {
            if (key.startsWith(fileToDelete.path + '/')) {
              delete updated[key];
            }
          });
          return updated;
        });
      }
      await refreshFileSystem(fileToDelete.path);
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : String(err);
      addNotification(`Failed to delete "${fileToDelete.name}": ${errorMessage}`, 'error');
    } finally {
      setLoading(false);
    }
  }

  function cancelRename() {
    setRenameContainerInfo({ visible: false, file: null, newName: '' });
  }

  async function performRename() {
    const fileToRename = renameContainerInfo().file;
    const newName = renameContainerInfo().newName.trim();

    if (!fileToRename || !newName) {
      addNotification('Invalid rename operation. New name cannot be empty.', 'error');
      cancelRename();
      return;
    }
    setLoading(true);
    try {
      const oldPath = fileToRename.path;
      const parentPath = oldPath.substring(0, oldPath.lastIndexOf('/'));
      const newPath = parentPath ? `${parentPath}/${newName}` : newName;

      if (oldPath === newPath) {
        addNotification('No change detected. Renaming cancelled.', 'info');
        cancelRename();
        setLoading(false);
        return;
      }

      const res = await fetch(`${linkManager}/rename`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ oldPath, newPath }),
      });
      const message = await res.text();
      if (!res.ok) {
        let errorMsg = message;
        try {
          const errData = JSON.parse(message);
          errorMsg = errData.message || errData.error || message;
        } catch (e) { }
        throw new Error(errorMsg || `HTTP error! status: ${res.status}`);
      }
      addNotification(`Renamed "${fileToRename.name}" to "${newName}" successfully.`, 'success');

      if (fileToRename.isDir && openFolders()[oldPath]) {
        const contents = openFolders()[oldPath];
        setOpenFolders((prev) => {
          const updated = { ...prev };
          delete updated[oldPath];
          updated[newPath] = contents;
          Object.keys(updated).forEach(key => {
            if (key.startsWith(oldPath + '/')) {
              const subPath = key.substring(oldPath.length);
              const oldSubOpenFolderContent = updated[key];
              delete updated[key];
              updated[newPath + subPath] = oldSubOpenFolderContent;
            }
          });
          return updated;
        });
      }

      if (selectedFile() === oldPath) {
        setSelectedFile(newPath);
      }

      await refreshFileSystem(newPath);
      cancelRename();

    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : String(err);
      addNotification('Failed to rename: ' + errorMessage, 'error');
    } finally {
      setLoading(false);
    }
  }

  function handleShowCreateItemModal(isDirContext) {
    const contextFile = contextMenu().file;
    let parentPathTarget = '';

    if (contextFile) {
        if (contextFile.isDir) {
            parentPathTarget = contextFile.path;
        } else {
            const lastSlash = contextFile.path.lastIndexOf('/');
            parentPathTarget = lastSlash === -1 ? '' : contextFile.path.substring(0, lastSlash);
        }
    }

    setCreateItemModalInfo({
        visible: true,
        parentPath: parentPathTarget,
        isDir: isDirContext,
        itemName: '',
    });
    setContextMenu({ visible: false, x: 0, y: 0, file: null });
}

  function cancelCreateItem() {
    setCreateItemModalInfo({ visible: false, parentPath: null, isDir: false, itemName: '' });
  }

  async function performCreateItem() {
    const { parentPath, itemName, isDir } = createItemModalInfo();
    const newItemNameTrimmed = itemName.trim();

    if (!newItemNameTrimmed) {
      addNotification(`Please enter a ${isDir ? 'folder' : 'file'} name.`, 'error');
      return;
    }
    const fullPath = parentPath ? `${parentPath}/${newItemNameTrimmed}` : newItemNameTrimmed;
    setLoading(true);
    try {
      const endpoint = isDir ? `${linkManager}/create-folder` : `${linkManager}/create`;
      const payload = isDir ? { folder: fullPath } : { file: fullPath };
      const res = await fetch(endpoint, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });
      const message = await res.text();
      if (!res.ok) {
        let errorMsg = message;
        try {
          const errData = JSON.parse(message);
          errorMsg = errData.message || errData.error || message;
        } catch (e) { }
        throw new Error(errorMsg || `HTTP error! status: ${res.status}`);
      }
      addNotification(`${isDir ? 'Folder' : 'File'} "${newItemNameTrimmed}" created successfully in "${parentPath || 'root'}".`, 'success');
      cancelCreateItem();
      await refreshFileSystem(fullPath);
      if (parentPath) {
         await fetchFiles(parentPath);
      }
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : String(err);
      addNotification(`Failed to create ${isDir ? 'folder' : 'file'}: ${errorMessage}`, 'error');
    } finally {
      setLoading(false);
    }
  }

  function getFileIconPath(fileItem, isFolderOpen) {
    const baseIconPath = './icons/';
    const nameLower = fileItem.name.toLowerCase();
    if (fileItem.isDir) {
      if (nameLower === '.git') {
        return `${baseIconPath}git.svg`;
      }
      return isFolderOpen ? `${baseIconPath}folder-open.svg` : `${baseIconPath}folder.svg`;
    }
    if (nameLower === 'exocore.run') { return `${baseIconPath}exocore.run.svg`; }
    if (nameLower === '.gitignore' || nameLower === '.gitattributes' || nameLower === '.gitmodules') {
      return `${baseIconPath}git.svg`;
    }
    const parts = nameLower.split('.');
    let extension = '';
    if (parts.length > 1) {
      const potentialExtension = parts.pop();
      if (parts[0] !== '' || parts.length > 0) {
          if (potentialExtension !== undefined) {
            extension = potentialExtension;
          }
      } else if (potentialExtension !== undefined) {
          extension = potentialExtension;
      }
    }
    switch (extension) {
      case 'js': return `${baseIconPath}js.svg`;
      case 'jsx': return `${baseIconPath}jsx.svg`;
      case 'ts': return `${baseIconPath}ts.svg`;
      case 'tsx': return `${baseIconPath}tsx.svg`;
      case 'json': return `${baseIconPath}json.svg`;
      case 'xml': return `${baseIconPath}xml.svg`;
      case 'html': return `${baseIconPath}html.svg`;
      case 'css': return `${baseIconPath}css.svg`;
      case 'md': return `${baseIconPath}md.svg`;
      case 'sh': return `${baseIconPath}sh.svg`;
      case 'sql': return `${baseIconPath}sql.svg`;
      case 'zip': return `${baseIconPath}zip.svg`;
      case 'gif': return `${baseIconPath}gifImage.svg`;
      case 'jpg':
      case 'jpeg':
      case 'png':
        return `${baseIconPath}image.svg`;
      case 'mp4':
      case 'mov':
      case 'avi':
      case 'mkv':
      case 'webm':
      case 'flv':
      case 'wmv':
        return `${baseIconPath}video.svg`;
      case 'git':
        return `${baseIconPath}git.svg`;
      default:
        return `${baseIconPath}undefined.svg`;
    }
  }

  function renderFiles(list, parentPath = '') {
    return (
      <ul style={{ 'margin-left': '1rem', 'padding-left': '0', 'list-style-type': 'none' }}>
        <For each={list}>
          {(file) => {
            const fullPath = parentPath ? `${parentPath}/${file.name}` : file.name;
            const isDirOpen = file.isDir && openFolders()[fullPath];
            const iconPath = getFileIconPath(file, isDirOpen);
            let listItemRef;
            const baseItemStyle = {
              'user-select': 'none',
              padding: '0.2rem 0.1rem',
              'border-radius': theme.borderRadius,
              transition: 'background-color 0.2s',
              'margin-bottom': '2px',
            };

            return (
              <li
                ref={listItemRef}
                style={baseItemStyle}
                onMouseEnter={() => { if (listItemRef) listItemRef.style.backgroundColor = theme.itemHoverBg; }}
                onMouseLeave={() => { if (listItemRef) listItemRef.style.backgroundColor = 'transparent'; }}
                title={fullPath}
              >
                <div style={{ display: 'flex', 'align-items': 'center', 'justify-content': 'space-between' }}>
                  <div
                    onClick={() => handleFileClick(file, fullPath)}
                    style={{ flexGrow: 1, display: 'flex', 'align-items': 'center', cursor: 'pointer', padding: '0.3rem 0.2rem' }}
                  >
                    <img src={iconPath} alt={file.isDir ? 'Folder' : 'File'} style={{ width: '18px', height: '18px', 'margin-right': '0.75rem', 'flex-shrink': 0 }} />
                    <span style={{ color: theme.text, 'font-size': '1.05rem' }}>{file.name}</span>
                  </div>
                  <span
                    onClick={(e) => handleContextMenu(e, file, fullPath)}
                    style={{ cursor: 'pointer', 'font-weight': 'bold', padding: '0 0.5rem', color: theme.textMuted, 'font-size': '1.2rem' }}
                    onMouseEnter={(e) => e.target.style.color = theme.primary}
                    onMouseLeave={(e) => e.target.style.color = theme.textMuted}
                  > ⋮ </span>
                </div>
                <Show when={file.isDir && openFolders()[fullPath] && Array.isArray(openFolders()[fullPath]) && openFolders()[fullPath].length > 0}>
                  {renderFiles(openFolders()[fullPath], fullPath)}
                </Show>
                <Show when={file.isDir && openFolders()[fullPath] && Array.isArray(openFolders()[fullPath]) && openFolders()[fullPath].length === 0}>
                  <div style={{ 'margin-left': '2rem', padding: '0.3rem 0', color: theme.textMuted, 'font-style': 'italic', 'font-size': '0.9rem' }}>(empty folder)</div>
                </Show>
              </li>
            );
          }}
        </For>
      </ul>
    );
  }

  function handleDownloadAll() {
    const form = document.createElement('form');
    form.method = 'POST';
    form.action = `${linkManager}/download-zip`;
    form.style.display = 'none';
    document.body.appendChild(form);
    form.submit();
    document.body.removeChild(form);
    addNotification('Downloading all files (root) as ZIP...', 'info');
  }

  const getCodeMirrorLanguageSupport = (filename) => {
    const extension = filename?.split('.').pop()?.toLowerCase();
    if (!extension) return javascript();
    switch (extension) {
      case 'js': case 'jsx': return javascript();
      case 'ts': case 'tsx': return javascript({typescript: true, jsx: true});
      case 'json': return json();
      case 'html': case 'htm': case 'xml': case 'svg': return html();
      case 'css': return css();
      case 'md': case 'markdown': return markdown();
      default: return javascript();
    }
  };

  onMount(() => {
    const patrickHandFontLink = document.createElement('link');
    patrickHandFontLink.href = 'https://fonts.googleapis.com/css2?family=Patrick+Hand&display=swap';
    patrickHandFontLink.rel = 'stylesheet';
    document.head.appendChild(patrickHandFontLink);

    const firaCodeFontLink = document.createElement('link');
    firaCodeFontLink.href = 'https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500&display=swap';
    firaCodeFontLink.rel = 'stylesheet';
    document.head.appendChild(firaCodeFontLink);

    const hljsThemeLink = document.createElement('link');
    hljsThemeLink.href = 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css';
    hljsThemeLink.rel = 'stylesheet';
    document.head.appendChild(hljsThemeLink);

    const appElement = document.getElementById('app');
    if (appElement) {
        appElement.style.fontFamily = theme.fontFamily;
        appElement.style.minHeight = '100vh';
    }

    fetchUserInfo();

    const handleClickOutside = (e) => {
      const contextMenuElement = document.getElementById('context-menu');
      const createItemModalOverlayElement = document.querySelector('.create-item-modal-overlay');
      const renameModalOverlayElement = document.querySelector('.rename-modal-overlay');

      if (contextMenu().visible && contextMenuElement && !contextMenuElement.contains(e.target)) {
        setContextMenu({ visible: false, x: 0, y: 0, file: null });
      }
      if (createItemModalInfo().visible && createItemModalOverlayElement && e.target === createItemModalOverlayElement) {
        cancelCreateItem();
      }
      if (renameContainerInfo().visible && renameModalOverlayElement && e.target === renameModalOverlayElement) {
        cancelRename();
      }
    };
    document.addEventListener('click', handleClickOutside);

    const checkMobile = () => setIsMobileView(window.innerWidth < 768);
    checkMobile();
    window.addEventListener('resize', checkMobile);

    onCleanup(() => {
      window.removeEventListener('resize', checkMobile);
      document.removeEventListener('click', handleClickOutside);
      if (editorViewInstance) {
        editorViewInstance.destroy();
        editorViewInstance = null;
      }
    });
  });

  createEffect(() => {
    const currentFile = selectedFile();
    const editing = isEditingFile();
    const content = fileContent();

    if (editorRef && editing && currentFile) {
      const cmLanguageSupport = getCodeMirrorLanguageSupport(currentFile);
      if (editorViewInstance) {
        if (editorViewInstance.state.doc.toString() !== content) {
            editorViewInstance.dispatch({
                changes: { from: 0, to: editorViewInstance.state.doc.length, insert: content || '' }
            });
        }
        editorViewInstance.dispatch({
          effects: [
            languageCompartment.reconfigure(cmLanguageSupport),
            editableCompartment.reconfigure(EditorView.editable.of(true)),
          ]
        });
      } else {
        const state = EditorState.create({
          doc: content || '',
          extensions: [
            EditorView.lineWrapping,
            history(),
            keymap.of([...defaultKeymap, ...historyKeymap, ...foldKeymap]),
            lineNumbers(),
            foldGutter(),
            lintGutter(),
            editableCompartment.of(EditorView.editable.of(true)),
            languageCompartment.of(cmLanguageSupport),
            themeCompartment.of(oneDark),
            syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
            EditorView.theme({
                '&': { fontSize: '12px' },
                '.cm-content': { fontFamily: theme.monospaceFontFamily },
                '.cm-gutters': { fontSize: '13px', backgroundColor: '#282c34' },
                '.cm-lineNumbers .cm-gutterElement': { padding: '0 3px 0 5px', minWidth: '20px', textAlign: 'right' }
            }),
            EditorView.updateListener.of(update => {
              if (update.docChanged) {
                if (update.transactions.some(tr => tr.isUserEvent('input') || tr.isUserEvent('delete'))) {
                    setFileContent(update.state.doc.toString());
                }
              }
            })
          ]
        });
        editorViewInstance = new EditorView({ state, parent: editorRef });
      }
    } else if (editorViewInstance) {
      editorViewInstance.destroy();
      editorViewInstance = null;
    }
  });

  let hasFocusedRenameInput = false;
  createEffect(() => {
    if (renameContainerInfo().visible && renameInputRef && !hasFocusedRenameInput) {
      setTimeout(() => {
        if (renameInputRef) {
          renameInputRef.focus();
          renameInputRef.select();
        }
        hasFocusedRenameInput = true;
      }, 50);
    } else if (!renameContainerInfo().visible) {
      hasFocusedRenameInput = false;
    }
  });

  let hasFocusedCreateItemInput = false;
  createEffect(() => {
    if (createItemModalInfo().visible && createItemInputRef && !hasFocusedCreateItemInput) {
      setTimeout(() => {
        if (createItemInputRef) {
           createItemInputRef.focus();
        }
        hasFocusedCreateItemInput = true;
      }, 50);
    } else if (!createItemModalInfo().visible) {
      hasFocusedCreateItemInput = false;
    }
  });

  const theme = {
    bg: '#0F172A',
    panelBg: '#1E293B',
    border: '#334155',
    text: '#E2E8F0',
    textMuted: '#94A3B8',
    primary: '#38BDF8',
    primaryHover: '#0EA5E9',
    primaryText: '#0F172A',
    secondary: '#FACC15',
    secondaryHover: '#EAB308',
    secondaryText: '#1E293B',
    destructive: '#F43F5E',
    destructiveHover: '#E11D48',
    destructiveText: '#E2E8F0',
    inputBg: '#0A0F1A',
    inputBorder: '#334155',
    inputFocusBorder: '#38BDF8',
    fontFamily: "'Patrick Hand', cursive",
    monospaceFontFamily: "'Fira Code', 'Source Code Pro', monospace",
    borderRadius: '6px',
    itemHoverBg: 'rgba(51, 65, 85, 0.7)',
    shadow: '0 6px 16px rgba(0, 0, 0, 0.4)',
    itemSelectedBg: '#38BDF8',
    notificationSuccess: '#10B981',
    notificationError: '#F43F5E',
    notificationInfo: '#38BDF8',
  };

  const NotificationContainer = () => {
    const baseStyle = {
        padding: '1rem 1.5rem',
        'margin-bottom': '0.75rem',
        'border-radius': theme.borderRadius,
        color: 'white',
        'font-size': '1.05rem',
        'box-shadow': '0 4px 10px rgba(0,0,0,0.3)',
        'font-family': theme.fontFamily,
        'letter-spacing': '0.5px',
        transition: 'transform 0.3s ease-out, opacity 0.3s ease-out',
        transform: 'translateX(0)',
        opacity: 1,
    };

    const typeStyles = {
        success: { 'background-color': theme.notificationSuccess },
        error: { 'background-color': theme.notificationError },
        info: { 'background-color': theme.notificationInfo, color: theme.primaryText },
    };

    return (
        <div style={{ position: 'fixed', top: '20px', right: '20px', 'z-index': '2000', width: '350px', 'max-width': '90%' }}>
            <For each={notifications()}>
                {notification => (
                    <div style={{ ...baseStyle, ...typeStyles[notification.type] }}>
                        {notification.message}
                    </div>
                )}
            </For>
        </div>
    );
  };

  const baseButtonStyle = {
    padding: '0.6rem 1.2rem',
    'font-size': '1.1rem',
    border: 'none',
    'border-radius': theme.borderRadius,
    cursor: 'pointer',
    'font-family': theme.fontFamily,
    'letter-spacing': '0.5px',
    transition: 'background-color 0.2s, transform 0.1s',
    'margin-right': '0.5rem',
    'line-height': '1.4',
  };

  const createButtonStyler = (baseColor, hoverColor, textColor) => {
    let btnRef;
    return {
      ref: el => btnRef = el,
      style: { ...baseButtonStyle, background: baseColor, color: textColor },
      onMouseEnter: () => btnRef && (btnRef.style.backgroundColor = hoverColor),
      onMouseLeave: () => btnRef && (btnRef.style.backgroundColor = baseColor),
    };
  };

  const primaryButtonProps = (text, onClick) => {
    const { ref, style, onMouseEnter, onMouseLeave } = createButtonStyler(theme.primary, theme.primaryHover, theme.primaryText);
    return <button ref={ref} style={style} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} onClick={onClick}>{text}</button>;
  };

  const secondaryButtonProps = (text, onClick) => {
    const { ref, style, onMouseEnter, onMouseLeave } = createButtonStyler(theme.secondary, theme.secondaryHover, theme.secondaryText);
    return <button ref={ref} style={style} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} onClick={onClick}>{text}</button>;
  };

  const destructiveButtonProps = (text, onClick) => {
    const { ref, style, onMouseEnter, onMouseLeave } = createButtonStyler(theme.destructive, theme.destructiveHover, theme.destructiveText);
    return <button ref={ref} style={style} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} onClick={onClick}>{text}</button>;
  };

  const defaultButtonProps = (text, onClick, additionalStyles = {}) => {
    const { ref, style, onMouseEnter, onMouseLeave } = createButtonStyler(theme.panelBg, theme.border, theme.textMuted);
    return <button ref={ref} style={{...style, border: `1px solid ${theme.border}`, ...additionalStyles}} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} onClick={onClick}>{text}</button>;
  };

  const iconButtonStyler = (baseColor, hoverColor, textColor) => {
    let btnRef;
    const iconBaseStyle = { ...baseButtonStyle, padding: '0.5rem 0.7rem', 'font-size': '1.5rem', 'line-height': '1', 'margin-right': '0' };
    return {
      ref: el => btnRef = el,
      style: { ...iconBaseStyle, background: baseColor, color: textColor, border: `1px solid ${theme.border}`},
      onMouseEnter: () => btnRef && (btnRef.style.backgroundColor = hoverColor),
      onMouseLeave: () => btnRef && (btnRef.style.backgroundColor = baseColor),
    };
  };

  const inputStyle = {
    padding: '0.7rem 0.9rem',
    'font-size': '1.05rem',
    border: `1px solid ${theme.inputBorder}`,
    'border-radius': theme.borderRadius,
    flex: '1',
    'margin-right': '0.5rem',
    'font-family': theme.fontFamily,
    'background-color': theme.inputBg,
    color: theme.text,
    outline: 'none',
    transition: 'border-color 0.2s, box-shadow 0.2s',
    'letter-spacing': '0.5px',
  };

  const modalInputStyle = {
      ...inputStyle,
      width: 'calc(100% - 22px)',
      'margin-bottom': '20px',
      'margin-right': '0',
      'font-size': '1.1rem',
  };

  const codeViewerBaseStyle = {
      width: '100%',
      fontFamily: theme.monospaceFontFamily,
      border: `1px solid ${theme.border}`,
      padding: '15px',
      boxSizing: 'border-box',
      flex: '1',
      marginBottom: '15px',
      minHeight: isMobileView() ? '250px' : '350px',
      resize: 'vertical',
      overflow: 'auto',
      backgroundColor: '#282c34',
      color: theme.text,
      borderRadius: theme.borderRadius,
      fontSize: '12px',
  };

  const codeMirrorEditorStyle = {
      ...codeViewerBaseStyle,
      padding: '0px',
  };

  return (
    <div style={{ 'font-size': '1.1rem', background: theme.bg, color: theme.text, 'min-height': '100vh', padding: '25px', 'box-sizing': 'border-box' }}>
      <NotificationContainer />
      <h2 style={{ color: theme.primary, 'font-size': '2.8rem', 'margin-bottom': '25px', 'text-align': 'center', 'letter-spacing': '1px' }}>
        📁 ExoCore Explorer 📂
      </h2>

      <Show when={status()}>
        <div class="status-box" style={{ 'background-color': theme.panelBg, border: `1px solid ${theme.border}`, color: theme.text, padding: '12px 18px', 'margin-bottom': '1.5rem', 'border-radius': theme.borderRadius, display: 'flex', 'align-items': 'center', 'justify-content': 'space-between', 'box-shadow': '0 2px 5px rgba(0,0,0,0.2)', 'font-size': '1.05rem' }}>
          {status()}
          {defaultButtonProps('Clear', () => setStatus(''), { padding: '0.2rem 0.5rem', 'margin-left': '10px', 'font-size': '0.9rem' })}
        </div>
      </Show>

      <Show when={loading() && !(isMobileView() && selectedFile())}>
         <div style={{ 'margin-top': '1.5rem', color: theme.textMuted, 'font-size': '1.2rem', 'text-align': 'center' }}>Loading... ⏳ Please wait...</div>
      </Show>

      <div class="main-content-flex" style={{ display: 'flex', 'margin-top': '1.5rem', gap: '25px', 'flex-wrap': (isMobileView() && selectedFile()) ? 'wrap' : 'nowrap' }}>
        <div class="file-list-panel" style={{ ...(isMobileView() && selectedFile() ? {display: 'none'} : {flex: '1'}), border: `1px solid ${theme.border}`, padding: '20px', background: theme.panelBg, 'min-width': '320px', color: theme.text, 'border-radius': theme.borderRadius, 'box-shadow': theme.shadow }}>
          <h4 style={{ color: theme.primary, 'font-size': '1.5rem', 'margin-top': '0', 'margin-bottom': '1rem', 'border-bottom': `1px solid ${theme.border}`, 'padding-bottom': '0.5rem' }}>Controls</h4>
          <div style={{ 'margin-bottom': '0.8rem', display: 'flex', 'align-items': 'center', gap: '0.5rem' }}>
            <input style={inputStyle} placeholder="New file name..." value={newFileName()} onInput={e => setNewFileName(e.target.value)} onKeyPress={e => e.key === 'Enter' && createFile()} onFocus={e => e.target.style.borderColor = theme.inputFocusBorder} onBlur={e => e.target.style.borderColor = theme.inputBorder} />
            {(() => {
                const { ref, style, onMouseEnter, onMouseLeave } = iconButtonStyler(theme.panelBg, theme.border, theme.primary);
                return <button ref={ref} style={style} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} onClick={createFile} title="Create File">📄</button>;
            })()}
          </div>
          <div style={{ 'margin-bottom': '0.8rem', display: 'flex', 'align-items': 'center', gap: '0.5rem' }}>
            <input style={inputStyle} placeholder="New folder name..." value={newFolderName()} onInput={e => setNewFolderName(e.target.value)} onKeyPress={e => e.key === 'Enter' && createFolder()} onFocus={e => e.target.style.borderColor = theme.inputFocusBorder} onBlur={e => e.target.style.borderColor = theme.inputBorder} />
            {(() => {
                const { ref, style, onMouseEnter, onMouseLeave } = iconButtonStyler(theme.panelBg, theme.border, theme.primary);
                return <button ref={ref} style={style} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} onClick={createFolder} title="Create Folder">📁</button>;
            })()}
          </div>
          <div style={{ 'margin-bottom': '1.5rem' }}>
            {(() => {
              const { ref, style, onMouseEnter, onMouseLeave } = createButtonStyler(theme.primary, theme.primaryHover, theme.primaryText);
              return <label for="fileUpload" ref={ref} style={{...style, display: 'inline-block', width: '100%', 'box-sizing': 'border-box', 'text-align': 'center', 'margin-right': 0}} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>📤 Upload File</label>;
            })()}
            <input id="fileUpload" type="file" onChange={uploadFile} style={{display: 'none'}} />
          </div>

          <h4 style={{ color: theme.primary, 'font-size': '1.5rem', 'margin-bottom': '1rem', 'border-bottom': `1px solid ${theme.border}`, 'padding-bottom': '0.5rem' }}>File System</h4>
          <div style={{ 'max-height': '450px', 'overflow-y': 'auto', border: `1px solid ${theme.border}`, padding: '10px', 'border-radius': theme.borderRadius, background: theme.inputBg }}>
            {renderFiles(files())}
          </div>
          <div style={{'margin-top': '1.5rem'}}>
            {secondaryButtonProps('Download All (Root) as ZIP 📦', handleDownloadAll)}
          </div>
        </div>

        <div class="file-editor-panel" style={ isMobileView() && selectedFile() ? { position: 'fixed', top: '0', left: '0', width: '100%', height: '100%', background: 'rgba(15, 23, 42, 0.9)', display: 'flex', 'align-items': 'center', 'justify-content': 'center', 'z-index': '1001', padding: '15px', 'box-sizing': 'border-box' } : { flex: '3.5', 'min-width': '0', display: selectedFile() ? 'flex' : 'block', 'flex-direction': 'column' } }>
          <Show when={selectedFile()} fallback={ !isMobileView() || (isMobileView() && !selectedFile()) ? <div style={{ border: `2px dashed ${theme.border}`, padding: '30px', 'text-align': 'center', background: theme.panelBg, color: theme.textMuted, height: '100%', display: 'flex', 'align-items': 'center', 'justify-content': 'center', 'border-radius': theme.borderRadius, 'font-size': '1.3rem', 'box-shadow': theme.shadow }}>Select a file to embark on an editing adventure! 🚀</div> : null }>
            <div style={ isMobileView() ? { background: theme.panelBg, padding: '20px', 'border-radius': theme.borderRadius, 'box-shadow': theme.shadow, width: '100%', height: 'auto', 'max-height': 'calc(100vh - 40px)', display: 'flex', 'flex-direction': 'column', 'overflow-y': 'auto', color: theme.text, border: `1px solid ${theme.border}` } : { border: `1px solid ${theme.border}`, padding: '20px', background: theme.panelBg, height: '100%', display: 'flex', 'flex-direction': 'column', color: theme.text, 'border-radius': theme.borderRadius, 'box-shadow': theme.shadow } }>
              <h3 style={{ 'margin-top': '0', color: theme.primary, 'font-size': '1.6rem', 'margin-bottom': '1rem', 'word-break': 'break-all' }}>
                Now Editing: {selectedFile()}
              </h3>
              <div ref={el => editorRef = el} style={codeMirrorEditorStyle}></div>
              <div style={{ 'text-align': 'right', 'margin-top': '10px', display: 'flex', 'justify-content': 'flex-end', gap: '0.5rem' }}>
                  {primaryButtonProps('💾 Save', saveFile)}
                  {destructiveButtonProps('❌ Close', closeFileEditor)}
              </div>
            </div>
          </Show>
        </div>
      </div>

      <Show when={contextMenu().visible}>
        <div id="context-menu" style={{ position: 'fixed', top: `${contextMenu().y}px`, left: `${contextMenu().x}px`, background: theme.panelBg, border: `1px solid ${theme.border}`, padding: '0.4rem', 'z-index': '1000', 'box-shadow': '0 5px 15px rgba(0,0,0,0.5)', 'min-width': '170px', 'text-align': 'left', color: theme.text, 'border-radius': theme.borderRadius, transform: contextMenu().x > (window.innerWidth - 200) ? 'translateX(-100%)' : 'none' }}>
          {[
            { label: '✏️ Rename', action: handleRenameClick, show: () => true },
            { label: '📂 Open', action: handleOpenFolderFromContextMenu, show: () => contextMenu().file?.isDir },
            { label: '➕📄 Add New File', action: () => handleShowCreateItemModal(false), show: () => contextMenu().file?.isDir || !contextMenu().file },
            { label: '➕📁 Add New Folder', action: () => handleShowCreateItemModal(true), show: () => contextMenu().file?.isDir || !contextMenu().file },
            { label: '⬇️ Download', action: handleDownloadSelected, show: () => contextMenu().file && !contextMenu().file.isDir },
            {
              label: '🌀 Unzip Here',
              action: handleUnzipSelected,
              show: () => {
                const file = contextMenu().file;
                return file && !file.isDir && file.name.toLowerCase().endsWith('.zip');
              }
            },
            { label: '🗑️ Delete', action: handleDeleteSelected, show: () => contextMenu().file, color: theme.destructive },
          ].map(item => (
            <Show when={item.show()}>
              <div
                style={{ cursor: 'pointer', padding: '0.5rem 0.7rem', 'white-space': 'nowrap', color: item.color || theme.text, 'border-radius': '4px', transition: 'background-color 0.15s', 'font-size': '0.9rem' }}
                onClick={item.action}
                onMouseEnter={e => e.target.style.backgroundColor = theme.itemHoverBg}
                onMouseLeave={e => e.target.style.backgroundColor = 'transparent'}
              >
                {item.label}
              </div>
            </Show>
          ))}
          <Show when={contextMenu().file}>
            <div style={{ 'font-size': '0.8em', color: theme.textMuted, 'margin-top': '6px', 'border-top': `1px solid ${theme.border}`, 'padding-top': '6px' }}>
                {contextMenu().file.name} ({contextMenu().file.isDir ? 'Folder' : 'File'})
            </div>
          </Show>
        </div>
      </Show>

      <Show when={renameContainerInfo().visible}>
        <div class="rename-modal-overlay" style={{ position: 'fixed', top: '0', left: '0', width: '100%', height: '100%', background: 'rgba(15, 23, 42, 0.85)', display: 'flex', 'justify-content': 'center', 'align-items': 'center', 'z-index': '1002' }}>
          <div class="rename-modal-content" style={{ background: theme.panelBg, padding: '25px', 'border-radius': theme.borderRadius, 'box-shadow': theme.shadow, 'text-align': 'center', 'min-width': '320px', 'max-width': '90%', 'box-sizing': 'border-box', position: 'relative', color: theme.text, border: `1px solid ${theme.border}` }} onClick={e => e.stopPropagation()}>
            <h3 style={{ color: theme.primary, 'margin-top': 0, 'margin-bottom': '20px', 'font-size': '1.5rem' }}>Rename "{renameContainerInfo().file?.name}"</h3>
            <input ref={el => renameInputRef = el} style={modalInputStyle} value={renameContainerInfo().newName} onInput={e => setRenameContainerInfo(prev => ({ ...prev, newName: e.target.value }))} onKeyPress={e => e.key === 'Enter' && performRename()} onFocus={e => e.target.style.borderColor = theme.inputFocusBorder} onBlur={e => e.target.style.borderColor = theme.inputBorder} />
            <div style={{ display: 'flex', 'justify-content': 'center', gap: '10px', 'margin-top': '10px' }}>
              {primaryButtonProps('✔️ Confirm', performRename)}
              {destructiveButtonProps('✖️ Cancel', cancelRename)}
            </div>
          </div>
        </div>
      </Show>

      <Show when={createItemModalInfo().visible}>
        <div class="create-item-modal-overlay" style={{ position: 'fixed', top: '0', left: '0', width: '100%', height: '100%', background: 'rgba(15, 23, 42, 0.85)', display: 'flex', 'justify-content': 'center', 'align-items': 'center', 'z-index': '1002' }}>
          <div class="create-item-modal-content" style={{ background: theme.panelBg, padding: '25px', 'border-radius': theme.borderRadius, 'box-shadow': theme.shadow, 'text-align': 'center', 'min-width': '360px', 'max-width': '90%', 'box-sizing': 'border-box', position: 'relative', color: theme.text, border: `1px solid ${theme.border}` }} onClick={e => e.stopPropagation()}>
            <h3 style={{ color: theme.primary, 'margin-top': 0, 'margin-bottom': '20px', 'font-size': '1.4rem' }}> Create New {createItemModalInfo().isDir ? 'Folder' : 'File'} in "{createItemModalInfo().parentPath || 'root'}" </h3>
            <input ref={el => createItemInputRef = el} style={modalInputStyle} placeholder={createItemModalInfo().isDir ? 'New folder name...' : 'New file name (e.g., script.js)'} value={createItemModalInfo().itemName} onInput={e => setCreateItemModalInfo(prev => ({ ...prev, itemName: e.target.value }))} onKeyPress={e => e.key === 'Enter' && performCreateItem()} onFocus={e => e.target.style.borderColor = theme.inputFocusBorder} onBlur={e => e.target.style.borderColor = theme.inputBorder} />
            <div style={{ display: 'flex', 'justify-content': 'center', gap: '10px', 'margin-top': '10px' }}>
              {primaryButtonProps('✔️ Create', performCreateItem)}
              {destructiveButtonProps('✖️ Cancel', cancelCreateItem)}
            </div>
          </div>
        </div>
      </Show>

    </div>
  );
}

render(() => <App />, document.getElementById('app'));
