<template>
  <PageHeader>
    <template #title>
      <BaseButton variant="ghost" size="sm" icon-only :icon="ChevronLeft" :to="{ name: 'groups' }" :aria-label="t('common.back')" />
      <h1 v-if="group" class="flex items-center gap-2 truncate text-lg font-semibold text-zinc-100">
        <span class="h-3 w-3 shrink-0 rounded-full" :style="{ backgroundColor: group.color ?? '#52525b' }" />
        {{ group.label }}
      </h1>
      <span v-else class="text-sm text-zinc-500">{{ t('common.loading') }}</span>
    </template>

    <template v-if="group">
      <BaseButton
        variant="ghost"
        size="sm"
        :icon="Pencil"
        :class="editingRepos ? 'text-sky-300' : ''"
        @click="editingRepos = !editingRepos"
      >
        {{ editingRepos ? t('groups.editDone') : t('groups.edit') }}
      </BaseButton>
      <BaseButton size="sm" :icon="Combine" :disabled="groupRepos.length === 0" @click="showFeatureModal = true">
        {{ t('groups.newFeature') }}
      </BaseButton>
      <SegmentedControl v-model="view" :options="viewOptions" />
      <BaseButton variant="ghost" size="sm" :icon="RefreshCw" :loading="worktrees.loading" @click="refresh" />
    </template>
  </PageHeader>

  <template v-if="group">
    <!-- édition de la composition : ajouter/retirer des repos déjà enregistrés -->
    <div v-if="editingRepos" class="card flex flex-col gap-1 text-xs text-zinc-400">
      {{ t('groups.reposLabel') }}
      <p v-if="worktrees.repos.length === 0" class="text-zinc-600">{{ t('groups.noReposRegistered') }}</p>
      <div v-else class="flex flex-wrap gap-2">
        <label
          v-for="repo in worktrees.repos"
          :key="repo.id"
          class="flex items-center gap-1.5 rounded-lg border border-zinc-800 bg-zinc-950/40 px-2 py-1"
        >
          <input type="checkbox" :checked="group.repoIds.includes(repo.id)" @change="toggleRepo(repo.id)" />
          <span class="text-zinc-300">{{ repo.label }}</span>
        </label>
      </div>
    </div>

    <!-- mode liste : réutilise RepoSection (worktrees + sessions + dialogues inline) -->
    <template v-if="view === 'list'">
      <EmptyState
        v-if="groupRepos.length === 0 && missingRepoIds.length === 0"
        :icon="Boxes"
        :title="t('groups.noReposInGroup')"
      />
      <RepoSection v-for="repo in groupRepos" :key="repo.id" :repo="repo" />
      <div
        v-for="id in missingRepoIds"
        :key="id"
        class="flex items-center gap-2 rounded-xl border border-amber-900/50 bg-amber-950/20 p-3 text-sm text-amber-300"
      >
        <span class="flex-1">{{ t('groups.missingRepo') }} <span class="font-mono text-xs text-amber-500/70">{{ id }}</span></span>
        <BaseButton size="sm" @click="removeRepo(id)">{{ t('groups.removeFromGroup') }}</BaseButton>
      </div>
    </template>

    <!-- mode grille : toolbar (tri waiting-first + recherche) en amont du cap dur de TerminalGrid -->
    <template v-else>
      <ListToolbar v-if="activeGroupSessions.length" :controls="gridControls" />
      <TerminalGrid :sessions="gridControls.processed.value" />
    </template>
  </template>

  <CrossRepoFeatureModal v-if="showFeatureModal && group" :repos="groupRepos" @close="showFeatureModal = false" />
</template>

<script setup lang="ts">
import { computed, ref } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { ChevronLeft, Pencil, Combine, RefreshCw, List, LayoutGrid, Boxes } from '@lucide/vue';
import type { SessionSummary } from '@arboretum/shared';
import { useGroupsStore } from '../stores/groups';
import { useWorktreesStore } from '../stores/worktrees';
import { useSessionsStore } from '../stores/sessions';
import { useToastsStore } from '../stores/toasts';
import { useListControls } from '../composables/useListControls';
import { sessionSorts } from '../composables/listDefs';
import PageHeader from '../components/layout/PageHeader.vue';
import BaseButton from '../components/ui/BaseButton.vue';
import EmptyState from '../components/ui/EmptyState.vue';
import SegmentedControl from '../components/ui/SegmentedControl.vue';
import ListToolbar from '../components/ListToolbar.vue';
import RepoSection from '../components/RepoSection.vue';
import TerminalGrid from '../components/TerminalGrid.vue';
import CrossRepoFeatureModal from '../components/CrossRepoFeatureModal.vue';

const { t } = useI18n();
const route = useRoute();
const groups = useGroupsStore();
const worktrees = useWorktreesStore();
const sessions = useSessionsStore();
const toasts = useToastsStore();

const groupId = computed(() => String(route.params.id));
const group = computed(() => groups.byId(groupId.value));
const view = ref('list');
const editingRepos = ref(false);
const showFeatureModal = ref(false);

const viewOptions = computed(() => [
  { value: 'list', label: t('groups.viewList'), icon: List },
  { value: 'grid', label: t('groups.viewGrid'), icon: LayoutGrid },
]);

const groupRepos = computed(() => groups.reposInGroup(groupId.value));

// repoIds du groupe absents du store worktrees (repo supprimé mais membership pas encore purgée côté UI).
const missingRepoIds = computed(() => {
  const g = group.value;
  if (!g) return [];
  const known = new Set(worktrees.repos.map((r) => r.id));
  return g.repoIds.filter((id) => !known.has(id));
});

// sessions vivantes et attachables des repos du groupe, en version live (store sessions).
const activeGroupSessions = computed<SessionSummary[]>(() => {
  const byId = new Map<string, SessionSummary>();
  for (const snap of groups.sessionsInGroup(groupId.value)) {
    const live = sessions.sessions.find((x) => x.id === snap.id) ?? snap;
    if (live.live && live.attachable) byId.set(live.id, live);
  }
  return [...byId.values()];
});

// mode grille : tri (waiting d'abord) + recherche, sans pagination ; TerminalGrid conserve son cap dur.
const gridControls = useListControls<SessionSummary>({
  source: () => activeGroupSessions.value,
  sorts: sessionSorts(),
  searchAccessor: (s) => `${s.cwd} ${s.title ?? ''}`,
  defaultPageSize: 0,
});

async function refresh(): Promise<void> {
  await Promise.all([groups.fetchGroups(), worktrees.fetchAll(), sessions.fetchSessions()]);
}

async function toggleRepo(repoId: string): Promise<void> {
  const g = group.value;
  if (!g) return;
  try {
    if (g.repoIds.includes(repoId)) await groups.removeRepoFromGroup(g.id, repoId);
    else await groups.addRepoToGroup(g.id, repoId);
    toasts.success(t('toast.groupUpdated'));
  } catch (err) {
    toasts.error(err);
  }
}

async function removeRepo(repoId: string): Promise<void> {
  const g = group.value;
  if (!g) return;
  try {
    await groups.removeRepoFromGroup(g.id, repoId);
    toasts.success(t('toast.groupUpdated'));
  } catch (err) {
    toasts.error(err);
  }
}
</script>
