<template>
  <div class="dept-wrap">
    <div class="dept-head">
      <div class="text-caption text-grey-7">{{ totalActive }} active(s) · glisser une carte = classer dans une file · clic = ouvrir le fil</div>
      <q-space />
      <q-toggle v-model="showResolved" dense size="sm" label="Inclure résolues" color="grey-7" class="q-mr-sm" />
      <q-btn flat dense round icon="refresh" :loading="loading" @click="fetchList" />
    </div>

    <div class="dept-board">
      <div v-for="dep in depts" :key="dep" class="dept-col" :class="{ 'drop-hover': dropDept === dep }"
           @dragover.prevent="dropDept = dep" @dragleave="dropDept === dep && (dropDept = null)" @drop="onDrop(dep)">
        <div class="dept-col-hd" :class="dep === UNASSIGNED ? 'dh-unassigned' : 'dh-' + slug(dep)">
          <q-icon :name="deptIcon(dep)" size="16px" class="q-mr-xs" />
          <span class="ellipsis col">{{ dep }}</span>
          <q-badge color="white" text-color="grey-9" class="q-ml-xs">{{ (columns[dep] || []).length }}</q-badge>
          <q-btn flat dense round icon="add" size="xs" color="white" class="q-ml-xs">
            <q-tooltip>Composer dans « {{ dep }} »</q-tooltip>
            <q-menu auto-close>
              <q-list dense style="min-width:160px">
                <q-item clickable @click="compose('email', dep)"><q-item-section avatar><q-icon name="mail" color="red-5" /></q-item-section><q-item-section>Nouveau courriel</q-item-section></q-item>
                <q-item clickable @click="compose('sms', dep)"><q-item-section avatar><q-icon name="sms" color="teal-6" /></q-item-section><q-item-section>Nouveau texto</q-item-section></q-item>
              </q-list>
            </q-menu>
          </q-btn>
        </div>
        <div class="dept-col-body">
          <div v-for="d in (columns[dep] || [])" :key="d.id" class="dept-card" :class="{ 'needs-reply': needsReply(d) }"
               draggable="true" @dragstart="onDragStart(d)" @dragend="dragCard = null" @click="openCard(d)">
            <div class="dept-card-t">
              <q-icon :name="d.channel === 'email' ? 'mail' : 'sms'" size="13px" class="q-mr-xs" :color="d.channel === 'email' ? 'red-5' : 'teal-6'" />
              <span class="ellipsis col">{{ d.customerName || d.email || d.phone || 'Inconnu' }}</span>
              <q-badge v-if="d.status === 'active'" color="green" class="q-ml-xs" style="font-size:.55rem;padding:1px 4px">actif</q-badge>
            </div>
            <div class="dept-card-s ellipsis">{{ preview(d) }}</div>
            <div class="dept-card-m">
              <span class="text-grey-6">{{ relTime(d.lastMessage && d.lastMessage.ts) }}</span>
              <q-icon v-if="needsReply(d)" name="reply" size="12px" color="blue-7" class="q-ml-xs"><q-tooltip>En attente de réponse</q-tooltip></q-icon>
              <q-space />
              <span v-if="d.assignee" class="dept-assignee"><q-icon name="pan_tool" size="11px" /> {{ shortAgent(d.assignee) }}</span>
            </div>
          </div>
          <div v-if="!(columns[dep] || []).length" class="dept-empty">—</div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { useQuasar } from 'quasar'
import { useConversations } from 'src/composables/useConversations'
import { shortAgent, relTime } from 'src/composables/useFormatters'

const $q = useQuasar()
const {
  discussions, QUEUES, assignQueue, fetchList, loading,
  openDiscussion, panelOpen, newDialogOpen, newDialogChannel,
} = useConversations()

const UNASSIGNED = 'Non assigné'
const depts = computed(() => [...QUEUES, UNASSIGNED])
const showResolved = ref(false)
const dragCard = ref(null)
const dropDept = ref(null)

const DEPT_ICONS = {
  'Facturations': 'request_quote',
  'Service à la clientèle': 'support_agent',
  'Support': 'build',
  'Supports': 'build',
  'Technicien': 'engineering',
}
function deptIcon (dep) { return dep === UNASSIGNED ? 'inbox' : (DEPT_ICONS[dep] || 'groups') }
function slug (s) { return String(s).normalize('NFD').replace(/[̀-ͯ]/g, '').toLowerCase().replace(/[^a-z]+/g, '-').replace(/^-|-$/g, '') }
function needsReply (d) { return d.status === 'active' && d.lastMessage && d.lastMessage.from === 'customer' }
function preview (d) { return d.subject || (d.lastMessage && d.lastMessage.text) || '—' }
function tsOf (d) { const t = d.lastMessage && d.lastMessage.ts; const n = t ? new Date(t).getTime() : 0; return Number.isFinite(n) ? n : 0 }
// shortAgent + relTime (ex-fmtTime, logique identique) viennent de useFormatters (consolidation)

