<template>
  <q-dialog v-model="open">
    <q-card style="min-width:580px">
      <q-card-section class="row items-center q-pb-none">
        <div class="text-subtitle1 text-weight-bold">Types de shift</div><q-space />
        <q-btn flat round dense icon="close" v-close-popup />
      </q-card-section>
      <q-card-section>
        <table class="demand-tbl">
          <thead><tr><th>Nom</th><th>Début</th><th>Fin</th><th>Heures</th><th>Couleur</th><th>🛡️ Garde</th><th></th></tr></thead>
          <tbody>
            <tr v-for="t in editTpls" :key="t.name">
              <td><span class="code-chip" :style="chip(t.color)">{{ (t.template_name||'?')[0].toUpperCase() }}</span> {{ t.template_name }}</td>
              <td><q-input dense outlined type="time" v-model="t.start" style="width:115px" /></td>
              <td><q-input dense outlined type="time" v-model="t.end" style="width:115px" /></td>
              <td class="text-center text-weight-medium">{{ calcHours(t.start, t.end) }} h</td>
              <td><input type="color" v-model="t.color" style="width:36px;height:26px;border:none;background:none" /></td>
              <td class="text-center"><q-toggle dense v-model="t.on_call" :true-value="1" :false-value="0" color="brown"><q-tooltip>Quart de garde (urgences) — non offert au booking</q-tooltip></q-toggle></td>
              <td><q-btn flat dense round size="sm" icon="save" color="primary" @click="saveShiftTpl(t)"><q-tooltip>Enregistrer</q-tooltip></q-btn><q-btn flat dense round size="sm" icon="delete" color="grey-7" @click="delShiftTpl(t)" /></td>
            </tr>
          </tbody>
        </table>
        <q-separator class="q-my-md" />
        <div class="row items-center q-gutter-sm">
          <q-input dense outlined v-model="newTpl.template_name" label="Nom (auto si vide)" style="width:150px" />
          <div style="width:230px;padding:0 8px">
            <q-range v-model="newTplRange" :min="0" :max="24" :step="0.5" snap label :left-label-value="fmtH(newTplRange.min) + 'h'" :right-label-value="fmtH(newTplRange.max) + 'h'" color="primary" />
          </div>
          <span class="text-caption text-grey-7 text-weight-medium">{{ fmtH(newTplRange.min) }}h–{{ fmtH(newTplRange.max) }}h · {{ calcHours(newTpl.start, newTpl.end) }} h</span>
          <input type="color" v-model="newTpl.color" style="width:36px;height:26px;border:none;background:none" />
          <q-toggle dense v-model="newTpl.on_call" :true-value="1" :false-value="0" label="🛡️ Garde" color="brown" />
          <q-btn dense unelevated color="primary" icon="add" label="Ajouter" @click="addShiftTpl" />
        </div>
      </q-card-section>
    </q-card>
  </q-dialog>
</template>

<script setup>
// Dialogue « Types de shift » (modèles de quart) — extrait de PlanificationPage (décomposition #4).
// Édite les Shift Template via l'API roster ; `editTpls` = copie d'édition locale.
// Après CHAQUE mutation → emit `changed` : le PARENT recharge sa liste partagée `templates`
// (lue par la grille / garde / demande). Semé instantanément depuis la prop `templates` à l'ouverture.
import { ref, reactive, computed, watch } from 'vue'
import { useQuasar } from 'quasar'
import * as roster from 'src/api/roster'

const props = defineProps({
  modelValue: { type: Boolean, default: false },
  templates: { type: Array, default: () => [] }, // liste partagée (LECTURE) — sème editTpls à l'ouverture
})
const emit = defineEmits(['update:modelValue', 'changed'])
const $q = useQuasar()
const err = (e) => $q.notify({ type: 'negative', message: '' + (e.message || e) })

