<template>
  <q-page padding>
    <!-- Real-time outage alerts -->
    <OutageAlertsPanel class="q-mb-md" @open-ticket="id => $router.push('/tickets')" />

    <!-- KPI cards -->
    <div class="row q-col-gutter-md q-mb-lg">
      <div class="col-6 col-md" v-for="stat in stats" :key="stat.label">
        <div class="ops-card ops-stat">
          <div class="row items-center no-wrap q-gutter-x-sm">
            <q-icon :name="stat.icon" :style="{ color: stat.color }" size="22px" />
            <div>
              <div class="ops-stat-value" :style="{ color: stat.color }">{{ stat.value }}</div>
              <div class="ops-stat-label">{{ stat.label }}</div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- Admin controls -->
    <div class="row q-col-gutter-md q-mb-lg">
      <div class="col-12 col-md-6">
        <div class="ops-card">
          <div class="text-subtitle1 text-weight-bold q-mb-sm">Planificateur</div>
          <div class="row items-center q-gutter-md">
            <q-chip :color="schedulerEnabled ? 'positive' : 'negative'" text-color="white" icon="schedule">
              {{ schedulerEnabled ? 'Actif' : 'Désactivé' }}
            </q-chip>
            <q-btn
              :label="schedulerEnabled ? 'Désactiver' : 'Activer'"
              :color="schedulerEnabled ? 'negative' : 'positive'"
              :icon="schedulerEnabled ? 'pause' : 'play_arrow'"
              :loading="togglingScheduler"
              dense no-caps
              @click="toggleScheduler"
            />
          </div>
        </div>
      </div>
      <div class="col-12 col-md-6">
        <div class="ops-card">
          <div class="text-subtitle1 text-weight-bold q-mb-sm">Facturation récurrente</div>

          <!-- Step indicators -->
          <div class="row items-center q-gutter-x-sm q-mb-sm">
            <q-chip :color="billingStep >= 1 ? 'primary' : 'grey-4'" text-color="white" dense size="sm" icon="receipt_long">1. Générer</q-chip>
            <q-icon name="chevron_right" size="16px" color="grey-5" />
            <q-chip :color="billingStep >= 2 ? 'amber-8' : 'grey-4'" text-color="white" dense size="sm" icon="publish">2. Soumettre</q-chip>
            <q-icon name="chevron_right" size="16px" color="grey-5" />
            <q-chip :color="billingStep >= 3 ? 'teal-7' : 'grey-4'" text-color="white" dense size="sm" icon="credit_score">3. PPA</q-chip>
          </div>

          <!-- Draft count indicator -->
          <div v-if="draftInvoiceCount > 0" class="q-mb-sm">
            <q-banner dense rounded class="bg-amber-1 text-warning" style="font-size:0.8rem">
              <template #avatar><q-icon name="pending_actions" color="warning" /></template>
              {{ draftInvoiceCount }} facture(s) en brouillon à soumettre
            </q-banner>
          </div>

          <div class="row items-center q-gutter-sm">
            <q-btn
              label="Générer"
              color="primary"
              icon="receipt_long"
              :loading="runningBilling"
              dense no-caps
              @click="runBilling"
            >
              <q-tooltip>Génère les factures récurrentes pour les abonnements actifs</q-tooltip>
            </q-btn>
            <q-btn
              label="Soumettre"
              color="warning"
              icon="publish"
              :loading="submittingDrafts"
              :disable="draftInvoiceCount === 0"
              dense no-caps
              @click="submitDrafts"
            >
              <q-tooltip>Soumet les {{ draftInvoiceCount }} facture(s) en brouillon</q-tooltip>
            </q-btn>
            <q-btn
              label="PPA"
              color="positive"
              icon="credit_score"
              :loading="runningPPA"
              dense no-caps
              @click="runPPA"
            >
              <q-tooltip>Prélève automatiquement les cartes enregistrées</q-tooltip>
            </q-btn>
          </div>
          <div class="q-mt-xs q-gutter-xs" style="min-height:20px">
            <span v-if="billingResult" class="text-caption" :class="billingResult.ok ? 'text-positive' : 'text-negative'">
              {{ billingResult.message }}
            </span>
            <span v-if="submitResult" class="text-caption" :class="submitResult.ok ? 'text-positive' : 'text-negative'">
              {{ submitResult.message }}
            </span>
            <span v-if="ppaResult" class="text-caption" :class="ppaResult.ok ? 'text-positive' : 'text-negative'">
              {{ ppaResult.message }}
            </span>
          </div>
        </div>
      </div>
    </div>

    <!-- Recent activity -->
    <div class="row q-col-gutter-md">
      <div class="col-12 col-md-6">
        <div class="ops-card">
          <div class="text-subtitle1 text-weight-bold q-mb-sm">Tickets ouverts</div>
          <q-list separator>
            <q-item v-for="t in openTickets" :key="t.name" clickable @click="$router.push('/tickets')">
              <q-item-section avatar style="min-width:32px">
                <q-icon name="confirmation_number" size="20px"
                  :color="t.priority === 'Urgent' ? 'red' : t.priority === 'High' ? 'orange-8' : 'grey-5'" />
              </q-item-section>
              <q-item-section>
                <q-item-label>{{ t.subject }}</q-item-label>
                <q-item-label caption>{{ t.customer_name || t.customer }}</q-item-label>
              </q-item-section>
              <q-item-section side>
                <span class="ops-badge open">{{ t.priority }}</span>
              </q-item-section>
            </q-item>
            <q-item v-if="!openTickets.length">
              <q-item-section>
                <q-item-label caption>Aucun ticket ouvert</q-item-label>
              </q-item-section>
            </q-item>
          </q-list>
        </div>
      </div>
      <div class="col-12 col-md-6">
        <div class="ops-card">
          <div class="text-subtitle1 text-weight-bold q-mb-sm">
            Dispatch aujourd'hui
            <q-badge v-if="todayJobs.length" :label="todayJobs.length" color="primary" class="q-ml-sm" />
          </div>
          <q-list separator>
            <q-item v-for="j in todayJobs" :key="j.name" clickable @click="$router.push('/dispatch')">
              <q-item-section avatar style="min-width:32px">
                <q-icon :name="j.status === 'completed' ? 'check_circle' : j.assigned_tech ? 'person' : 'radio_button_unchecked'"
                  :color="j.status === 'completed' ? 'green-6' : j.assigned_tech ? 'blue-6' : 'grey-5'" size="20px" />
              </q-item-section>
              <q-item-section>
                <q-item-label>{{ j.subject || j.name }}</q-item-label>
                <q-item-label caption>
                  <span v-if="j.assigned_tech">{{ j.assigned_tech }}</span>
                  <span v-if="j.customer"> &middot; {{ j.customer }}</span>
                </q-item-label>
              </q-item-section>
              <q-item-section side>
                <span class="ops-badge" :class="j.status === 'completed' ? 'active' : j.status === 'assigned' ? 'draft' : 'closed'">{{ j.status }}</span>
              </q-item-section>
            </q-item>
            <q-item v-if="!todayJobs.length">
              <q-item-section>
                <q-item-label caption>Aucune tâche planifiée aujourd'hui</q-item-label>
              </q-item-section>
            </q-item>
          </q-list>
        </div>
      </div>
    </div>
  </q-page>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { listDocs, countDocs } from 'src/api/erp'
