<template>
  <!-- Contenu du menu de cellule PARTAGÉ (grille semaine/jour ET calendrier par tech).
       Le PARENT l'enveloppe dans son propre <q-menu> (ancrage propre à chaque contexte) et câble les intentions émises
       à ses propres fonctions (applyWindow / toggleGarde / absence / …). Aucun état de page ici : 100 % réutilisable. -->
  <q-list dense style="width:262px;user-select:none;-webkit-user-select:none">
    <q-item-label header class="q-py-xs">{{ title }}</q-item-label>
    <!-- 4 actions : Jour · Soir · Garde · Absent -->
    <div class="row q-gutter-xs q-px-sm q-pb-xs">
      <q-btn dense unelevated size="sm" color="primary" label="Jour 8–16" class="col" @click="$emit('window', { min: 8, max: 16 })" />
      <q-btn dense unelevated size="sm" color="deep-purple-5" label="Soir 16–20" class="col" @click="$emit('window', { min: 16, max: 20 })" />
    </div>
    <div class="row q-gutter-xs q-px-sm q-pb-xs">
      <q-btn dense :unelevated="isGarde" :outline="!isGarde" size="sm" color="brown" icon="shield" :label="isGarde ? 'Garde ✓' : 'Garde'" class="col" @click="$emit('toggle-garde')"><q-tooltip>Mettre / retirer de garde (G) — en parallèle d'un shift</q-tooltip></q-btn>
      <q-btn dense :unelevated="isAbsent" :outline="!isAbsent" size="sm" color="negative" icon="event_busy" :label="isAbsent ? 'Absent ✓' : 'Absent'" class="col" @click="$emit('toggle-absent')"><q-tooltip>Congé / absence — à publier</q-tooltip></q-btn>
    </div>
    <!-- Saisie rapide d'heures : 8-17 · 830-16 · 85 (=8→17) -->
    <div class="q-px-sm q-pb-xs" @click.stop @mousedown.stop>
      <q-input dense outlined v-model="quickEntry" placeholder="Heures : 8-16 · 816 · 830-16" @keyup.enter="applyQuick">
        <template #append><q-btn flat dense round size="sm" icon="keyboard_return" color="primary" @click="applyQuick"><q-tooltip>Appliquer</q-tooltip></q-btn></template>
      </q-input>
    </div>
    <!-- Plage personnalisée (slider replié) -->
    <q-expansion-item dense dense-toggle icon="tune" label="Personnaliser la plage" header-class="text-caption text-grey-7">
      <div class="q-px-md q-pb-sm" @click.stop @mousedown.stop>
        <q-range v-model="range" :min="0" :max="24" :step="0.5" snap color="primary" class="q-mt-sm" />
        <div class="row items-center no-wrap q-gutter-sm">
          <span class="text-caption text-weight-bold">{{ fmtH(range.min) }}h–{{ fmtH(range.max) }}h</span>
          <q-space />
          <q-btn dense unelevated size="sm" color="primary" label="Appliquer" @click="applyRange" />
        </div>
      </div>
    </q-expansion-item>
    <q-separator />
    <!-- Job « bouche-trou » : occuper la journée du tech (formation, réunion, admin…) → le retire du dispatch -->
    <q-item clickable dense @click="$emit('filler')">
      <q-item-section avatar style="min-width:30px"><q-icon name="block" color="deep-orange-6" /></q-item-section>
      <q-item-section><q-item-label>Bloquer du temps…</q-item-label><q-item-label caption>Job/ticket qui occupe la journée → hors dispatch (priorité = curseur dur/souple)</q-item-label></q-item-section>
    </q-item>
    <q-separator />
    <!-- Shifts en place + actions compactes -->
    <q-item v-for="a in shifts" :key="'c' + (a.shift || a.name)" dense>
      <q-item-section>{{ a.shift_name || a.shift }} <span class="text-grey-6">{{ a.hours }}h</span></q-item-section>
      <q-item-section side><q-btn flat dense round size="sm" icon="close" color="grey-7" @click="$emit('remove-shift', a)"><q-tooltip>Retirer</q-tooltip></q-btn></q-item-section>
    </q-item>
    <div class="row items-center q-px-sm q-py-xs q-gutter-sm">
      <q-btn v-if="showCopy" flat dense size="sm" icon="content_copy" color="grey-8" @click="$emit('copy')"><q-tooltip>Copier la case</q-tooltip></q-btn>
      <q-btn v-if="showCopy" flat dense size="sm" icon="content_paste" color="grey-8" :disable="!clipboardCount" @click="$emit('paste')"><q-tooltip>Coller{{ clipboardCount ? ' (' + clipboardCount + ')' : '' }}</q-tooltip></q-btn>
      <q-space />
      <q-btn v-if="shifts.length" flat dense size="sm" icon="layers_clear" color="grey-8" label="Vider" @click="$emit('clear')" />
    </div>
  </q-list>
