<template>
  <div class="ops-card q-mb-md">
    <div class="row items-center q-mb-xs">
      <q-icon name="inbox" size="20px" color="primary" class="q-mr-sm" />
      <span class="text-subtitle1 text-weight-bold">Files (Inbox) & équipes</span>
      <q-space />
      <q-spinner v-if="loading" size="16px" color="primary" />
    </div>
    <div class="text-caption text-grey-6 q-mb-md">
      Qui reçoit et traite les demandes de chaque file. À l'arrivée d'une demande, ses membres sont notifiés (courriel + Inbox). Même logique que les groupes de droits — on cherche des utilisateurs et on les ajoute.
    </div>

    <!-- Liste des files -->
    <div class="row q-col-gutter-sm">
      <div class="col-12 col-sm-6 col-md-3" v-for="q in queues" :key="q">
        <div class="queue-card" :class="{ sel: selected === q }" @click="select(q)">
          <div class="row items-center no-wrap">
            <q-icon name="groups" size="18px" :color="selected === q ? 'primary' : 'grey-6'" class="q-mr-sm" />
            <span class="text-weight-medium">{{ label(q) }}</span>
            <q-space />
            <q-badge :color="(members[q] || []).length ? 'green-1' : 'grey-3'" :text-color="(members[q] || []).length ? 'green-8' : 'grey-6'">
              {{ (members[q] || []).length }}
            </q-badge>
          </div>
        </div>
      </div>
    </div>

    <!-- Détail file -->
    <q-slide-transition>
      <div v-if="selected" class="queue-detail q-mt-md">
        <div class="row items-center q-mb-sm">
          <q-icon name="groups" size="22px" color="primary" class="q-mr-sm" />
          <span class="text-h6">{{ label(selected) }}</span>
          <q-space />
          <q-btn flat round dense icon="close" @click="selected = null" />
        </div>

        <!-- Nom d'affichage (ex. singulier) — le nom réel (clé, = F, souvent au pluriel) reste inchangé -->
        <div class="row items-center q-gutter-sm q-mb-md">
          <q-input dense outlined v-model="labelDraft" label="Nom affiché" style="min-width:220px" @keyup.enter="saveLabel" @blur="saveLabel">
            <template #append><q-icon v-if="(labels[selected] || selected) !== labelDraft" name="edit" size="16px" color="green-5" /></template>
          </q-input>
          <span class="text-caption text-grey-6">Nom réel (F) : <b>{{ selected }}</b> — inchangé</span>
        </div>

        <div class="text-subtitle2 q-mb-xs">Membres ({{ (members[selected] || []).length }})</div>
        <div v-for="email in (members[selected] || [])" :key="email" class="row items-center q-py-xs q-px-sm qm-member-row">
          <q-avatar size="26px" color="green-1" text-color="green-8" class="q-mr-sm" style="font-size:.7rem">{{ initial(email) }}</q-avatar>
          <span class="text-body2">{{ email }}</span>
          <q-space />
          <q-btn flat round dense icon="person_remove" size="sm" color="negative" class="qm-del" @click="removeMember(email)"><q-tooltip>Retirer de la file</q-tooltip></q-btn>
        </div>
        <div v-if="!(members[selected] || []).length" class="text-caption text-grey-5 q-py-sm">Aucun membre — personne n'est notifié pour cette file.</div>

        <!-- Ajouter un membre (recherche utilisateurs Authentik) -->
        <div class="q-mt-sm" style="position:relative">
          <q-input v-model="search" label="Ajouter un membre…" outlined dense autocomplete="off" name="qm-add-nope" @update:model-value="onSearch">
            <template #append>
              <q-spinner v-if="searching" size="16px" color="primary" />
              <q-icon v-else-if="search" name="close" class="cursor-pointer" @click="search = ''; results = []" />
            </template>
          </q-input>
          <div v-if="results.length" class="qm-dropdown">
            <div v-for="u in results" :key="u.email || u.pk" class="qm-item" @click="addMember(u)">
              <q-avatar size="24px" color="green-1" text-color="green-8" class="q-mr-sm" style="font-size:.65rem">{{ initial(u.email || u.name) }}</q-avatar>
              <span class="text-body2">{{ u.name || u.username || u.email }}</span>
              <span class="text-caption text-grey-6 q-ml-sm">{{ u.email }}</span>
              <q-badge v-if="(members[selected] || []).includes((u.email || '').toLowerCase())" label="déjà membre" color="grey-3" text-color="grey-6" class="q-ml-auto" />
            </div>
          </div>
        </div>

        <!-- Importer tout un groupe Authentik (la table explicite reste la source) -->
        <div class="row items-center q-gutter-sm q-mt-sm">
          <q-select v-model="importGroupName" :options="groupsList" dense outlined options-dense style="min-width:200px" label="Importer un groupe Authentik" clearable emit-value map-options />
          <q-btn dense unelevated color="green-5" icon="group_add" label="Importer les membres" :disable="!importGroupName" :loading="importing" no-caps @click="importGroup" />
        </div>
      </div>
    </q-slide-transition>
  </div>
</template>

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

const $q = useQuasar()
const queues = ref(['Facturations', 'Service à la clientèle', 'Supports', 'Technicien'])
const members = ref({})
const selected = ref(null)
const loading = ref(false)
const search = ref('')
const searching = ref(false)
const results = ref([])
const groupsList = ref([])
const importGroupName = ref(null)
const importing = ref(false)
const labels = ref({})        // nom réel (clé) → libellé d'affichage
const labelDraft = ref('')
let _t = null

