<template>
  <div class="pipe-wrap">
    <div class="pipe-head">
      <div v-if="!embedded" class="text-h6 text-weight-bold">Pipeline de ventes</div>
      <div v-else class="text-subtitle2 text-weight-bold text-grey-8">Leads</div>
      <q-space />
      <div class="text-caption text-grey-7 q-mr-md">{{ totalLeads }} lead(s) · {{ openLeads }} en cours<span v-if="pipelineValue > 0"> · <b class="text-primary">{{ formatMoney(pipelineValue) }}</b> en pipeline</span></div>
      <q-btn flat dense round icon="refresh" :loading="loading" @click="load" />
    </div>

    <div class="pipe-board">
      <div v-for="st in stages" :key="st" class="pipe-col">
        <div class="pipe-col-hd" :class="stageClass(st)">
          <span>{{ st }}</span>
          <q-badge color="white" text-color="grey-9" class="q-ml-xs">{{ (columns[st] || []).length }}</q-badge>
          <q-space />
          <span v-if="colTotal(st) > 0" style="font-size:.72rem;opacity:.92;font-weight:600">{{ formatMoney(colTotal(st)) }}</span>
        </div>
        <!-- vuedraggable (SortableJS) : glisser-déposer qui marche AU DOIGT — appui long 160ms sur tactile
             (delay-on-touch-only → le défilement reste fluide), instantané à la souris sur desktop. -->
        <draggable :list="columns[st]" group="pipeline" item-key="token" class="pipe-col-body"
                   :animation="150" :delay="160" :delay-on-touch-only="true" :touch-start-threshold="6" ghost-class="pipe-ghost"
                   @change="(e) => onDragChange(e, st)">
          <template #item="{ element: c }">
            <div class="pipe-card" @click="openLead(c)">
              <div class="pipe-card-t">
                <q-icon :name="c.channel === 'email' ? 'mail' : 'sms'" size="13px" class="q-mr-xs" :color="c.channel === 'email' ? 'red-5' : 'teal-6'" />
                {{ c.customerName || c.contact || 'Lead' }}
                <q-badge v-if="c.is_customer" color="green-2" text-color="green-9" class="q-ml-xs" style="font-size:.6rem">client</q-badge>
              </div>
              <div class="pipe-card-s ellipsis">{{ c.subject || '—' }}</div>
              <div class="pipe-card-m">
                <span v-if="c.value > 0" class="pipe-val">{{ formatMoney(c.value) }}</span>
                <span v-else-if="c.contact" class="text-grey-6 ellipsis" style="max-width:130px">{{ c.contact }}</span>
                <q-space />
                <span v-if="c.assignee" class="pipe-assignee"><q-icon name="pan_tool" size="11px" /> {{ shortAgent(c.assignee) }}</span>
              </div>
            </div>
          </template>
          <template #footer>
            <div v-if="!(columns[st] || []).length" class="pipe-empty">Glissez un lead ici</div>
          </template>
        </draggable>
      </div>
    </div>
  </div>
</template>

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

defineProps({ embedded: Boolean })

const $q = useQuasar()
const { pipelineBoard, setPipeline, fetchList, discussions, openDiscussion, panelOpen } = useConversations()

const stages = ref(['Nouveau', 'Qualifié', 'Devis', 'Gagné', 'Perdu'])
const columns = ref({})
const loading = ref(false)

const totalLeads = computed(() => Object.values(columns.value).reduce((s, a) => s + a.length, 0))
const openLeads = computed(() => ['Nouveau', 'Qualifié', 'Devis'].reduce((s, st) => s + ((columns.value[st] || []).length), 0))
function colTotal (st) { return (columns.value[st] || []).reduce((s, c) => s + (c.value || 0), 0) }
const pipelineValue = computed(() => ['Nouveau', 'Qualifié', 'Devis'].reduce((s, st) => s + colTotal(st), 0))   // valeur ouverte (hors Gagné/Perdu)

// shortAgent vient de useFormatters (consolidation)
function stageClass (st) { return 'st-' + st.normalize('NFD').replace(/[̀-ͯ]/g, '').toLowerCase() }

async function load () {
  loading.value = true
  try {
    const b = await pipelineBoard()
    if (b.stages && b.stages.length) stages.value = b.stages
    const cols = b.columns || {}
    for (const st of stages.value) if (!Array.isArray(cols[st])) cols[st] = [] // chaque étape = vrai tableau (requis par vuedraggable :list)
    columns.value = cols
  } catch (e) { /* */ } finally { loading.value = false }
}

// vuedraggable a DÉJÀ déplacé la carte entre les colonnes (optimiste) ; on persiste seulement à l'arrivée (added).
async function onDragChange (evt, stage) {
  const c = evt && evt.added && evt.added.element
  if (!c || !stage) return
  try { await setPipeline(c.token, stage); $q.notify({ type: 'positive', message: `${c.customerName || 'Lead'} → ${stage}`, timeout: 1500 }) }
  catch (e) { $q.notify({ type: 'negative', message: 'Échec déplacement' }); load() }
}

async function openLead (c) {
  panelOpen.value = true
  let disc = discussions.value.find(d => d.token === c.token || (d.conversations || []).some(x => x.token === c.token))
  if (!disc) { await fetchList(); disc = discussions.value.find(d => d.token === c.token || (d.conversations || []).some(x => x.token === c.token)) }
  if (disc) openDiscussion(disc)
}

onMounted(load)
</script>

<style scoped>
.pipe-wrap { padding: 12px 16px; }
.pipe-head { display: flex; align-items: center; margin-bottom: 12px; }
.pipe-board { display: flex; gap: 12px; overflow-x: auto; align-items: flex-start; padding-bottom: 8px; }
.pipe-col { flex: 0 0 250px; background: #f1f5f9; border-radius: 10px; display: flex; flex-direction: column; max-height: calc(100vh - 220px); }
.pipe-col.drop-hover { outline: 2px dashed #6366f1; outline-offset: -2px; }
.pipe-col-hd { display: flex; align-items: center; font-weight: 700; font-size: .8rem; color: #fff; padding: 8px 10px; border-radius: 10px 10px 0 0; }
.st-nouveau { background: #64748b; } .st-qualifie { background: #6366f1; } .st-devis { background: #d97706; } .st-gagne { background: #16a34a; } .st-perdu { background: #dc2626; }
.pipe-col-body { padding: 8px; overflow-y: auto; display: flex; flex-direction: column; gap: 7px; }
.pipe-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); }
.pipe-card:hover { border-color: #6366f1; }
.pipe-ghost { opacity: .55; background: #eef2ff; border: 1px dashed #6366f1; }
.pipe-card-t { font-weight: 600; font-size: .82rem; display: flex; align-items: center; }
.pipe-card-s { font-size: .75rem; color: #475569; margin-top: 2px; }
.pipe-card-m { display: flex; align-items: center; font-size: .68rem; margin-top: 5px; }
.pipe-assignee { color: #b45309; font-weight: 600; }
.pipe-val { color: #4f46e5; font-weight: 700; }
.pipe-empty { text-align: center; color: #cbd5e1; padding: 10px; font-size: .8rem; }
@media (max-width: 640px) {
  .pipe-board { scroll-snap-type: x mandatory; }
  .pipe-col { flex-basis: 86vw; scroll-snap-align: start; }
}
</style>