</template>

<script setup>
// Menu de cellule réutilisable — voir en-tête du template. Émet des INTENTIONS ; le parent exécute (single source of logic).
import { ref, watch } from 'vue'
const props = defineProps({
  title: { type: String, default: '' },
  shifts: { type: Array, default: () => [] }, // [{ shift, shift_name, hours, name? }]
  isGarde: { type: Boolean, default: false },
  isAbsent: { type: Boolean, default: false },
  clipboardCount: { type: Number, default: 0 },
  initialRange: { type: Object, default: () => ({ min: 8, max: 16 }) },
  cellKey: { type: String, default: '' }, // change à chaque (ré)ouverture → réinitialise saisie/slider
  showCopy: { type: Boolean, default: true },
})
const emit = defineEmits(['window', 'toggle-garde', 'toggle-absent', 'remove-shift', 'clear', 'copy', 'paste', 'filler'])
const quickEntry = ref('')
const range = ref({ min: props.initialRange.min, max: props.initialRange.max })
// Réinitialise à chaque ouverture sur une nouvelle cellule (le composant reste monté, seul le q-menu parent s'affiche/masque).
watch(() => props.cellKey, () => { quickEntry.value = ''; range.value = { min: props.initialRange.min, max: props.initialRange.max } })
function fmtH (h) { const hh = Math.floor(h); const mm = Math.round((h - hh) * 60); return mm ? (hh + ':' + String(mm).padStart(2, '0')) : ('' + hh) }
// Parse « 8-17 » · « 8:30-16 » · « 830-16 » · « 85 » (=8→17, dernier chiffre en pm si ≤ début).
function parseHM (tok) { tok = String(tok).trim().toLowerCase().replace(/h/g, ':').replace(/[^\d:]/g, ''); if (!tok) return null; if (tok.includes(':')) { const [h, m] = tok.split(':'); return Number(h) + (Number(m || 0)) / 60 } if (tok.length >= 3) return Number(tok.slice(0, -2)) + Number(tok.slice(-2)) / 60; return Number(tok) }
function parseQuickShift (str) {
  const s = (str || '').trim().toLowerCase(); if (!s) return null
  if (/[-–—]|to|→|\s/.test(s)) { const p = s.split(/[-–—]|to|→|\s+/).filter(Boolean); if (p.length < 2) return null; const a = parseHM(p[0]); const b = parseHM(p[1]); return (a == null || b == null || b <= a || b > 24) ? null : { min: a, max: b } }
  // Compact SANS séparateur : « 816 »=8–16 · « 1016 »=10–16 · « 0816 »=8–16 (2 derniers chiffres = fin, le reste = début).
  if (/^\d{3,4}$/.test(s)) { const end = Number(s.slice(-2)); const start = Number(s.slice(0, -2)); if (end <= 24 && start >= 0 && start < end) return { min: start, max: end } }
  if (/^\d{2}$/.test(s)) { const a = Number(s[0]); let b = Number(s[1]); if (b <= a) b += 12; return (b <= a || b > 24) ? null : { min: a, max: b } } // « 85 »=8→17
  return null
}
function applyQuick () { const r = parseQuickShift(quickEntry.value); if (!r) return; quickEntry.value = ''; emit('window', r) }
function applyRange () { if (range.value.max > range.value.min) emit('window', { min: range.value.min, max: range.value.max }) }
</script>
