<template>
  <!-- Section repliable « glance → detail » : n'affiche que l'essentiel, révèle le reste au clic.
       Standardise le pattern ad-hoc (tickets slice(0,5) + « Voir tout », « Plus d'options »…).
       - #summary : ligne compacte TOUJOURS visible (aperçu quand replié). Optionnel.
       - défaut   : contenu révélé quand ouvert.
       - #actions : boutons à droite de l'en-tête (n'ouvrent/ferment pas la section).
       État d'ouverture persisté PAR UTILISATEUR si `persist-key` fourni (cross-appareil via /prefs).
       Usage :
         <DisclosureSection title="Tickets" :count="tickets.length" persist-key="client.tickets">
           <template #summary>{{ openCount }} ouverts · dernier {{ lastDate }}</template>
           <TicketList :rows="tickets" />
         </DisclosureSection> -->
  <div class="disclosure" :class="{ 'is-open': open }">
    <div class="ds-header" role="button" tabindex="0"
         @click="toggle" @keydown.enter.prevent="toggle" @keydown.space.prevent="toggle">
      <q-icon :name="open ? 'expand_more' : 'chevron_right'" size="22px" class="ds-chevron" />
      <q-icon v-if="icon" :name="icon" size="18px" class="ds-icon" />
      <span class="ds-title">{{ title }}</span>
      <span v-if="count !== null && count !== undefined" class="ds-count">{{ count }}</span>
      <div v-if="$slots.summary && !open" class="ds-summary"><slot name="summary" /></div>
      <q-space />
      <div v-if="$slots.actions" class="ds-actions" @click.stop><slot name="actions" /></div>
    </div>
    <q-slide-transition>
      <div v-show="open" class="ds-body"><slot /></div>
    </q-slide-transition>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { useUserPrefs } from 'src/composables/useUserPrefs'

const props = defineProps({
  title: { type: String, default: '' },
  count: { type: [Number, String], default: null },
  icon: { type: String, default: '' },
  defaultOpen: { type: Boolean, default: false },
  // Clé de persistance de l'état ouvert/fermé (namespace 'disclosure'). Absente = pas de persistance.
  persistKey: { type: String, default: '' },
})

// Un seul namespace partagé pour toutes les sections repliables de l'app.
const { prefs, save } = props.persistKey ? useUserPrefs('disclosure', {}) : { prefs: null, save: null }

const open = ref(
  props.persistKey && prefs && prefs.value[props.persistKey] !== undefined
    ? !!prefs.value[props.persistKey]
    : props.defaultOpen,
)

function toggle () {
  open.value = !open.value
  if (props.persistKey && save) save({ [props.persistKey]: open.value })
}
</script>

<style scoped>
.disclosure { border: 1px solid var(--ops-border); border-radius: 12px; background: var(--ops-surface, #fff); margin-bottom: 12px; overflow: hidden; }
.ds-header { display: flex; align-items: center; gap: 8px; padding: 12px 14px; cursor: pointer; user-select: none; min-height: 48px; }
.ds-header:hover { background: var(--ops-bg-light); }
.ds-header:focus-visible { outline: 2px solid var(--ops-primary, #6366f1); outline-offset: -2px; }
.ds-chevron { color: var(--ops-text-muted); flex: 0 0 auto; }
.ds-icon { color: var(--ops-text-muted); flex: 0 0 auto; }
.ds-title { font-weight: 650; font-size: 0.98rem; color: var(--ops-text); flex: 0 0 auto; }
.ds-count { font-size: 0.72rem; font-weight: 600; color: var(--ops-text-muted); background: var(--ops-bg-light); border: 1px solid var(--ops-border); border-radius: 20px; padding: 1px 9px; font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.ds-summary { font-size: 0.84rem; color: var(--ops-text-muted); margin-left: 6px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ds-actions { display: flex; gap: 6px; align-items: center; flex: 0 0 auto; }
.ds-body { padding: 4px 14px 14px; border-top: 1px solid var(--ops-border); }
@media (max-width: 599px) { .ds-summary { display: none; } }
</style>