import { authFetch } from 'src/api/auth'
import { BASE_URL } from 'src/config/erpnext'
import { HUB_SSE_URL } from 'src/config/dispatch'
import OutageAlertsPanel from 'src/components/shared/OutageAlertsPanel.vue'

const stats = ref([
  { label: 'Abonnés', value: '...', color: 'var(--ops-accent)', icon: 'people' },
  { label: 'Clients', value: '...', color: 'var(--ops-primary)', icon: 'business' },
  { label: 'Rev. mensuel', value: '...', color: 'var(--ops-success)', icon: 'attach_money' },
  { label: 'Tickets ouverts', value: '...', color: 'var(--ops-warning)', icon: 'confirmation_number' },
  { label: 'Dispatch aujourd\'hui', value: '...', color: 'var(--ops-accent)', icon: 'local_shipping' },
])

const openTickets = ref([])
const todayJobs = ref([])

// Scheduler controls
const schedulerEnabled = ref(false)
const togglingScheduler = ref(false)

async function fetchSchedulerStatus () {
  try {
    const res = await authFetch(BASE_URL + '/api/method/scheduler_status')
    if (res.ok) {
      const data = await res.json()
      schedulerEnabled.value = data.message?.status === 'enabled'
    }
  } catch {}
}

async function toggleScheduler () {
  togglingScheduler.value = true
  try {
    const res = await authFetch(BASE_URL + '/api/method/toggle_scheduler', { method: 'POST' })
    if (res.ok) {
      const data = await res.json()
      schedulerEnabled.value = data.message?.status === 'enabled'
    }
  } catch {}
  togglingScheduler.value = false
}

