<template>
  <q-dialog v-model="open" @hide="reset">
    <q-card style="min-width:540px;max-width:96vw">
      <q-card-section class="row items-center q-pb-none">
        <q-icon name="bolt" color="deep-purple-6" size="22px" class="q-mr-sm" />
        <div class="text-subtitle1 text-weight-bold">Commande dictée</div>
        <q-space />
        <q-btn flat round dense icon="close" v-close-popup />
      </q-card-section>

      <q-card-section>
        <!-- Dictée / texte -->
        <div class="row items-end q-gutter-sm">
          <q-input v-model="text" type="textarea" autogrow :rows="2" outlined class="col" autofocus
            label="Dicte ou écris (ex. « Crée un ticket de facture non payée pour Louis-Paul, texto au client qu'on attend le paiement »)"
            @keyup.enter.exact.prevent="plan" />
          <q-btn round :color="listening ? 'red-6' : 'deep-purple-5'" :icon="listening ? 'mic' : 'mic_none'" :loading="planning" @click="toggleMic">
            <q-tooltip>{{ micSupported ? (listening ? 'Arrêter la dictée' : 'Dicter à voix') : 'Dictée non supportée ici' }}</q-tooltip>
          </q-btn>
        </div>
        <div class="row justify-end q-mt-xs">
          <q-btn unelevated color="deep-purple-6" icon="auto_awesome" label="Préparer le plan" no-caps :disable="!text.trim() || planning" :loading="planning" @click="plan" />
        </div>

        <!-- Vérifications (lecture immédiate — pas de confirmation) -->
        <div v-if="diagnoses.length" class="q-mt-md">
          <div v-for="(a, i) in diagnoses" :key="'d' + i" class="orch-diag">
            <div class="row items-center q-mb-xs">
              <q-icon name="network_check" color="primary" size="18px" class="q-mr-sm" />
              <span class="text-weight-medium">Vérification</span>
              <span class="text-caption text-grey-6 q-ml-sm">« {{ a.customer_query }} »</span>
            </div>
            <!-- 1 client → diagnostic -->
            <template v-if="a.diagnostic && a.diagnostic.found">
              <div class="row items-center no-wrap">
                <span class="diag-dot" :style="{ background: dotColor(a.diagnostic.summary) }"></span>
                <div class="col">
                  <div class="text-weight-medium">{{ a.diagnostic.customer.customer_name }}</div>
                  <div class="text-caption text-grey-7">{{ a.diagnostic.location ? a.diagnostic.location.address : '—' }}</div>
                </div>
                <div class="text-right">
                  <div class="text-weight-medium" :style="{ color: dotColor(a.diagnostic.summary) }">{{ a.diagnostic.summary.label }}</div>
                  <div class="text-caption text-grey-6">{{ a.diagnostic.summary.detail }}<span v-if="a.diagnostic.summary.signal"> · {{ a.diagnostic.summary.signal }}</span></div>
                </div>
              </div>
              <div v-if="a.diagnostic.locations && a.diagnostic.locations.length > 1" class="text-caption text-warning q-mt-xs"><q-icon name="place" size="13px" /> {{ a.diagnostic.locations.length }} adresses — affichage de la principale</div>
            </template>
            <!-- plusieurs clients → préciser l'adresse -->
            <template v-else-if="a.diagnostic && a.diagnostic.ambiguous">
              <div class="text-caption text-warning q-mb-xs">Plusieurs clients — précise l'adresse :</div>
              <q-list dense bordered class="rounded-borders">
                <q-item clickable v-ripple v-for="(m, j) in a.diagnostic.matches" :key="j" @click="pickDiag(a, m)">
                  <q-item-section><q-item-label>{{ m.customer_name }}</q-item-label><q-item-label caption>{{ m.address || m.phone || m.email }}</q-item-label></q-item-section>
                  <q-item-section side><q-icon name="chevron_right" color="grey-5" /></q-item-section>
                </q-item>
              </q-list>
            </template>
            <div v-else-if="a.diagnostic && !a.diagnostic.found" class="text-caption text-negative">Client introuvable pour « {{ a.diagnostic.query || a.customer_query }} »</div>
            <div v-else class="text-caption text-grey-6"><q-spinner size="14px" /> diagnostic…</div>
          </div>
        </div>

        <!-- Plan d'actions à confirmer -->
        <div v-if="writeActions.length" class="q-mt-md">
          <div class="text-caption text-weight-medium text-grey-7 q-mb-xs">Plan ({{ writeActions.length }} action{{ writeActions.length > 1 ? 's' : '' }}) — vérifie puis confirme :</div>
          <div v-for="(a, i) in writeActions" :key="i" class="orch-act">
            <div class="row items-center no-wrap q-mb-xs">
              <q-icon :name="iconOf(a.type)" :color="colorOf(a.type)" size="18px" class="q-mr-sm" />
              <span class="text-weight-medium">{{ labelOf(a.type) }}</span>
              <q-badge v-if="a.type === 'create_ticket' && a.status === 'On Hold'" color="amber-1" text-color="amber-9" label="En attente" class="q-ml-sm" />
              <q-badge v-if="a.category" :label="a.category" color="grey-3" text-color="grey-8" class="q-ml-xs" />
              <q-space />
              <q-btn flat round dense size="xs" icon="delete" color="grey-5" @click="actions.splice(actions.indexOf(a), 1)" />
            </div>
            <!-- destinataire / client résolu -->
            <div v-if="a.candidates && a.candidates.length" class="q-mb-xs">
              <q-select dense outlined v-model="a.resolved" :options="a.candidates" option-label="customer_name" map-options emit-value
                :display-value="a.resolved ? a.resolved.customer_name : '— aucun —'" label="Client / destinataire" @update:model-value="onResolved(a)">
                <template #option="s">
                  <q-item v-bind="s.itemProps"><q-item-section>
                    <q-item-label>{{ s.opt.customer_name }}<q-badge v-if="s.opt.inactive" color="grey-4" text-color="grey-8" label="inactif" class="q-ml-xs" /></q-item-label>
                    <q-item-label caption>{{ s.opt.kind === 'technicien' ? '🔧 technicien · ' : '' }}{{ s.opt.address || s.opt.phone || s.opt.email }}{{ s.opt.can_sms ? ' · SMS ✓' : '' }}</q-item-label>
                  </q-item-section></q-item>
                </template>
              </q-select>
              <div v-if="a.type === 'send_sms' && a.resolved && !a.resolved.can_sms" class="text-caption text-warning"><q-icon name="warning" size="13px" /> pas de mobile — SMS impossible</div>
            </div>
            <div v-else-if="a.phone" class="text-caption text-grey-7 q-mb-xs"><q-icon name="call" size="13px" /> {{ a.phone }}</div>
            <div v-else-if="a.customer_query || a.to_query" class="text-caption text-warning q-mb-xs"><q-icon name="info" size="13px" /> « {{ a.customer_query || a.to_query }} » — non résolu</div>
            <!-- Adresse de service liée (compte multi-adresses → on choisit la bonne, pas la facturation) -->
            <div v-if="a.type === 'create_ticket' && a.resolved" class="q-mb-xs">
              <q-select v-if="a._locs && a._locs.length > 1" dense outlined v-model="a.service_location" :options="a._locs" option-label="address" option-value="name" emit-value map-options clearable label="Adresse de service">
                <template #prepend><q-icon name="place" color="warning" /></template>
              </q-select>
              <div v-else-if="a.resolved.address || a.service_location" class="text-caption text-grey-7"><q-icon name="place" size="13px" color="warning" /> {{ a.resolved.address || locLabel(a) }}</div>
            </div>
            <!-- contenu éditable -->
            <q-input v-if="a.type === 'create_ticket'" v-model="a.subject" dense outlined label="Sujet" />
            <q-input v-if="a.type === 'send_sms'" v-model="a.message" type="textarea" autogrow :rows="2" dense outlined label="Texto" />
            <template v-if="a.type === 'send_email'"><q-input v-model="a.subject" dense outlined label="Sujet" class="q-mb-xs" /><q-input v-model="a.body" type="textarea" autogrow :rows="2" dense outlined label="Courriel" /></template>
            <q-input v-if="a.type === 'note'" v-model="a.text" type="textarea" autogrow :rows="2" dense outlined label="Note" />
          </div>
        </div>

        <!-- Résultats -->
        <div v-if="results.length" class="q-mt-md">
          <div v-for="(r, i) in results" :key="i" class="text-body2" :class="r.ok ? 'text-green-8' : 'text-negative'">
            <q-icon :name="r.ok ? 'check_circle' : 'error'" size="15px" /> {{ summaryOf(r) }}
          </div>
        </div>
      </q-card-section>

      <q-card-actions v-if="writeActions.length && !results.length" align="right">
        <q-btn flat label="Annuler" @click="actions = []" />
        <q-btn unelevated color="green-7" icon="send" label="Confirmer et exécuter" no-caps :loading="running" @click="run" />
      </q-card-actions>
      <q-card-actions v-else-if="results.length" align="right">
        <q-btn unelevated color="grey-7" label="Fermer" v-close-popup />
      </q-card-actions>
    </q-card>
  </q-dialog>
