<script lang="ts">
  import type { FileEntry } from "$lib/types/editor";
  import { editorStore } from "$lib/stores/editor";
  import Self from "./FileTreeItem.svelte";

  interface Props {
    entry: FileEntry;
    depth?: number;
    onContextMenu?: (event: MouseEvent, entry: FileEntry) => void;
  }

  let { entry, depth = 0, onContextMenu }: Props = $props();

  function handleClick() {
    if (entry.isDirectory) {
      editorStore.toggleDirectory(entry);
    } else {
      editorStore.openFile(entry.path);
    }
  }

  function handleKeydown(event: KeyboardEvent) {
    if (event.key === "Enter" || event.key === " ") {
      event.preventDefault();
      handleClick();
    }
  }

  function handleContextMenu(event: MouseEvent) {
    event.preventDefault();
    event.stopPropagation();
    onContextMenu?.(event, entry);
  }

  const isExpanded = $derived(entry.isExpanded ?? false);
  const isLoading = $derived(entry.isLoading ?? false);
  const children = $derived(entry.children ?? []);
</script>

<div class="file-tree-item">
  <button
    class="item-row"
    class:directory={entry.isDirectory}
    class:file={!entry.isDirectory}
    style="padding-left: {depth * 16 + 8}px"
    onclick={handleClick}
    onkeydown={handleKeydown}
    oncontextmenu={handleContextMenu}
    title={entry.path}
  >
    {#if entry.isDirectory}
      <span class="icon">
        {#if isLoading}
          <svg
            class="spinner"
            width="14"
            height="14"
            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>
        {:else if isExpanded}
          <svg
            width="14"
            height="14"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
          >
            <path d="M6 9l6 6 6-6" />
          </svg>
        {:else}
          <svg
            width="14"
            height="14"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
          >
            <path d="M9 6l6 6-6 6" />
          </svg>
        {/if}
      </span>
      <span class="folder-icon">
        <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor">
          <path
            d="M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"
          />
        </svg>
      </span>
    {:else}
      <span class="icon spacer"></span>
      <span class="file-icon">
        <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" />
          <polyline points="14 2 14 8 20 8" />
        </svg>
      </span>
    {/if}
    <span class="name">{entry.name}</span>
  </button>

  {#if entry.isDirectory && isExpanded && children.length > 0}
    <div class="children">
      {#each children as child (child.path)}
        <Self entry={child} depth={depth + 1} {onContextMenu} />
      {/each}
    </div>
  {/if}
</div>

<style>
  .file-tree-item {
    user-select: none;
  }

  .item-row {
    display: flex;
    align-items: center;
    gap: 4px;
    width: 100%;
    padding: 4px 8px;
    background: transparent;
    border: none;
    color: var(--text-primary);
    font-size: 13px;
    cursor: pointer;
    text-align: left;
    border-radius: 4px;
    transition: background-color 0.15s ease;
  }

  .item-row:hover {
    background-color: var(--bg-secondary);
  }

  .item-row:focus {
    outline: 1px solid var(--accent-primary);
    outline-offset: -1px;
  }

  .icon {
    flex-shrink: 0;
    width: 14px;
    height: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-secondary);
  }

  .icon.spacer {
    visibility: hidden;
  }

  .folder-icon {
    flex-shrink: 0;
    color: var(--accent-primary);
  }

  .file-icon {
    flex-shrink: 0;
    color: var(--text-secondary);
  }

  .name {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .children {
    margin-left: 0;
  }

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

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