<template>
  <q-page class="q-pa-md" style="max-width:900px;margin:0 auto">
    <div class="text-h6 q-mb-xs">🤖 Copilote dispatch</div>
    <div class="text-caption text-grey-7 q-mb-md">
      Demande en langage naturel (texte ou voix) l'impact d'une absence et des idées de réassignation.
      Ex : « Kadi est malade le 16 juin, quel impact et quelles réassignations ? »
    </div>

    <!-- Politique de reprise -->
    <q-card flat bordered class="q-pa-md q-mb-md">
      <div class="text-subtitle2 q-mb-sm">Politique de reprise (technicien indisponible)</div>
      <q-select dense outlined emit-value map-options
        v-model="policy.reschedule" :options="opts.reschedule"
        label="Quand un tech ne peut se présenter" :loading="loadingPolicy" />
      <div class="row items-center q-gutter-md q-mt-sm">
        <q-toggle v-model="policy.sms_enabled" label="SMS client activé" />
        <q-toggle v-model="policy.sms_quiet_hours" label="Pas la nuit (21h–8h)" />
        <q-select dense outlined emit-value map-options style="min-width:260px"
          v-model="policy.escalation" :options="opts.escalation" label="Escalade superviseur" />
        <q-space />
        <q-btn unelevated color="primary" label="Enregistrer" :loading="savingPolicy" @click="doSavePolicy" />
      </div>
      <div v-if="policySaved" class="text-positive text-caption q-mt-xs">✓ Politique enregistrée</div>
    </q-card>

    <!-- Chat -->
    <q-card flat bordered class="q-pa-md">
      <div ref="scrollEl" style="max-height:52vh;overflow:auto" class="q-pb-sm">
        <div v-if="!messages.length" class="text-grey-6 text-center q-pa-lg">
          Pose ta question — j'analyse l'équipe et les rendez-vous réels avant de répondre.
        </div>
        <q-chat-message v-for="(m, i) in messages" :key="i"
          :sent="m.role === 'user'"
          :bg-color="m.role === 'user' ? 'primary' : 'grey-2'"
          :text-color="m.role === 'user' ? 'white' : 'grey-10'">
          <div style="white-space:pre-wrap">{{ m.content }}</div>
        </q-chat-message>
        <q-chat-message v-if="loading" :text="['…']" bg-color="grey-2" />
      </div>
      <q-separator class="q-my-sm" />
      <div class="row items-end q-gutter-sm">
        <q-input class="col" outlined dense autogrow v-model="input"
          placeholder="Ex : Simon Clo est malade aujourd'hui, quel impact ?"
          @keyup.enter.exact.prevent="send" />
        <q-btn v-if="voiceOk" round flat :color="listening ? 'red' : 'grey-7'"
          :icon="listening ? 'mic' : 'mic_none'" @click="toggleVoice" :title="listening ? 'Arrêter' : 'Dicter'" />
        <q-btn round unelevated color="primary" icon="send" :loading="loading"
          :disable="!input.trim()" @click="send" />
      </div>
    </q-card>
  </q-page>
</template>

<script setup>
import { ref, reactive, onMounted, nextTick } from 'vue'
import { askAssistant, getPolicy, savePolicy } from 'src/api/roster'

const messages = ref([])
const input = ref('')
const loading = ref(false)
const scrollEl = ref(null)

const policy = reactive({ reschedule: 'auto_then_sms_then_super', sms_enabled: true, sms_quiet_hours: true, escalation: 'queue_sms' })
const opts = reactive({ reschedule: [], escalation: [] })
const loadingPolicy = ref(false)
const savingPolicy = ref(false)
const policySaved = ref(false)

onMounted(async () => {
  loadingPolicy.value = true
  try {
    const d = await getPolicy()
    Object.assign(policy, d.policy || {})
    opts.reschedule = d.options?.reschedule || []
    opts.escalation = d.options?.escalation || []
  } catch (e) { /* defaults */ }
  loadingPolicy.value = false
})

async function doSavePolicy () {
  savingPolicy.value = true; policySaved.value = false
  try { await savePolicy({ ...policy }); policySaved.value = true; setTimeout(() => { policySaved.value = false }, 2500) }
  catch (e) { /* ignore */ }
  savingPolicy.value = false
}

async function scrollDown () { await nextTick(); if (scrollEl.value) scrollEl.value.scrollTop = scrollEl.value.scrollHeight }

async function send () {
  const text = input.value.trim()
  if (!text || loading.value) return
  messages.value.push({ role: 'user', content: text })
  input.value = ''
  loading.value = true
  await scrollDown()
  try {
    const hist = messages.value.slice(-8).map(m => ({ role: m.role, content: m.content }))
    const d = await askAssistant(text, hist)
    messages.value.push({ role: 'assistant', content: d.reply || 'Aucune réponse.' })
  } catch (e) {
    messages.value.push({ role: 'assistant', content: 'Erreur : ' + (e.message || e) })
  }
  loading.value = false
  await scrollDown()
}

// ── Voix (Web Speech API, navigateur) ──
const SR = (typeof window !== 'undefined') && (window.SpeechRecognition || window.webkitSpeechRecognition)
const voiceOk = !!SR
const listening = ref(false)
let rec = null
function toggleVoice () {
  if (!SR) return
  if (listening.value) { try { rec && rec.stop() } catch {} ; return }
  rec = new SR(); rec.lang = 'fr-CA'; rec.interimResults = false; rec.maxAlternatives = 1
  rec.onresult = (e) => { const t = e.results[0][0].transcript; input.value = (input.value ? input.value + ' ' : '') + t }
  rec.onend = () => { listening.value = false }
  rec.onerror = () => { listening.value = false }
  listening.value = true
  try { rec.start() } catch { listening.value = false }
}
</script>
