<template>
  <q-page padding>
    <div class="row items-center q-mb-md">
      <q-btn flat dense round icon="arrow_back" :to="'/campaigns'" class="q-mr-sm" />
      <div class="text-h5">Nouvelle campagne</div>
    </div>

    <q-stepper v-model="step" header-nav ref="stepper" color="primary" animated flat bordered class="bg-white">

      <!-- Step 1 — Upload + parameters ─────────────────────────────────── -->
      <q-step :name="1" title="Fichiers + paramètres" icon="upload_file" :done="step > 1" :header-nav="step > 1">
        <div class="row q-col-gutter-md">
          <div class="col-12 col-md-6">
            <q-card flat bordered>
              <q-card-section>
                <div class="text-subtitle1 q-mb-sm">1. Export Map CSV (brut)</div>
                <div class="text-caption text-grey-7 q-mb-md">
                  Le fichier <code>selectionAdressesMap*.csv</code> tel qu'exporté de la sélection
                  d'adresses (pipe-delimited, préambule de 1 ligne accepté).
                </div>
                <q-file v-model="mapFile" label="Sélectionner le fichier" accept=".csv" outlined dense @update:model-value="readMapFile">
                  <template v-slot:prepend><q-icon name="attach_file" /></template>
                </q-file>
                <div v-if="mapPreview" class="text-caption q-mt-sm text-grey-7">
                  ✓ {{ countMapRows(mapPreview) }} lignes de contacts (préambule + header retirés)
                </div>
              </q-card-section>
            </q-card>
          </div>
          <div class="col-12 col-md-6">
            <q-card flat bordered>
              <q-card-section>
                <div class="text-subtitle1 q-mb-sm">2. Shortlinks Giftbit CSV</div>
                <div class="text-caption text-grey-7 q-mb-md">
                  Le fichier <code>giftbit-gifts-&lt;id&gt;.csv</code> retourné par
                  <code>create_giftbit_campaign.js</code> (colonnes: firstname, lastname, email,
                  gift_url, giftbit_uuid, gift_value_cents).
                </div>
                <q-file v-model="giftFile" label="Sélectionner le fichier" accept=".csv" outlined dense @update:model-value="readGiftFile">
                  <template v-slot:prepend><q-icon name="attach_file" /></template>
                </q-file>
                <div v-if="giftPreview" class="text-caption q-mt-sm text-grey-7">
                  ✓ {{ countGiftRows(giftPreview) }} cartes-cadeaux
                  <span v-if="giftFormatHint" class="text-grey-6">(format: {{ giftFormatHint }})</span>
                </div>
              </q-card-section>
            </q-card>
          </div>
        </div>

        <q-card flat bordered class="q-mt-md">
          <q-card-section>
            <div class="text-subtitle1 q-mb-sm">Paramètres de la campagne</div>
            <div class="row q-col-gutter-md">
              <q-input v-model="params.name" label="Nom interne" outlined dense class="col-12 col-md-6" />
              <q-input v-model="params.amount" label="Montant (affiché)" outlined dense class="col-6 col-md-3" placeholder="60 $" />
              <q-input v-model.number="params.commitment_months" type="number" label="Engagement (mois)" outlined dense class="col-6 col-md-3" />
              <q-input v-model="params.subject" label="Sujet du courriel" outlined dense class="col-12 col-md-6" />
              <q-input v-model="params.from" label="Expéditeur (From)" outlined dense class="col-12 col-md-6" placeholder="TARGO <support@targointernet.com>" />
              <q-input v-model="params.expiry" label="Expiration (texte affiché)" outlined dense class="col-12 col-md-6" placeholder="31 décembre 2026" />
              <q-input v-model.number="params.throttle_ms" type="number" label="Throttle (ms entre envois)" outlined dense class="col-12 col-md-6" />
              <q-select v-model="params.multi" :options="multiOptions" emit-value map-options label="Emails multiples (couples)" outlined dense class="col-12 col-md-6" />
            </div>
          </q-card-section>
        </q-card>

        <q-stepper-navigation>
          <q-btn unelevated color="primary" label="Suivant — Aperçu" icon-right="arrow_forward"
                 :disable="!mapPreview || !giftPreview || parsing"
                 :loading="parsing" @click="goPreview" />
        </q-stepper-navigation>
      </q-step>

      <!-- Step 2 — Preview matched send list ─────────────────────────── -->
      <q-step :name="2" title="Aperçu et matching" icon="preview" :done="step > 2" :header-nav="step > 2">
        <!-- Counter strip — at a glance: total / paired / sendable / unmatched -->
        <div class="row q-col-gutter-sm q-mb-md">
          <q-card flat bordered class="col-6 col-md">
            <q-card-section class="text-center q-pa-sm">
              <div class="text-h5">{{ recipients.length }}</div>
              <div class="text-caption text-grey-7">Paires contact ↔ lien</div>
            </q-card-section>
          </q-card>
          <q-card flat bordered class="col-6 col-md" :class="{ 'bg-positive-1': sendableCount > 0 }">
            <q-card-section class="text-center q-pa-sm">
              <div class="text-h5 text-positive">{{ sendableCount }}</div>
              <div class="text-caption text-grey-7">À envoyer</div>
            </q-card-section>
          </q-card>
          <q-card flat bordered class="col-6 col-md">
            <q-card-section class="text-center q-pa-sm">
              <div class="text-h5 text-positive">{{ matchedCount }}</div>
              <div class="text-caption text-grey-7">Client lié</div>
            </q-card-section>
          </q-card>
          <q-card flat bordered class="col-6 col-md">
            <q-card-section class="text-center q-pa-sm">
              <div class="text-h5 text-warning">{{ unmatchedCount }}</div>
              <div class="text-caption text-grey-7">Sans client</div>
            </q-card-section>
          </q-card>
          <q-card flat bordered class="col-6 col-md" v-if="unpairedContacts.length">
            <q-card-section class="text-center q-pa-sm">
              <div class="text-h5 text-negative">{{ unpairedContacts.length }}</div>
              <div class="text-caption text-grey-7">Sans lien</div>
            </q-card-section>
          </q-card>
          <q-card flat bordered class="col-6 col-md" v-if="unusedGifts.length">
            <q-card-section class="text-center q-pa-sm">
              <div class="text-h5 text-orange">{{ unusedGifts.length }}</div>
              <div class="text-caption text-grey-7">Liens en surplus</div>
            </q-card-section>
          </q-card>
        </div>

        <!-- Imbalance banner: explicit explanation of what the imbalance means -->
        <q-banner v-if="unpairedContacts.length || unusedGifts.length" class="bg-orange-1 text-orange-9 q-mb-md" rounded>
          <template v-slot:avatar><q-icon name="warning" /></template>
          <div v-if="unpairedContacts.length">
            <strong>{{ unpairedContacts.length }} contact(s) sans lien-cadeau</strong> —
            ils n'apparaissent PAS dans la liste d'envoi ci-dessous et ne recevront rien.
            Pour les inclure, acquérir {{ unpairedContacts.length }} liens supplémentaires
            chez Giftbit et re-uploader le fichier.
          </div>
          <div v-if="unusedGifts.length" :class="unpairedContacts.length ? 'q-mt-xs' : ''">
            <strong>{{ unusedGifts.length }} lien(s) Giftbit non utilisés</strong> —
            il y a plus de cartes-cadeaux que de contacts. Le surplus sera perdu si
            la campagne est envoyée tel quel.
          </div>
        </q-banner>

        <!-- ✓ Paired recipients (will be sent) ────────────────────────── -->
        <div class="text-subtitle1 q-mb-xs">
          <q-icon name="link" /> Association contact ↔ lien-cadeau
          <span class="text-caption text-grey-7">— vérifier avant d'approuver</span>
        </div>
        <q-table
          :rows="recipients" :columns="recipientColumns" row-key="row_index"
          flat bordered dense :pagination="{ rowsPerPage: 25 }"
          :rows-per-page-options="[10, 25, 50, 100, 0]"
          class="q-mb-md"
        >
          <template v-slot:body-cell-row_index="props">
            <q-td :props="props" class="text-grey-6">#{{ props.row.row_index }}</q-td>
          </template>
          <template v-slot:body-cell-gift_url="props">
            <q-td :props="props">
              <a :href="props.row.gift_url" target="_blank" style="color:var(--q-primary); font-family:monospace; font-size:0.78rem">
                {{ shortenUrl(props.row.gift_url) }}
              </a>
            </q-td>
          </template>
          <template v-slot:body-cell-match="props">
            <q-td :props="props">
              <q-chip v-if="props.row.customer_id" dense color="positive" text-color="white" size="sm" :label="props.row.match_method" />
              <q-chip v-else dense color="warning" text-color="white" size="sm" label="non lié" />
            </q-td>
          </template>
          <template v-slot:body-cell-actions="props">
            <q-td :props="props" class="text-right">
              <q-btn flat dense size="sm" :icon="props.row.excluded ? 'add_circle' : 'block'"
                     :color="props.row.excluded ? 'positive' : 'negative'"
                     @click="props.row.excluded = !props.row.excluded">
                <q-tooltip>{{ props.row.excluded ? 'Inclure' : 'Exclure' }}</q-tooltip>
              </q-btn>
            </q-td>
          </template>
        </q-table>

        <!-- ⚠ Contacts that have NO gift-url (won't be sent) ─────────── -->
        <q-expansion-item v-if="unpairedContacts.length" expand-separator
                          icon="person_off" :label="`${unpairedContacts.length} contact(s) sans lien-cadeau (ne recevront pas)`"
                          header-class="bg-red-1 text-red-9">
          <q-table
            :rows="unpairedContacts" :columns="unpairedColumns" row-key="row_index"
            flat dense hide-bottom :pagination="{ rowsPerPage: 0 }"
          >
            <template v-slot:body-cell-row_index="props">
              <q-td :props="props" class="text-grey-6">#{{ props.row.row_index }}</q-td>
            </template>
          </q-table>
        </q-expansion-item>

        <!-- ⓘ Unused gift URLs (extra capacity) ────────────────────────── -->
        <q-expansion-item v-if="unusedGifts.length" expand-separator
                          icon="card_giftcard"
                          :label="`${unusedGifts.length} lien(s) Giftbit non utilisés`"
                          header-class="bg-orange-1 text-orange-9"
                          class="q-mt-sm">
          <q-list dense>
            <q-item v-for="g in unusedGifts" :key="g.gift_url">
              <q-item-section side class="text-grey-6">#{{ g.row_index }}</q-item-section>
              <q-item-section>
                <a :href="g.gift_url" target="_blank" style="color:var(--q-primary); font-family:monospace; font-size:0.85rem">{{ g.gift_url }}</a>
              </q-item-section>
            </q-item>
          </q-list>
        </q-expansion-item>

        <q-stepper-navigation>
          <q-btn flat label="Retour" @click="step = 1" />
          <q-btn unelevated color="primary" :label="`Approuver — ${sendableCount} à envoyer`" icon-right="send"
                 class="q-ml-sm" @click="step = 3" :disable="sendableCount === 0" />
        </q-stepper-navigation>
      </q-step>

      <!-- Step 3 — Confirm + send ──────────────────────────────────────── -->
      <q-step :name="3" title="Confirmation" icon="send">
        <q-card flat bordered>
          <q-card-section>
            <div class="text-subtitle1 q-mb-sm">Récapitulatif</div>
            <q-list dense>
              <q-item><q-item-section side>Nom</q-item-section><q-item-section>{{ params.name }}</q-item-section></q-item>
              <q-item><q-item-section side>Destinataires actifs</q-item-section><q-item-section>{{ sendableCount }} (sur {{ recipients.length }} paires ; {{ excludedCount }} exclus, {{ unpairedContacts.length }} sans lien)</q-item-section></q-item>
              <q-item><q-item-section side>Montant affiché</q-item-section><q-item-section>{{ params.amount }}</q-item-section></q-item>
              <q-item><q-item-section side>Engagement</q-item-section><q-item-section>{{ params.commitment_months }} mois</q-item-section></q-item>
              <q-item><q-item-section side>Sujet</q-item-section><q-item-section>{{ params.subject }}</q-item-section></q-item>
              <q-item><q-item-section side>Expéditeur</q-item-section><q-item-section>{{ params.from }}</q-item-section></q-item>
              <q-item><q-item-section side>Throttle</q-item-section><q-item-section>{{ params.throttle_ms }} ms entre envois (≈ {{ Math.round((60 / (params.throttle_ms / 1000)) || 0) }} emails/min)</q-item-section></q-item>
              <q-item><q-item-section side>Durée estimée</q-item-section><q-item-section>≈ {{ estimatedMinutes }} min</q-item-section></q-item>
            </q-list>
          </q-card-section>
          <q-card-section class="bg-orange-1 text-orange-9">
            <q-icon name="info" /> L'envoi démarre dès que vous cliquez ci-dessous.
            Vous serez redirigé vers la page de progression en temps réel.
          </q-card-section>
        </q-card>
        <q-stepper-navigation>
          <q-btn flat label="Retour" @click="step = 2" />
          <q-btn unelevated color="primary" label="Lancer l'envoi" icon-right="send"
                 class="q-ml-sm" :loading="sending" @click="launchSend" />
        </q-stepper-navigation>
      </q-step>

    </q-stepper>
  </q-page>
</template>

<script setup>
import { ref, computed } from 'vue'
import { useRouter } from 'vue-router'
import { useQuasar } from 'quasar'
import { parseCsvs, createCampaign, sendCampaign } from 'src/api/campaigns'

const $q = useQuasar()
const router = useRouter()
const step = ref(1)

const mapFile = ref(null)
const giftFile = ref(null)
const mapPreview = ref('')
const giftPreview = ref('')

const params = ref({
  name: `Campagne ${new Date().toISOString().slice(0,10)}`,
  amount: '60 $',
  commitment_months: 3,
  subject: '🎁 Un cadeau pour vous, de la part de TARGO',
  from: 'TARGO <support@targointernet.com>',
  expiry: '',
  throttle_ms: 600,
  multi: 'first',
})
const multiOptions = [
  { label: '1er email seulement (1 cadeau/foyer)', value: 'first' },
  { label: 'Séparer en 2 rangées (1 cadeau/personne)', value: 'split' },
  { label: 'Ignorer les couples', value: 'skip' },
]

const parsing = ref(false)
const sending = ref(false)
const recipients = ref([])
const unpairedContacts = ref([])
const unusedGifts = ref([])

// row_index (#1, #2, ...) is the source-CSV position — invaluable for the
// user to cross-reference what they see here against the file they uploaded.
// gift_url is rendered as a clickable short label so contact↔link pairing
// can be eyeballed at a glance and the user can click through to verify
// the shortlink works.
const recipientColumns = [
  { name: 'row_index', label: '#', field: 'row_index', align: 'left' },
  { name: 'firstname', label: 'Prénom', field: 'firstname', align: 'left' },
  { name: 'lastname', label: 'Nom', field: 'lastname', align: 'left' },
  { name: 'email', label: 'Email', field: 'email', align: 'left' },
  { name: 'civic_address', label: 'Adresse', field: 'civic_address', align: 'left' },
  { name: 'gift_url', label: 'Lien-cadeau', field: 'gift_url', align: 'left' },
  { name: 'match', label: 'Match client', field: 'match_method', align: 'left' },
  { name: 'customer_name', label: 'Client ERPNext', field: 'customer_name', align: 'left' },
  { name: 'actions', label: '', field: '', align: 'right' },
]

const unpairedColumns = [
  { name: 'row_index', label: '#', field: 'row_index', align: 'left' },
  { name: 'firstname', label: 'Prénom', field: 'firstname', align: 'left' },
  { name: 'lastname', label: 'Nom', field: 'lastname', align: 'left' },
  { name: 'email', label: 'Email', field: 'email', align: 'left' },
  { name: 'civic_address', label: 'Adresse', field: 'civic_address', align: 'left' },
  { name: 'postal_code', label: 'Code postal', field: 'postal_code', align: 'left' },
]

const matchedCount = computed(() => recipients.value.filter(r => r.customer_id).length)
const unmatchedCount = computed(() => recipients.value.filter(r => !r.customer_id).length)
const excludedCount = computed(() => recipients.value.filter(r => r.excluded).length)
// Net number of emails that will actually be fired off (paired AND not excluded)
const sendableCount = computed(() => recipients.value.filter(r => !r.excluded && r.gift_url).length)
const estimatedMinutes = computed(() => {
  const per = (params.value.throttle_ms || 600) / 1000
  return Math.max(1, Math.round((sendableCount.value * per) / 60))
})

function shortenUrl (u) {
  if (!u) return ''
  return u.replace(/^https?:\/\//, '').slice(0, 28) + (u.length > 35 ? '…' : '')
}

function readFile (file) {
  return new Promise((resolve, reject) => {
    const r = new FileReader()
    r.onload = () => resolve(r.result)
    r.onerror = reject
    r.readAsText(file, 'utf-8')
  })
}
async function readMapFile (file) { if (file) mapPreview.value = await readFile(file) }
async function readGiftFile (file) { if (file) giftPreview.value = await readFile(file) }

// Counts must mirror the backend parser exactly so the user sees the same
// numbers in the preview as what Step 2 will receive.

// Map CSV format: 1-line title preamble + header row + N data rows.
// Returns N (the # of contact lines, excluding the preamble and header).
function countMapRows (text) {
  if (!text) return 0
  const lines = text.split(/\r?\n/).filter(l => l.trim())
  // -1 for preamble, -1 for header
  return Math.max(0, lines.length - 2)
}

// Giftbit CSV: TWO formats
//   1. "Link Order" — headerless, one URL per line (each URL = 1 gift)
//   2. "Campaign export" — header row + N data rows (-1 for header)
// Detect like the backend: first non-empty line is a bare URL with no
// separator → no header.
function countGiftRows (text) {
  if (!text) return 0
  const cleaned = text.replace(/^﻿/, '').trim()
  if (!cleaned) return 0
  const firstLine = cleaned.split(/\r?\n/, 1)[0].trim()
  const isLinkOrder = /^https?:\/\/\S+$/.test(firstLine) &&
                      !firstLine.includes(',') && !firstLine.includes('\t') && !firstLine.includes('|')
  const lines = cleaned.split(/\r?\n/).filter(l => l.trim())
  return isLinkOrder ? lines.length : Math.max(0, lines.length - 1)
}

// Show "Link Order" or "Campaign export" hint next to the gift count
const giftFormatHint = computed(() => {
  if (!giftPreview.value) return ''
  const firstLine = giftPreview.value.replace(/^﻿/, '').trim().split(/\r?\n/, 1)[0].trim()
  if (/^https?:\/\/\S+$/.test(firstLine) && !firstLine.includes(',') && !firstLine.includes('\t') && !firstLine.includes('|')) {
    return 'Link Order'
  }
  return 'Campaign export'
})

async function goPreview () {
  if (!mapPreview.value || !giftPreview.value) return
  parsing.value = true
  try {
    const r = await parseCsvs({ map_csv: mapPreview.value, giftbit_csv: giftPreview.value, multi: params.value.multi })
    recipients.value      = r.recipients || []
    unpairedContacts.value = r.unpaired_contacts || []
    unusedGifts.value      = r.unused_gifts || []
    step.value = 2
  } catch (e) {
    $q.notify({ type: 'negative', message: 'Erreur de parsing: ' + e.message })
  } finally {
    parsing.value = false
  }
}

async function launchSend () {
  sending.value = true
  try {
    const saved = await createCampaign({
      name: params.value.name,
      params: { ...params.value },
      recipients: recipients.value,
    })
    await sendCampaign(saved.id)
    router.push(`/campaigns/${saved.id}`)
  } catch (e) {
    $q.notify({ type: 'negative', message: 'Erreur: ' + e.message })
  } finally {
    sending.value = false
  }
}
</script>