// Regroupe les discussions unifiées (SMS + courriel) par file/département.
const columns = computed(() => {
  const map = {}
  for (const dep of depts.value) map[dep] = []
  for (const d of (discussions.value || [])) {
    if (!showResolved.value && d.status === 'closed') continue
    const q = (d.queue && QUEUES.includes(d.queue)) ? d.queue : UNASSIGNED
    map[q].push(d)
  }
  for (const dep of depts.value) map[dep].sort((a, b) => tsOf(b) - tsOf(a))
  return map
})
const totalActive = computed(() => (discussions.value || []).filter(d => d.status === 'active').length)

// Jeton de conversation à classer (active sinon dernière sinon token de la discussion).
function discToken (d) {
  const active = (d.conversations || []).find(c => c.status === 'active')
  return (active && active.token) || d.token || (((d.conversations || []).slice(-1)[0]) || {}).token || null
}

function onDragStart (d) { dragCard.value = d }
async function onDrop (dep) {
  dropDept.value = null
  const d = dragCard.value; dragCard.value = null
  if (!d) return
  const tok = discToken(d)
  if (!tok) { $q.notify({ type: 'warning', message: 'Conversation sans jeton — impossible de classer.' }); return }
  const newQueue = dep === UNASSIGNED ? '' : dep
  if ((d.queue || '') === newQueue) return
  const prev = d.queue
  d.queue = newQueue // déplacement optimiste (assignQueue rafraîchit ensuite la liste)
  try {
    await assignQueue(tok, newQueue)
    $q.notify({ type: 'positive', message: `${d.customerName || d.phone || 'Conversation'} → ${dep}`, timeout: 1200 })
  } catch (e) { d.queue = prev; $q.notify({ type: 'negative', message: 'Échec du classement' }) }
}

function openCard (d) { panelOpen.value = true; openDiscussion(d) }

// Envoi depuis une colonne : ouvre le dialogue partagé (rendu dans ConversationPanel, hors du tiroir).
// v1 : la nouvelle conversation atterrit en « Non assigné » → l'agent la glisse dans la bonne file (auto-routage à venir).
function compose (channel /* , dep */) {
  newDialogChannel.value = channel
  newDialogOpen.value = true
}

onMounted(() => { if (!discussions.value || !discussions.value.length) fetchList() })
</script>

<style scoped>
.dept-wrap { padding: 10px 14px; }
.dept-head { display: flex; align-items: center; margin-bottom: 10px; }
.dept-board { display: flex; gap: 12px; overflow-x: auto; align-items: flex-start; padding-bottom: 8px; }
.dept-col { flex: 0 0 270px; background: #f1f5f9; border-radius: 10px; display: flex; flex-direction: column; max-height: calc(100vh - 230px); }
.dept-col.drop-hover { outline: 2px dashed #6366f1; outline-offset: -2px; }
.dept-col-hd { display: flex; align-items: center; font-weight: 700; font-size: .8rem; color: #fff; padding: 7px 10px; border-radius: 10px 10px 0 0; }
.dh-facturations { background: #d97706; }
.dh-service-a-la-clientele { background: #6366f1; }
.dh-support, .dh-supports { background: #0891b2; }
.dh-technicien { background: #16a34a; }
.dh-unassigned { background: #64748b; }
.dept-col-body { padding: 8px; overflow-y: auto; display: flex; flex-direction: column; gap: 7px; }
.dept-card { background: #fff; border: 1px solid #e2e8f0; border-radius: 8px; padding: 8px 10px; cursor: pointer; box-shadow: 0 1px 2px rgba(0,0,0,.04); }
.dept-card:hover { border-color: #6366f1; }
.dept-card.needs-reply { border-left: 3px solid #2563eb; background: #eff6ff; }
.dept-card-t { font-weight: 600; font-size: .82rem; display: flex; align-items: center; }
.dept-card-s { font-size: .75rem; color: #475569; margin-top: 2px; }
.dept-card-m { display: flex; align-items: center; font-size: .68rem; margin-top: 5px; }
.dept-assignee { color: #b45309; font-weight: 600; }
.dept-empty { text-align: center; color: #cbd5e1; padding: 10px; font-size: .8rem; }
.col { min-width: 0; }
@media (max-width: 640px) {
  .dept-board { scroll-snap-type: x mandatory; }
  .dept-col { flex-basis: 86vw; scroll-snap-align: start; max-height: calc(100vh - 200px); }
}
</style>