// ── Billing pipeline: Generate → Submit → PPA ──────────────────
const billingStep = ref(0) // 0=idle, 1=generated, 2=submitted, 3=ppa done
const runningBilling = ref(false)
const billingResult = ref(null)
const submittingDrafts = ref(false)
const submitResult = ref(null)
const runningPPA = ref(false)
const ppaResult = ref(null)
const draftInvoiceCount = ref(0)

async function refreshDraftCount () {
  try {
    const res = await authFetch(BASE_URL + '/api/method/frappe.client.get_count?doctype=Sales+Invoice&filters=' +
      encodeURIComponent(JSON.stringify({ docstatus: 0, is_return: 0 })))
    if (res.ok) {
      const data = await res.json()
      draftInvoiceCount.value = data.message || 0
    }
  } catch {}
}

async function runBilling () {
  runningBilling.value = true
  billingResult.value = null
  submitResult.value = null
  ppaResult.value = null
  billingStep.value = 0
  try {
    // Create a Process Subscription doc (submitting it enqueues the background job)
    const today = new Date().toISOString().slice(0, 10)
    const res = await authFetch(BASE_URL + '/api/resource/Process Subscription', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ posting_date: today }),
    })
    if (!res.ok) throw new Error('Erreur création: ' + res.status)
    const doc = (await res.json()).data

    // Submit it to trigger the background job (must pass full doc with modified timestamp)
    const submitRes = await authFetch(BASE_URL + '/api/method/frappe.client.submit', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ doc: doc }),
    })
    if (!submitRes.ok) throw new Error('Erreur soumission: ' + submitRes.status)

    // Poll background jobs until complete (max 60s)
    billingResult.value = { ok: true, message: 'Génération en cours...' }
    const startDrafts = draftInvoiceCount.value
    let attempts = 0
    while (attempts < 30) {
      await new Promise(r => setTimeout(r, 2000))
      await refreshDraftCount()
      attempts++
      // Check if background job finished by looking at job queue
      const jobRes = await authFetch(BASE_URL + '/api/method/frappe.client.get_list?' + new URLSearchParams({
        doctype: 'RQ Job',
        filters: JSON.stringify({ job_name: ['like', '%process_all%'], status: ['in', ['queued', 'started']] }),
        limit_page_length: 1,
      }))
      if (jobRes.ok) {
        const jobData = await jobRes.json()
        const jobs = jobData.data || jobData.message || []
        if (!jobs.length) break // no more running jobs
      } else {
        break // can't check, assume done
      }
    }

    await refreshDraftCount()
    const newDrafts = draftInvoiceCount.value - startDrafts
    billingResult.value = { ok: true, message: `Génération terminée. ${newDrafts > 0 ? newDrafts + ' nouvelle(s) facture(s)' : 'Aucune nouvelle facture'}.` }
    billingStep.value = 1
  } catch (e) {
    billingResult.value = { ok: false, message: e.message }
  }
  runningBilling.value = false
}

