<template>
  <div class="ops-card q-mb-md">
    <div class="row items-center q-mb-xs cursor-pointer" @click="expanded = !expanded">
      <q-icon name="quickreply" size="20px" color="primary" class="q-mr-sm" />
      <span class="text-subtitle1 text-weight-bold">Signatures & réponses pré-écrites</span>
      <q-chip v-if="list.length" dense square color="green-1" text-color="green-8" class="q-ml-sm">{{ list.length }}</q-chip>
      <q-space />
      <q-spinner v-if="loading" size="16px" color="primary" class="q-mr-sm" />
      <q-btn v-if="expanded" dense unelevated color="green-5" icon="add" label="Nouvelle" no-caps @click.stop="addNew" />
      <q-icon :name="expanded ? 'keyboard_arrow_up' : 'keyboard_arrow_down'" size="24px" color="grey-7" class="q-ml-sm" />
    </div>
    <div v-if="expanded">
    <div class="text-caption text-grey-6 q-mb-md">
      Réutilisables dans l'Inbox (menu « Réponses types » sous la réponse). Éditeur HTML : gras, listes, liens et <b>images / logo</b> — ou collez votre signature Gmail. Variables : <code v-pre>{{client}}</code>, <code v-pre>{{agent}}</code> (remplacées à l'insertion). Associez une <b>mailbox</b> (ex. factures@ → « Comptes Payables »).
    </div>

    <div v-for="(c, i) in list" :key="c.id" class="canned-row q-mb-md">
      <div class="row items-center q-gutter-sm q-mb-xs">
        <q-input dense outlined v-model="c.title" label="Titre (ex. Signature Support)" class="col" />
        <q-select dense outlined v-model="c.mailbox" :options="mailboxes" emit-value map-options label="Mailbox / file" style="min-width:185px" />
        <q-btn flat round dense icon="delete" color="negative" @click="remove(i)"><q-tooltip>Supprimer</q-tooltip></q-btn>
      </div>
      <q-editor v-model="c.html" min-height="7rem" class="canned-editor"
        :toolbar="[['bold','italic','underline'],['unordered','ordered'],['link','removeFormat'],['undo','redo']]"
        placeholder="Texte / signature… (image via le bouton ci-dessous, ou collez depuis Gmail)" />
      <div class="row items-center q-mt-xs">
        <q-btn flat dense size="sm" icon="image" color="primary" no-caps label="Image / logo" :loading="upBusy === c.id" @click="pickImage(c)" />
        <span class="text-caption text-grey-5 q-ml-sm">PNG/JPG/SVG · hébergée sur nos serveurs (visible chez le destinataire)</span>
      </div>
    </div>
    <div v-if="!list.length" class="text-caption text-grey-5 q-py-sm">Aucune — cliquez « Nouvelle » pour en créer une.</div>

    <input ref="fileInput" type="file" accept="image/png,image/jpeg,image/gif,image/webp,image/svg+xml" style="display:none" @change="onFile" />
    <div class="row justify-end q-mt-sm">
      <q-btn unelevated color="primary" icon="save" label="Enregistrer" no-caps :loading="saving" @click="persist" />
    </div>
    </div>
  </div>
</template>

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

const $q = useQuasar()
const list = ref([])
const expanded = ref(false)   // section repliée par défaut dans Paramètres (éditeurs montés à l'ouverture)
const loading = ref(false)
const saving = ref(false)
const upBusy = ref(null)
const fileInput = ref(null)
let _target = null
const mailboxes = [
  { label: 'Toutes', value: '' },
  { label: 'Facturations (Comptes Payables)', value: 'Facturations' },
  { label: 'Service à la clientèle', value: 'Service à la clientèle' },
  { label: 'Support', value: 'Supports' },
  { label: 'Technicien', value: 'Technicien' },
]

function uid () { try { return crypto.randomUUID() } catch (e) { return 'c' + Date.now() + Math.round(Math.random() * 1e6) } }
function textToHtml (t) { return String(t || '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\n/g, '<br>') }
function htmlToText (h) { return String(h || '').replace(/<br\s*\/?>/gi, '\n').replace(/<\/(p|div|li|h[1-6])>/gi, '\n').replace(/<[^>]+>/g, '').replace(/&nbsp;/g, ' ').replace(/&amp;/g, '&').trim() }

async function load () {
  loading.value = true
  try {
    const r = await fetch(`${HUB_URL}/conversations/canned`)
    if (r.ok) { const d = await r.json(); list.value = (d.responses || []).map(x => ({ id: x.id || uid(), title: x.title || '', mailbox: x.mailbox || '', category: x.category || 'Général', html: x.html || textToHtml(x.body) })) }
  } catch (e) { /* */ } finally { loading.value = false }
}
function addNew () { expanded.value = true; list.value.push({ id: uid(), title: '', mailbox: '', category: 'Général', html: '' }) }
function remove (i) { list.value.splice(i, 1) }

function pickImage (c) { _target = c; if (fileInput.value) { fileInput.value.value = ''; fileInput.value.click() } }
async function onFile (e) {
  const f = e.target.files && e.target.files[0]; const c = _target
  if (!f || !c) return
  upBusy.value = c.id
  try {
    const data = await new Promise((resolve, reject) => { const fr = new FileReader(); fr.onload = () => resolve(fr.result); fr.onerror = reject; fr.readAsDataURL(f) })
    const r = await fetch(`${HUB_URL}/campaigns/assets/upload`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: f.name, data }) })
    const d = await r.json().catch(() => ({}))
    if (!r.ok || !d.url) throw new Error(d.error || 'Téléversement échoué')
    c.html = (c.html || '') + `<img src="${d.url}" alt="" style="max-width:280px;height:auto" />`
    $q.notify({ type: 'positive', message: 'Image ajoutée à la signature' })
  } catch (err) { $q.notify({ type: 'negative', message: err.message }) } finally { upBusy.value = null; _target = null }
}

async function persist () {
  saving.value = true
  try {
    const clean = list.value
      .filter(c => (c.title || '').trim() || htmlToText(c.html).trim())
      .map(c => ({ id: c.id, title: c.title, category: c.category, mailbox: c.mailbox || '', html: c.html || '', body: htmlToText(c.html) }))
    const r = await fetch(`${HUB_URL}/conversations/canned`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ responses: clean }) })
    if (r.ok) $q.notify({ type: 'positive', message: 'Réponses enregistrées' })
    else $q.notify({ type: 'negative', message: 'Échec sauvegarde' })
  } catch (e) { $q.notify({ type: 'negative', message: e.message }) } finally { saving.value = false }
}

onMounted(load)
</script>

<style scoped>
.canned-row { border: 1px solid #e2e8f0; border-radius: 8px; padding: 10px; background: #fafbff; }
.canned-editor { background: #fff; }
code { background: #eef2ff; padding: 1px 5px; border-radius: 4px; font-size: .8em; }
</style>
