<template>
  <div>
    <button
      type="button"
      class="flex w-full items-center gap-1 rounded py-0.5 pr-2 text-left text-xs hover:bg-zinc-800/60"
      :class="isActive ? 'bg-zinc-800 text-zinc-100' : 'text-zinc-300'"
      :style="{ paddingLeft: `${depth * 12 + 6}px` }"
      :title="entry.name"
      @click="onClick"
    >
      <component
        :is="entry.isFile ? File : expanded ? ChevronDown : ChevronRight"
        :size="14"
        class="shrink-0 text-zinc-500"
      />
      <span class="truncate font-mono">{{ entry.name }}</span>
    </button>

    <template v-if="!entry.isFile && expanded">
      <p v-if="loading" class="py-0.5 text-xs text-zinc-600" :style="{ paddingLeft: `${(depth + 1) * 12 + 6}px` }">…</p>
      <p v-else-if="error" class="py-0.5 text-xs text-rose-400" :style="{ paddingLeft: `${(depth + 1) * 12 + 6}px` }">{{ error }}</p>
      <FileTreeNode
        v-for="c in children"
        :key="c.path"
        :entry="c"
        :wt="wt"
        :depth="depth + 1"
        :active="active"
        @open="(p) => emit('open', p)"
      />
    </template>
  </div>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue';
import { ChevronDown, ChevronRight, File } from '@lucide/vue';
import type { FsEntry, FsListResponse } from '@arboretum/shared';
import { api } from '../../lib/api';

const props = defineProps<{ entry: FsEntry; wt: string; depth: number; active: string | null }>();
const emit = defineEmits<{ open: [relPath: string] }>();

const expanded = ref(false);
const loading = ref(false);
const error = ref<string | null>(null);
const children = ref<FsEntry[]>([]);
let loaded = false;

// chemin relatif au worktree (POSIX) : clé utilisée par l'API fichiers / diff.
const relPath = computed(() => (props.entry.path.startsWith(props.wt) ? props.entry.path.slice(props.wt.length + 1) : props.entry.name));
const isActive = computed(() => props.entry.isFile && props.active === relPath.value);

async function loadChildren(): Promise<void> {
  if (loaded) return;
  loading.value = true;
  error.value = null;
  try {
    const res = await api.get<FsListResponse>(`/api/v1/fs/list?path=${encodeURIComponent(props.entry.path)}&includeFiles=1`);
    children.value = sortEntries(res.entries);
    loaded = true;
  } catch (err) {
    error.value = err instanceof Error ? err.message : String(err);
  } finally {
    loading.value = false;
  }
}

function onClick(): void {
  if (props.entry.isFile) {
    emit('open', relPath.value);
    return;
  }
  expanded.value = !expanded.value;
  if (expanded.value) void loadChildren();
}

// dossiers d'abord, puis fichiers, tri alphabétique.
function sortEntries(entries: FsEntry[]): FsEntry[] {
  return [...entries].sort((a, b) => Number(!!a.isFile) - Number(!!b.isFile) || a.name.localeCompare(b.name));
}
</script>
