<script lang="ts">
  import { onMount, onDestroy } from "svelte";
  import { editorStore } from "$lib/stores/editor";
  import FileTreeItem from "./FileTreeItem.svelte";
  import FileContextMenu from "./FileContextMenu.svelte";
  import InputDialog from "./InputDialog.svelte";
  import ConfirmDialog from "./ConfirmDialog.svelte";
  import type { FileEntry } from "$lib/types/editor";

  const fileTree = editorStore.fileTree;
  const isLoadingTree = editorStore.isLoadingTree;
  const currentDirectory = editorStore.currentDirectory;

  // Listen for Ctrl+N keyboard shortcut from +page.svelte
  function handleNewFileEvent() {
    handleNewFile();
  }

  onMount(() => {
    window.addEventListener("editor-new-file", handleNewFileEvent);
  });

  onDestroy(() => {
    window.removeEventListener("editor-new-file", handleNewFileEvent);
  });

  // Context menu state
  let contextMenu = $state<{
    show: boolean;
    x: number;
    y: number;
    targetEntry: FileEntry | null;
  }>({
    show: false,
    x: 0,
    y: 0,
    targetEntry: null,
  });

  // Dialog state
  let dialog = $state<{
    type: "newFile" | "newFolder" | "delete" | "rename" | null;
    parentPath: string;
    targetEntry: FileEntry | null;
  }>({
    type: null,
    parentPath: "",
    targetEntry: null,
  });

  function handleRefresh() {
    const dir = $currentDirectory;
    if (dir) {
      editorStore.initializeFileTree(dir);
    }
  }

  function handleContextMenu(event: MouseEvent, entry: FileEntry | null = null) {
    event.preventDefault();
    contextMenu = {
      show: true,
      x: event.clientX,
      y: event.clientY,
      targetEntry: entry,
    };
  }

  function closeContextMenu() {
    contextMenu = { show: false, x: 0, y: 0, targetEntry: null };
  }

  function openNewFileDialog(parentPath: string) {
    dialog = { type: "newFile", parentPath, targetEntry: null };
  }

  function openNewFolderDialog(parentPath: string) {
    dialog = { type: "newFolder", parentPath, targetEntry: null };
  }

  function openDeleteDialog(entry: FileEntry) {
    dialog = { type: "delete", parentPath: "", targetEntry: entry };
  }

  function openRenameDialog(entry: FileEntry) {
    dialog = { type: "rename", parentPath: "", targetEntry: entry };
  }

  function closeDialog() {
    dialog = { type: null, parentPath: "", targetEntry: null };
  }

  async function handleCreateFile(fileName: string) {
    await editorStore.createFile(dialog.parentPath, fileName);
    closeDialog();
  }

  async function handleCreateFolder(folderName: string) {
    await editorStore.createDirectory(dialog.parentPath, folderName);
    closeDialog();
  }

  async function handleDelete() {
    if (!dialog.targetEntry) return;

    if (dialog.targetEntry.isDirectory) {
      await editorStore.deleteDirectory(dialog.targetEntry.path);
    } else {
      await editorStore.deleteFile(dialog.targetEntry.path);
    }
    closeDialog();
  }

  async function handleRename(newName: string) {
    if (!dialog.targetEntry) return;
    await editorStore.renamePath(dialog.targetEntry.path, newName);
    closeDialog();
  }

  function handleNewFile() {
    openNewFileDialog($currentDirectory);
  }

  function handleNewFolder() {
    openNewFolderDialog($currentDirectory);
  }
</script>