// Helpers — copies locales (les originaux restent partagés dans la page ; on ne les déplace pas).
const calcHours = (st, et) => { if (!st || !et) return 0; const [h1, m1] = st.split(':').map(Number); const [h2, m2] = et.split(':').map(Number); let mins = (h2 * 60 + m2) - (h1 * 60 + m1); if (mins < 0) mins += 1440; return Math.round(mins / 60 * 100) / 100 }
const hToNum = (t) => { if (!t) return null; const p = String(t).split(':'); return Number(p[0]) + (Number(p[1]) || 0) / 60 }
const fmtH = (h) => { const hh = Math.floor(h); const mm = Math.round((h - hh) * 60); return mm ? (hh + ':' + String(mm).padStart(2, '0')) : ('' + hh) }
const numToTime = (h) => { const hh = Math.floor(h); const mm = Math.round((h - hh) * 60); return String(hh).padStart(2, '0') + ':' + String(mm).padStart(2, '0') }
const chip = (color) => ({ background: color || '#1976d2', color: '#fff' })

const open = computed({ get: () => props.modelValue, set: v => emit('update:modelValue', v) })
const editTpls = ref([])
const newTpl = reactive({ template_name: '', start: '08:00', end: '16:00', color: '#1976d2', on_call: 0 })
// Slider à 2 poignées pour le nouveau modèle (heures custom) ↔ newTpl.start/end
const newTplRange = computed({ get: () => ({ min: hToNum(newTpl.start) || 8, max: hToNum(newTpl.end) || 16 }), set: (v) => { newTpl.start = numToTime(v.min); newTpl.end = numToTime(v.max) } })

const mapTpl = (t) => ({ name: t.name, template_name: t.template_name, start: (t.start_time || '08:00:00').slice(0, 5), end: (t.end_time || '16:00:00').slice(0, 5), color: t.color || '#1976d2', on_call: t.on_call ? 1 : 0 })
async function reloadFromServer () { try { editTpls.value = ((await roster.listTemplates()).templates || []).map(mapTpl) } catch (e) { err(e) } }

async function saveShiftTpl (t) { try { await roster.updateTemplate(t.name, { start_time: t.start + ':00', end_time: t.end + ':00', hours: calcHours(t.start, t.end), color: t.color, on_call: t.on_call ? 1 : 0 }); emit('changed'); $q.notify({ type: 'positive', message: t.template_name + ' enregistré (' + calcHours(t.start, t.end) + ' h)' }) } catch (e) { err(e) } }
async function addShiftTpl () { const nm = (newTpl.template_name || '').trim() || (fmtH(hToNum(newTpl.start)) + 'h–' + fmtH(hToNum(newTpl.end)) + 'h'); try { await roster.createTemplate({ template_name: nm, start_time: newTpl.start + ':00', end_time: newTpl.end + ':00', hours: calcHours(newTpl.start, newTpl.end), color: newTpl.color, default_required: 1, on_call: newTpl.on_call ? 1 : 0 }); newTpl.template_name = ''; newTpl.on_call = 0; emit('changed'); await reloadFromServer(); $q.notify({ type: 'positive', message: 'Type « ' + nm + ' » ajouté' }) } catch (e) { err(e) } }
async function delShiftTpl (t) { if (!window.confirm('Supprimer le type « ' + t.template_name + ' » ?')) return; try { await roster.deleteShiftTemplate(t.name); emit('changed'); editTpls.value = editTpls.value.filter(x => x.name !== t.name); $q.notify({ type: 'info', message: 'Type supprimé' }) } catch (e) { err(e) } }

// Semer editTpls à l'ouverture depuis la liste partagée déjà chargée (remplace l'ancien openShiftEditor).
watch(() => props.modelValue, (v) => { if (v) editTpls.value = (props.templates || []).map(mapTpl) })
</script>

<style scoped>
/* Copiés de PlanificationPage (le CSS scoped ne traverse pas vers l'enfant). */
.demand-tbl { border-collapse: collapse; }
.demand-tbl th { font-size: 11px; color: #888; font-weight: 600; padding: 2px 6px; text-align: left; }
.demand-tbl td { padding: 2px 4px; }
.code-chip { display: inline-block; min-width: 18px; padding: 1px 5px; border-radius: 4px; font-weight: 700; font-size: 11px; line-height: 16px; margin: 1px; }
</style>
