<template>
  <section class="flex flex-col gap-2 rounded-lg border border-zinc-800 bg-zinc-950/40 p-2">
    <header class="flex items-center gap-2">
      <button type="button" class="btn text-xs" :disabled="loading || parent === null" @click="load(parent ?? undefined)">
        ↑ {{ t('fs.up') }}
      </button>
      <span class="min-w-0 flex-1 truncate font-mono text-xs text-zinc-400" :title="current">{{ current }}</span>
      <button type="button" class="btn text-xs" @click="emit('close')">{{ t('common.cancel') }}</button>
    </header>

    <p v-if="error" class="text-sm text-red-400">{{ error }}</p>

    <ul class="flex max-h-60 flex-col gap-0.5 overflow-y-auto">
      <li v-if="loading" class="px-2 py-1 text-xs text-zinc-500">{{ t('fs.loading') }}</li>
      <li v-else-if="entries.length === 0" class="px-2 py-1 text-xs text-zinc-500">{{ t('fs.empty') }}</li>
      <li v-for="e in entries" :key="e.path">
        <button
          type="button"
          class="flex w-full items-center gap-2 rounded px-2 py-1 text-left text-sm text-zinc-200 hover:bg-zinc-800"
          @click="load(e.path)"
        >
          <span class="flex-1 truncate font-mono">{{ e.name }}</span>
          <span v-if="e.isRepo" class="badge bg-emerald-950 text-emerald-400">{{ t('fs.repoBadge') }}</span>
        </button>
      </li>
    </ul>

    <footer class="flex items-center gap-2">
      <label class="flex items-center gap-1 text-xs text-zinc-400">
        <input v-model="showHidden" type="checkbox" @change="load(current || undefined)" /> {{ t('fs.showHidden') }}
      </label>
      <button type="button" class="btn-primary ml-auto text-xs" :disabled="loading || current === ''" @click="emit('select', current)">
        {{ t('fs.useFolder') }}
      </button>
    </footer>
  </section>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import type { FsEntry, FsListResponse } from '@arboretum/shared';
import { api } from '../lib/api';

// mode 'repo' : annote les sous-dossiers qui sont des dépôts git (badge). 'dir' : navigation simple.
const props = withDefaults(defineProps<{ mode?: 'dir' | 'repo'; initialPath?: string }>(), {
  mode: 'dir',
  initialPath: '',
});
const emit = defineEmits<{ select: [path: string]; close: [] }>();
const { t } = useI18n();

const current = ref('');
const parent = ref<string | null>(null);
const entries = ref<FsEntry[]>([]);
const loading = ref(false);
const error = ref<string | null>(null);
const showHidden = ref(false);

/** path absent → le serveur retombe sur le home. En cas d'erreur, on garde l'écoute précédente affichée. */
async function load(path?: string): Promise<void> {
  loading.value = true;
  error.value = null;
  try {
    const params = new URLSearchParams();
    if (path) params.set('path', path);
    if (props.mode === 'repo') params.set('markRepos', '1');
    if (showHidden.value) params.set('showHidden', '1');
    const res = await api.get<FsListResponse>(`/api/v1/fs/list?${params.toString()}`);
    current.value = res.path;
    parent.value = res.parent;
    entries.value = res.entries;
  } catch (err) {
    error.value = err instanceof Error ? err.message : String(err);
  } finally {
    loading.value = false;
  }
}

onMounted(() => {
  // démarre sur le chemin déjà saisi s'il est absolu, sinon sur le home (path absent).
  void load(props.initialPath.startsWith('/') ? props.initialPath : undefined);
});
</script>