</template>

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

const props = defineProps({ modelValue: Boolean })
const emit = defineEmits(['update:modelValue', 'done'])
const $q = useQuasar()

const open = ref(false)
const text = ref('')
const actions = ref([])
const results = ref([])
const planning = ref(false)
const running = ref(false)
const listening = ref(false)
const micSupported = !!(window.SpeechRecognition || window.webkitSpeechRecognition)
let recog = null

// Les vérifications (lecture) sont déjà exécutées dans le plan → séparées des actions à confirmer.
const diagnoses = computed(() => actions.value.filter(a => a.type === 'diagnose'))
const writeActions = computed(() => actions.value.filter(a => a.type !== 'diagnose'))
function dotColor (s) { return (s && s.online === true) ? '#16a34a' : (s && s.online === false) ? '#dc2626' : '#94a3b8' }
async function pickDiag (a, m) {
  a.diagnostic = null
  try { const r = await fetch(`${HUB_URL}/collab/service-status?customer=${encodeURIComponent(m.name)}`); if (r.ok) a.diagnostic = await r.json() } catch (e) { a.diagnostic = { ok: false, error: e.message } }
}

watch(() => props.modelValue, v => { open.value = v; if (v) reset() })
watch(open, v => emit('update:modelValue', v))
function reset () { text.value = ''; actions.value = []; results.value = []; if (recog) { try { recog.stop() } catch (e) {} } listening.value = false }