<!-- svelte-ignore a11y_no_static_element_interactions -->
<div class="file-browser" oncontextmenu={(e) => handleContextMenu(e, null)}>
  <div class="header">
    <span class="title">Files</span>
    <div class="header-buttons">
      <button class="header-button" onclick={handleNewFile} title="New File (Ctrl+N)">
        <svg
          width="14"
          height="14"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
        >
          <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
          <path d="M14 2v6h6" />
          <path d="M12 18v-6" />
          <path d="M9 15h6" />
        </svg>
      </button>
      <button class="header-button" onclick={handleNewFolder} title="New Folder">
        <svg
          width="14"
          height="14"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
        >
          <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" />
          <path d="M12 11v6" />
          <path d="M9 14h6" />
        </svg>
      </button>
      <button class="header-button" onclick={handleRefresh} title="Refresh file tree">
        <svg
          width="14"
          height="14"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
        >
          <path d="M23 4v6h-6" />
          <path d="M1 20v-6h6" />
          <path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15" />
        </svg>
      </button>
    </div>
  </div>

  <div class="tree-container">
    {#if $isLoadingTree}
      <div class="loading">
        <svg
          class="spinner"
          width="20"
          height="20"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
        >
          <circle cx="12" cy="12" r="10" stroke-dasharray="32" stroke-dashoffset="32">
            <animate
              attributeName="stroke-dashoffset"
              dur="1s"
              values="32;0"
              repeatCount="indefinite"
            />
          </circle>
        </svg>
        <span>Loading...</span>
      </div>
    {:else if $fileTree.length === 0}
      <div class="empty">
        <span>No files found</span>
      </div>
    {:else}
      <div class="tree">
        {#each $fileTree as entry (entry.path)}
          <FileTreeItem {entry} onContextMenu={handleContextMenu} />
        {/each}
      </div>
    {/if}
  </div>
</div>

{#if contextMenu.show}
  <FileContextMenu
    x={contextMenu.x}
    y={contextMenu.y}
    targetEntry={contextMenu.targetEntry}
    currentDirectory={$currentDirectory}
    onNewFile={openNewFileDialog}
    onNewFolder={openNewFolderDialog}
    onRename={openRenameDialog}
    onDelete={openDeleteDialog}
    onClose={closeContextMenu}
  />
{/if}

{#if dialog.type === "newFile"}
  <InputDialog
    title="New File"
    placeholder="Enter file name..."
    confirmText="Create"
    onConfirm={handleCreateFile}
    onCancel={closeDialog}
  />
{/if}

{#if dialog.type === "newFolder"}
  <InputDialog
    title="New Folder"
    placeholder="Enter folder name..."
    confirmText="Create"
    onConfirm={handleCreateFolder}
    onCancel={closeDialog}
  />
{/if}

{#if dialog.type === "delete" && dialog.targetEntry}
  <ConfirmDialog
    title="Delete {dialog.targetEntry.isDirectory ? 'Folder' : 'File'}"
    message="Are you sure you want to delete '{dialog.targetEntry.name}'? {dialog.targetEntry
      .isDirectory
      ? 'This will also delete all files and folders inside it.'
      : 'This action cannot be undone.'}"
    confirmText="Delete"
    destructive={true}
    onConfirm={handleDelete}
    onCancel={closeDialog}
  />
{/if}

{#if dialog.type === "rename" && dialog.targetEntry}
  <InputDialog
    title="Rename {dialog.targetEntry.isDirectory ? 'Folder' : 'File'}"
    placeholder="Enter new name..."
    confirmText="Rename"
    initialValue={dialog.targetEntry.name}
    onConfirm={handleRename}
    onCancel={closeDialog}
  />
{/if}

<style>
  .file-browser {
    display: flex;
    flex-direction: column;
    height: 100%;
    background-color: var(--bg-primary);
    border-right: 1px solid var(--border-color);
  }

  .header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 12px;
    border-bottom: 1px solid var(--border-color);
    background-color: var(--bg-secondary);
  }

  .title {
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    color: var(--text-secondary);
    letter-spacing: 0.5px;
  }

  .header-buttons {
    display: flex;
    gap: 4px;
  }

  .header-button {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 4px;
    background: transparent;
    border: none;
    color: var(--text-secondary);
    cursor: pointer;
    border-radius: 4px;
    transition: all 0.15s ease;
  }

  .header-button:hover {
    background-color: var(--bg-primary);
    color: var(--text-primary);
  }

  .tree-container {
    flex: 1;
    overflow-y: auto;
    padding: 4px 0;
  }

  .tree {
    min-width: max-content;
  }

  .loading,
  .empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 24px;
    color: var(--text-secondary);
    font-size: 13px;
  }

  .spinner {
    animation: spin 1s linear infinite;
  }

  @keyframes spin {
    from {
      transform: rotate(0deg);
    }
    to {
      transform: rotate(360deg);
    }
  }
</style>