function initial (s) { return String(s || '?').trim().charAt(0).toUpperCase() }
function label (q) { return labels.value[q] || q } // affichage (singulier possible) ; la clé reste le nom réel

async function load () {
  loading.value = true
  try {
    const r = await fetch(`${HUB_URL}/conversations/queue-members`)
    if (r.ok) { const d = await r.json(); members.value = d.members || {}; labels.value = d.labels || {}; if (d.queues && d.queues.length) queues.value = d.queues }
  } catch (e) { /* */ } finally { loading.value = false }
  try {
    const g = await fetch(`${HUB_URL}/auth/groups`)
    if (g.ok) { const d = await g.json(); groupsList.value = (d.groups || d || []).map(x => ({ label: `${x.name}${x.num_users != null ? ' (' + x.num_users + ')' : ''}`, value: x.name })) }
  } catch (e) { /* */ }
}

async function importGroup () {
  if (!importGroupName.value || !selected.value) return
  importing.value = true
  try {
    const r = await fetch(`${HUB_URL}/auth/users?group=${encodeURIComponent(importGroupName.value)}`)
    const d = r.ok ? await r.json() : {}
    const emails = (d.users || d || []).map(u => String(u.email || '').toLowerCase()).filter(Boolean)
    const list = members.value[selected.value] || (members.value[selected.value] = [])
    let added = 0
    emails.forEach(e => { if (!list.includes(e)) { list.push(e); added++ } })
    if (added) { await save(); $q.notify({ type: 'positive', message: `${added} membre(s) de « ${importGroupName.value} » ajouté(s) à ${selected.value}` }) }
    else $q.notify({ type: 'info', message: 'Tous ces membres sont déjà dans la file', timeout: 1500 })
    importGroupName.value = null
  } catch (e) { $q.notify({ type: 'negative', message: 'Échec import groupe' }) } finally { importing.value = false }
}
function select (q) { selected.value = selected.value === q ? null : q; search.value = ''; results.value = []; labelDraft.value = selected.value ? label(selected.value) : '' }

function onSearch (v) {
  clearTimeout(_t)
  const q = String(v || '').trim()
  if (q.length < 2) { results.value = []; return }
  _t = setTimeout(async () => {
    searching.value = true
    try { const r = await fetch(`${HUB_URL}/auth/users?search=${encodeURIComponent(q)}`); if (r.ok) { const d = await r.json(); results.value = (d.users || d || []).filter(u => u && u.email).slice(0, 8) } } catch (e) { results.value = [] } finally { searching.value = false }
  }, 300)
}

async function save () {
  try { await fetch(`${HUB_URL}/conversations/queue-members`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ members: members.value, labels: labels.value }) }) } catch (e) { $q.notify({ type: 'negative', message: 'Échec sauvegarde' }) }
}
function saveLabel () {
  if (!selected.value) return
  const v = String(labelDraft.value || '').trim()
  const cur = labels.value[selected.value] || ''
  if (v && v !== selected.value) { if (cur === v) return; labels.value = { ...labels.value, [selected.value]: v } } // libellé personnalisé
  else { if (!cur) return; const cp = { ...labels.value }; delete cp[selected.value]; labels.value = cp } // vide ou = nom réel → retire le libellé
  save(); $q.notify({ type: 'positive', message: 'Nom affiché mis à jour', timeout: 1200 })
}
function addMember (u) {
  const email = String(u.email || '').toLowerCase(); if (!email || !selected.value) return
  const list = members.value[selected.value] || (members.value[selected.value] = [])
  if (!list.includes(email)) { list.push(email); save(); $q.notify({ type: 'positive', message: `${email} ajouté à ${selected.value}`, timeout: 1500 }) }
  search.value = ''; results.value = []
}
function removeMember (email) {
  if (!selected.value) return
  members.value[selected.value] = (members.value[selected.value] || []).filter(e => e !== email)
  save()
}

onMounted(load)
</script>

<style scoped>
.queue-card { border: 1px solid #e2e8f0; border-radius: 8px; padding: 10px 12px; cursor: pointer; transition: all .12s; }
.queue-card:hover { border-color: #a5b4fc; }
.queue-card.sel { border-color: #6366f1; background: #eef2ff; }
.queue-detail { border: 1px solid #e2e8f0; border-radius: 8px; padding: 14px; background: #fafbff; }
.qm-dropdown { position: absolute; z-index: 20; left: 0; right: 0; background: #fff; border: 1px solid #e2e8f0; border-radius: 8px; box-shadow: 0 6px 18px rgba(0,0,0,.12); margin-top: 2px; max-height: 240px; overflow-y: auto; }
.qm-item { display: flex; align-items: center; padding: 7px 10px; cursor: pointer; }
.qm-item:hover { background: #f1f5f9; }
/* Survol de la ligne membre → viser le bon « Retirer » dans une longue liste */
.qm-member-row { border-bottom: 1px solid #f1f5f9; border-radius: 6px; transition: background .1s; }
.qm-member-row:hover { background: #eff3ff; box-shadow: inset 3px 0 0 #6366f1; }
.qm-member-row .qm-del { opacity: .45; transition: opacity .1s; }
.qm-member-row:hover .qm-del { opacity: 1; }
</style>