const iconOf = t => ({ create_ticket: 'confirmation_number', send_sms: 'sms', send_email: 'mail', note: 'sticky_note_2' }[t] || 'bolt')
const colorOf = t => ({ create_ticket: 'teal-7', send_sms: 'green-6', send_email: 'red-5', note: 'amber-7' }[t] || 'grey-7')
const labelOf = t => ({ create_ticket: 'Créer un ticket', send_sms: 'Envoyer un texto', send_email: 'Envoyer un courriel', note: 'Note interne' }[t] || t)
function summaryOf (r) {
  if (r.type === 'create_ticket') return r.ok ? `Ticket ${r.name} créé (${r.label || ''})` : 'Ticket : ' + (r.error || 'échec')
  if (r.type === 'send_sms') return r.ok ? `Texto envoyé à ${r.to} (${r.via})` : 'Texto : ' + (r.error || 'échec')
  if (r.type === 'send_email') return r.ok ? `Courriel envoyé à ${r.to}` : 'Courriel : ' + (r.error || 'échec')
  if (r.type === 'note') return 'Note : ' + (r.text || '')
  return JSON.stringify(r)
}

function toggleMic () {
  const SR = window.SpeechRecognition || window.webkitSpeechRecognition
  if (!SR) { $q.notify({ type: 'warning', message: 'Dictée non supportée par ce navigateur' }); return }
  if (listening.value) { try { recog && recog.stop() } catch (e) {} return }
  recog = new SR(); recog.lang = 'fr-CA'; recog.interimResults = true; recog.continuous = false
  recog.onresult = e => { let t = ''; for (const r of e.results) t += r[0].transcript; text.value = t }
  recog.onend = () => { listening.value = false }
  recog.onerror = () => { listening.value = false }
  try { recog.start(); listening.value = true } catch (e) { listening.value = false }
}

async function plan () {
  if (!text.value.trim()) return
  planning.value = true; results.value = []
  try {
    const r = await fetch(`${HUB_URL}/collab/orchestrate`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: text.value.trim() }) })
    const d = await r.json()
    if (d.ok) {
      actions.value = d.actions || []
      for (const a of actions.value) if (a.type === 'create_ticket' && a.resolved) onResolved(a) // pré-charge les adresses de service
      if (!actions.value.length) $q.notify({ type: 'info', message: 'Aucune action détectée — reformule.' })
    } else $q.notify({ type: 'negative', message: d.error || 'Échec' })
  } catch (e) { $q.notify({ type: 'negative', message: e.message }) } finally { planning.value = false }
}
// Quand le client résolu change (ou au chargement) : récupère ses adresses de service et présélectionne celle qui matche.
async function onResolved (a) {
  if (a.type !== 'create_ticket' || !a.resolved || !a.resolved.name) { a._locs = []; return }
  a.service_location = a.resolved.service_location || ''
  try {
    const r = await fetch(`${HUB_URL}/collab/service-locations?customer=${encodeURIComponent(a.resolved.name)}`)
    if (r.ok) { const d = await r.json(); a._locs = d.locations || []; if (!a.service_location && a._locs.length) a.service_location = a._locs[0].name } // adresse de service active la plus récente (triée 1re)
  } catch (e) { a._locs = [] }
}
function locLabel (a) { const l = (a._locs || []).find(x => x.name === a.service_location); return l ? l.address : a.service_location }
async function run () {
  running.value = true
  try {
    const r = await fetch(`${HUB_URL}/collab/orchestrate/run`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ actions: writeActions.value }) })
    const d = await r.json()
    results.value = d.results || []
    const ok = results.value.filter(x => x.ok).length
    $q.notify({ type: ok ? 'positive' : 'negative', message: `${ok}/${results.value.length} action(s) exécutée(s)` })
    emit('done')
  } catch (e) { $q.notify({ type: 'negative', message: e.message }) } finally { running.value = false }
}
</script>

<style scoped>
.orch-act { border: 1px solid #e2e8f0; border-radius: 8px; padding: 10px; margin-bottom: 8px; background: #faf9ff; }
.orch-diag { border: 1px solid #e0e7ff; border-radius: 8px; padding: 10px; margin-bottom: 8px; background: #f5f7ff; }
.diag-dot { width: 11px; height: 11px; border-radius: 50%; margin-right: 10px; flex: 0 0 auto; }
</style>
