<template>
  <!-- Tampon d'envoi : courriels multi-destinataires retenus N s avant l'envoi → on voit + on peut annuler -->
  <transition name="ob-slide">
    <div v-if="pending.length" class="outbox-panel">
      <div class="ob-head row items-center no-wrap">
        <q-icon name="schedule_send" color="warning" size="20px" class="q-mr-xs" />
        <div class="text-weight-bold">{{ pending.length }} courriel{{ pending.length > 1 ? 's' : '' }} en attente d'envoi</div>
        <q-space />
        <q-btn dense flat no-caps size="sm" color="negative" icon="block" label="Tout annuler" @click="cancelAll" />
      </div>
      <div v-for="it in pending" :key="it.id" class="ob-item row items-center no-wrap"
        :class="{ 'ob-failed': it.status === 'failed' }">
        <q-circular-progress v-if="it.status !== 'failed'" :value="pct(it)" size="38px" :thickness="0.18"
          color="warning" track-color="warning" show-value class="q-mr-sm">
          <span class="text-caption text-weight-bold">{{ secLeft(it) }}</span>
        </q-circular-progress>
        <q-icon v-else name="error" color="negative" size="30px" class="q-mr-sm" />
        <div class="col" style="min-width:0">
          <div class="text-caption text-grey-7 ellipsis">
            <q-badge :color="kindColor(it.kind)" text-color="white" :label="it.label || it.kind" class="q-mr-xs" />
            {{ it.count }} destinataire{{ it.count > 1 ? 's' : '' }}
          </div>
          <div class="text-body2 ellipsis" :title="it.subject">{{ it.subject || '(sans objet)' }}</div>
          <div class="text-caption text-grey-6 ellipsis" :title="it.recipients.join(', ')">{{ it.recipients.join(', ') }}</div>
          <div v-if="it.status === 'failed'" class="text-caption text-negative ellipsis">Échec : {{ it.error }}</div>
        </div>
        <q-btn dense flat round icon="close" color="grey-7" @click="cancel(it.id)"><q-tooltip>Annuler (ne pas envoyer)</q-tooltip></q-btn>
        <q-btn dense flat round :icon="it.status === 'failed' ? 'refresh' : 'send'" color="green-7" @click="sendNow(it.id)">
          <q-tooltip>{{ it.status === 'failed' ? 'Réessayer' : 'Envoyer maintenant' }}</q-tooltip>
        </q-btn>
      </div>
    </div>
  </transition>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import { useQuasar } from 'quasar'
import { HUB_URL } from 'src/config/hub'
import { useSSE } from 'src/composables/useSSE'

const $q = useQuasar()
const pending = ref([])
const holdSec = ref(20)
const now = ref(Date.now())
let ticker = null
let tick = 0

const sse = useSSE({ listeners: { outbox: (d) => { pending.value = d.pending || []; if (d.holdSec) holdSec.value = d.holdSec } } })

async function refresh () {
  try { const r = await fetch(`${HUB_URL}/outbox`); if (r.ok) { const d = await r.json(); pending.value = d.pending || []; if (d.holdSec) holdSec.value = d.holdSec } } catch (e) { /* */ }
}
function secLeft (it) { return Math.max(0, Math.ceil((it.sendAt - now.value) / 1000)) }
function pct (it) { const total = holdSec.value * 1000; const left = Math.max(0, it.sendAt - now.value); return Math.max(0, Math.min(100, (left / total) * 100)) }
function kindColor (k) { return k === 'queue-notif' ? 'green-5' : k === 'ticket-notif' ? 'teal-6' : 'blue-grey-5' }

async function cancel (id) {
  pending.value = pending.value.filter(x => x.id !== id) // optimiste
  try { await fetch(`${HUB_URL}/outbox/cancel`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id }) }) } catch (e) { /* */ }
}
async function cancelAll () {
  const n = pending.value.length; pending.value = []
  try { await fetch(`${HUB_URL}/outbox/cancel-all`, { method: 'POST' }); $q.notify({ type: 'info', message: `${n} envoi(s) annulé(s)` }) } catch (e) { /* */ }
}
async function sendNow (id) {
  try { const r = await fetch(`${HUB_URL}/outbox/send-now`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id }) }); const d = await r.json(); if (!d.ok) $q.notify({ type: 'negative', message: d.error || 'Échec envoi' }) } catch (e) { /* */ }
  refresh()
}

onMounted(() => {
  refresh()
  sse.connect(['outbox'])
  ticker = setInterval(() => { now.value = Date.now(); if (++tick % 6 === 0) refresh() }, 1000) // countdown + resync léger toutes les 6 s
})
onUnmounted(() => { if (ticker) clearInterval(ticker); sse.disconnect() })
</script>

<style scoped>
.outbox-panel { position: fixed; left: 18px; bottom: 18px; z-index: 4000; width: 390px; max-width: calc(100vw - 36px);
  background: #fffdf5; border: 1px solid #fde68a; border-radius: 10px; box-shadow: 0 8px 28px rgba(0,0,0,.18); overflow: hidden; }
.ob-head { padding: 8px 10px; background: #fef3c7; color: #92400e; border-bottom: 1px solid #fde68a; }
.ob-item { padding: 8px 10px; border-bottom: 1px solid #f5f0e0; gap: 2px; }
.ob-item:last-child { border-bottom: none; }
.ob-failed { background: #fef2f2; }
.ob-slide-enter-active, .ob-slide-leave-active { transition: all .25s ease; }
.ob-slide-enter-from, .ob-slide-leave-to { transform: translateY(20px); opacity: 0; }
</style>
