<script setup lang="ts">
// Sommaire — langage du gabarit : filet couleur 5 mm en haut, marges 8 mm,
// titre Syne 45 pt. La taille des entrées et leur disposition (colonne unique
// ou grille) s'adaptent au nombre de projets listés.
import type { Background } from '~~/types'

const props = withDefaults(
  defineProps<{
    title?: string
    entries: { title: string; subtitle?: string; category?: string; pageNumber: number }[]
    background: Background
    bandColor?: string
    page: { index: number; total: number }
    renderMode?: 'preview' | 'print'
  }>(),
  { title: 'Sommaire', renderMode: 'preview' },
)

const emit = defineEmits<{ navigate: [pageNumber: number] }>()

const strip = computed(() => props.bandColor || FL_INK)
const pageStyle = computed(() => backgroundStyle(props.background, strip.value))
const isPrint = computed(() => props.renderMode === 'print')

// En print, chaque entrée est un lien interne #page-N (converti en lien PDF par
// Chromium). En aperçu, le même clic défile jusqu'à la page dans la preview.
function hrefFor(n: number) {
  return isPrint.value ? `#page-${n}` : `#preview-page-${n}`
}
function onEntryClick(n: number, e: MouseEvent) {
  if (isPrint.value) return // laisse le lien natif au PDF
  e.preventDefault()
  e.stopPropagation() // n'active pas la sélection de la page-sommaire elle-même
  emit('navigate', n)
}

// Peu de projets = gros titres sur une colonne ; beaucoup = grille dense.
const layout = computed(() => {
  const n = props.entries.length
  if (n <= 4) return { cols: 1, size: 48, sub: 18.7, gapX: 0, gapY: 44 }
  if (n <= 8) return { cols: 1, size: 32, sub: 14.7, gapX: 0, gapY: 30 }
  if (n <= 16) return { cols: 2, size: 24, sub: 13.3, gapX: 96, gapY: 24 }
  if (n <= 26) return { cols: 2, size: 18.7, sub: 12, gapX: 96, gapY: 18 }
  return { cols: 3, size: 14.7, sub: 10.7, gapX: 60, gapY: 14 }
})

const gridStyle = computed(() => ({
  gridTemplateColumns: `repeat(${layout.value.cols}, minmax(0, 1fr))`,
  columnGap: `${layout.value.gapX}px`,
  rowGap: `${layout.value.gapY}px`,
  gridAutoRows: 'min-content',
}))
</script>

<template>
  <div class="fl-page" :style="pageStyle">
    <div v-if="background.mode !== 'full'" class="absolute inset-x-0 top-0" :style="{ height: 'var(--fl-strip)', backgroundColor: strip }" />

    <div class="absolute flex flex-col" :style="{ inset: 'var(--fl-margin)', top: '60px' }">
      <h2 :style="{ fontSize: '60px', lineHeight: '1.05' }">{{ title }}</h2>
      <div class="mt-14 grid min-h-0 flex-1 content-start" :style="gridStyle">
        <a
          v-for="entry in entries"
          :key="`${entry.pageNumber}-${entry.title}`"
          :href="hrefFor(entry.pageNumber)"
          class="flex items-baseline gap-3 self-center text-current no-underline"
          :class="{ 'cursor-pointer': !isPrint }"
          @click="onEntryClick(entry.pageNumber, $event)"
        >
          <span :class="CATEGORY_TITLE_CLASS[entry.category ?? '']" :style="{ fontSize: `${layout.size}px`, lineHeight: '1.2' }">{{ entry.title }}</span>
          <span v-if="entry.subtitle" class="whitespace-nowrap opacity-70" :style="{ fontSize: `${layout.sub}px` }">{{ entry.subtitle }}</span>
          <!-- Filet de conduite en points dégradés (une bordure `dotted` saute
               au rendu mis à l'échelle : ici les points s'antialiasent). -->
          <span
            class="flex-1 opacity-40"
            :style="{
              alignSelf: 'baseline',
              height: '4px',
              backgroundImage: 'radial-gradient(circle at center, currentColor 1px, transparent 1.5px)',
              backgroundSize: '6px 4px',
              backgroundRepeat: 'repeat-x',
              backgroundPosition: '0 100%',
            }"
          />
          <span class="tabular-nums opacity-80" :style="{ fontSize: `${layout.sub + 2}px` }">{{ entry.pageNumber }}</span>
        </a>
      </div>
    </div>
  </div>
</template>