async function submitDrafts () {
  submittingDrafts.value = true
  submitResult.value = null
  try {
    // Get all draft invoices (docstatus=0, not credit notes)
    const draftsRes = await authFetch(BASE_URL + '/api/method/frappe.client.get_list?' + new URLSearchParams({
      doctype: 'Sales Invoice',
      filters: JSON.stringify({ docstatus: 0, is_return: 0 }),
      fields: JSON.stringify(['name']),
      limit_page_length: 500,
    }))
    if (!draftsRes.ok) throw new Error('Erreur lecture drafts: ' + draftsRes.status)
    const drafts = (await draftsRes.json()).message || []

    if (!drafts.length) {
      submitResult.value = { ok: true, message: 'Aucune facture en brouillon.' }
      submittingDrafts.value = false
      return
    }

    // Submit each draft (must fetch full doc for modified timestamp)
    let submitted = 0
    let errors = 0
    for (const d of drafts) {
      try {
        const docRes = await authFetch(BASE_URL + '/api/resource/Sales%20Invoice/' + encodeURIComponent(d.name))
        if (!docRes.ok) { errors++; continue }
        const fullDoc = (await docRes.json()).data
        const r = await authFetch(BASE_URL + '/api/method/frappe.client.submit', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ doc: fullDoc }),
        })
        if (r.ok) submitted++
        else errors++
      } catch {
        errors++
      }
    }

    await refreshDraftCount()
    submitResult.value = {
      ok: errors === 0,
      message: `${submitted} facture(s) soumise(s)${errors ? ', ' + errors + ' erreur(s)' : ''}.`,
    }
    billingStep.value = 2
  } catch (e) {
    submitResult.value = { ok: false, message: e.message }
  }
  submittingDrafts.value = false
}

async function runPPA () {
  runningPPA.value = true
  ppaResult.value = null
  try {
    const res = await fetch(HUB_SSE_URL + '/payments/ppa-run', { method: 'POST' })
    if (res.ok) {
      const data = await res.json()
      const charged = data.charged?.length || 0
      const failed = data.failed?.length || 0
      const skipped = data.skipped?.length || 0
      ppaResult.value = {
        ok: true,
        message: `PPA: ${charged} prélevé(s), ${failed} échoué(s), ${skipped} ignoré(s)`,
      }
      billingStep.value = 3
    } else {
      const err = await res.json().catch(() => ({}))
      ppaResult.value = { ok: false, message: err.error || 'Erreur ' + res.status }
    }
  } catch (e) {
    ppaResult.value = { ok: false, message: e.message }
  }
  runningPPA.value = false
}

onMounted(async () => {
  fetchSchedulerStatus()
  refreshDraftCount()

  const today = new Date().toISOString().slice(0, 10)

  const [clients, tickets, todayDispatch, openTix] = await Promise.all([
    countDocs('Customer', { disabled: 0 }),
    countDocs('Issue', { status: 'Open' }),
    listDocs('Dispatch Job', {
      filters: { scheduled_date: today },
      fields: ['name', 'subject', 'status', 'assigned_tech', 'customer', 'priority', 'source_issue'],
      limit: 50, orderBy: 'start_time asc',
    }).catch(() => []),
    listDocs('Issue', {
      filters: { status: 'Open' },
      fields: ['name', 'subject', 'customer', 'customer_name', 'priority', 'opening_date'],
      limit: 10, orderBy: 'opening_date desc',
    }),
  ])

  // Abonnés = unique customers with active subscriptions (via server script)
  let abonnes = 0
  let monthlyRev = 0
  try {
    const [subRes, revRes] = await Promise.all([
      authFetch(BASE_URL + '/api/method/subscriber_count').then(r => r.ok ? r.json() : null).catch(() => null),
      listDocs('Service Subscription', {
        filters: { status: 'Actif' },
        fields: ['actual_price'],
        limit: 0,
      }).catch(() => []),
    ])
    abonnes = subRes?.message?.count || clients
    monthlyRev = revRes.reduce((sum, s) => sum + parseFloat(s.actual_price || 0), 0)
  } catch {
    abonnes = clients
  }

  stats.value[0].value = abonnes.toLocaleString()
  stats.value[1].value = clients.toLocaleString()
  stats.value[2].value = monthlyRev ? (Math.round(monthlyRev).toLocaleString() + ' $') : '...'
  stats.value[3].value = tickets.toLocaleString()
  stats.value[4].value = todayDispatch.length.toLocaleString()

  openTickets.value = openTix
  todayJobs.value = todayDispatch
})
</script>
