<template>
  <q-page padding>
    <div class="row items-center q-mb-md">
      <q-btn flat dense icon="arrow_back" to="/rapports" class="q-mr-sm" />
      <div class="text-h6 text-weight-bold">Revenus par compte</div>
      <q-space />
      <q-btn flat dense icon="download" label="CSV" @click="downloadCSV" :disable="!data.accounts?.length" />
    </div>

    <!-- Filters — empilent sur téléphone (col-12/col-6), en ligne sur ordinateur (col-sm-auto) -->
    <div class="row q-col-gutter-sm q-mb-md items-end">
      <div class="col-6 col-sm-auto">
        <q-input v-model="startDate" type="date" label="Début" dense outlined style="width:160px;max-width:100%" />
      </div>
      <div class="col-6 col-sm-auto">
        <q-input v-model="endDate" type="date" label="Fin" dense outlined style="width:160px;max-width:100%" />
      </div>
      <div class="col-12 col-sm-auto">
        <q-btn-toggle
          v-model="mode"
          dense no-caps unelevated spread
          toggle-color="primary"
          :options="[{ label: 'Comptes GL', value: 'gl' }, { label: 'Groupes articles', value: 'items' }]"
        />
      </div>
      <div class="col-12 col-sm-auto">
        <q-btn color="primary" label="Générer" icon="play_arrow" class="full-width" @click="loadReport" :loading="loading" />
      </div>
    </div>

    <!-- Account selector -->
    <div v-if="allAccounts.length" class="q-mb-md">
      <q-select
        v-model="selectedAccounts"
        :options="accountOptions"
        label="Comptes à afficher (vide = tous)"
        multiple
        use-chips
        dense outlined
        emit-value map-options
        option-value="value"
        option-label="label"
        clearable
        style="max-width:800px"
      >
        <template #option="{ opt, selected, toggleOption }">
          <q-item clickable @click="toggleOption(opt)" :active="selected" dense>
            <q-item-section side>
              <q-checkbox :model-value="selected" @update:model-value="toggleOption(opt)" dense />
            </q-item-section>
            <q-item-section>
              <q-item-label>{{ opt.label }}</q-item-label>
            </q-item-section>
          </q-item>
        </template>
        <template #after>
          <q-btn flat dense icon="refresh" @click="loadReport" :loading="loading" />
        </template>
      </q-select>
    </div>

    <!-- Chart -->
    <div v-if="chartAccounts.length" class="ops-card q-mb-md" style="height:400px;position:relative">
      <canvas ref="chartCanvas"></canvas>
    </div>

    <!-- Summary cards -->
    <div v-if="data.accounts?.length" class="row q-col-gutter-sm q-mb-md">
      <div class="col-6 col-sm-auto"><StatCard label="Revenu total" :value="formatMoney(grandTotal)" value-class="text-positive" /></div>
      <div class="col-6 col-sm-auto"><StatCard label="Comptes actifs" :value="data.accounts.length" /></div>
      <div class="col-6 col-sm-auto"><StatCard label="Mois" :value="data.months?.length || 0" /></div>
      <div class="col-6 col-sm-auto"><StatCard label="Mode" :value="data.mode === 'items' ? 'Articles' : 'GL'" /></div>
    </div>

    <!-- Data table -->
    <DataTable
      v-if="data.accounts?.length"
      :rows="tableRows"
      :columns="tableColumns"
      row-key="name"
      class="ops-table"
      :pagination="{ rowsPerPage: 50 }"
      dense
    >
      <template #body-cell-total="props">
        <q-td :props="props">
          <span class="text-weight-bold">{{ formatMoney(props.value) }}</span>
        </q-td>
      </template>
    </DataTable>

    <!-- Empty state -->
    <div v-if="!loading && !data.accounts?.length" class="text-center text-grey-5 q-pa-xl">
      <q-icon name="trending_up" size="64px" class="q-mb-md" />
      <div>Sélectionnez une période et cliquez <b>Générer</b></div>
    </div>
  </q-page>
</template>

<script setup>
import { ref, computed, nextTick } from 'vue'
import { Notify } from 'quasar'
import { fetchRevenueReport } from 'src/api/reports'
import { formatMoney } from 'src/composables/useFormatters'
import StatCard from 'src/components/shared/StatCard.vue'
import DataTable from 'src/components/shared/DataTable.vue'
let Chart = null // chart.js ~90 KB → chargé à la demande au 1er rendu de graphique (hors du chunk de la page)

const now = new Date()
const startDate = ref(new Date(now.getFullYear(), 0, 1).toISOString().slice(0, 10))
const endDate = ref(now.toISOString().slice(0, 10))
const mode = ref('gl')
const loading = ref(false)
const data = ref({})
const chartCanvas = ref(null)
let chartInstance = null

const selectedAccounts = ref([])
const allAccounts = ref([])

const accountOptions = computed(() =>
  allAccounts.value.map(a => ({
    label: a.number ? `${a.number} — ${a.label}` : a.label,
    value: a.name,
  }))
)

const FR_SHORT = ['Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Jun', 'Jul', 'Aoû', 'Sep', 'Oct', 'Nov', 'Déc']

const grandTotal = computed(() => {
  if (!data.value.accounts) return 0
  return data.value.accounts.reduce((s, a) => s + a.total, 0)
})

// Accounts shown in chart — selected or all if none selected
const chartAccounts = computed(() => {
  if (!data.value.accounts?.length) return []
  if (!selectedAccounts.value?.length) return data.value.accounts
  return data.value.accounts.filter(a =>
    selectedAccounts.value.includes(a.name)
  )
})

const tableColumns = computed(() => {
  const cols = [
    { name: 'number', label: '#', field: 'number', align: 'left', sortable: true, style: 'width:60px' },
    { name: 'label', label: 'Compte', field: 'label', align: 'left', sortable: true },
  ]
  for (const m of (data.value.months || [])) {
    const [y, mo] = m.split('-')
    cols.push({
      name: m,
      label: FR_SHORT[parseInt(mo) - 1] + ' ' + y,
      field: m,
      align: 'right',
      sortable: true,
      format: v => v ? formatMoney(v) : '—',
    })
  }
  cols.push({ name: 'total', label: 'Total', field: 'total', align: 'right', sortable: true, format: v => v ? formatMoney(v) : '—' })
  return cols
})

const tableRows = computed(() => {
  if (!data.value.accounts) return []
  return data.value.accounts.map(a => {
    const row = { name: a.name, number: a.number, label: a.label, total: a.total }
    for (let i = 0; i < (data.value.months || []).length; i++) {
      row[data.value.months[i]] = a.monthly[i] || 0
    }
    return row
  })
})

async function loadReport () {
  loading.value = true
  try {
    const filter = selectedAccounts.value?.length ? selectedAccounts.value.join(',') : ''
    data.value = await fetchRevenueReport(startDate.value, endDate.value, { mode: mode.value, filter })
    // Populate account selector from API response
    if (data.value.all_accounts?.length) {
      allAccounts.value = data.value.all_accounts
    }
    await nextTick()
    renderChart()
  } catch (e) {
    console.error('Revenue report error:', e)
    Notify.create({ type: 'negative', message: 'Échec du chargement du rapport — réessayez.' })
  } finally {
    loading.value = false
  }
}

const CHART_COLORS = [
  '#6366f1', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6',
  '#06b6d4', '#f97316', '#ec4899', '#14b8a6', '#84cc16',
  '#a855f7', '#3b82f6', '#d946ef', '#0ea5e9', '#f43f5e',
]

async function renderChart () {
  if (chartInstance) chartInstance.destroy()
  if (!chartCanvas.value || !chartAccounts.value.length) return
  if (!Chart) Chart = (await import('chart.js/auto')).default

  const months = data.value.months || []
  const labels = months.map(m => {
    const [y, mo] = m.split('-')
    return FR_SHORT[parseInt(mo) - 1] + ' ' + y.slice(2)
  })

  // Group small accounts into "Autres" if more than 8 shown
  let accts = [...chartAccounts.value]
  let datasets

  if (accts.length > 8) {
    const top = accts.slice(0, 7)
    const others = accts.slice(7)
    const othersMonthly = months.map((_, mi) =>
      others.reduce((s, a) => s + (a.monthly[mi] || 0), 0)
    )
    datasets = [
      ...top.map((a, i) => makeDataset(a, i)),
      {
        label: 'Autres',
        data: othersMonthly,
        backgroundColor: 'rgba(156,163,175,0.4)',
        borderColor: '#9ca3af',
        borderWidth: 2,
        fill: true,
        tension: 0.3,
        pointRadius: 0,
        pointHitRadius: 10,
      },
    ]
  } else {
    datasets = accts.map((a, i) => makeDataset(a, i))
  }

  chartInstance = new Chart(chartCanvas.value, {
    type: 'line',
    data: { labels, datasets },
    options: {
      responsive: true,
      maintainAspectRatio: false,
      interaction: { mode: 'index', intersect: false },
      plugins: {
        legend: { position: 'bottom', labels: { boxWidth: 12, font: { size: 11 } } },
        tooltip: {
          callbacks: {
            label: ctx => ctx.dataset.label + ': ' + formatMoney(ctx.parsed.y),
            footer: items => 'Total: ' + formatMoney(items.reduce((s, i) => s + i.parsed.y, 0)),
          },
        },
      },
      scales: {
        x: { grid: { display: false } },
        y: {
          stacked: true,
          ticks: { callback: v => (v / 1000).toFixed(0) + 'k$' },
          grid: { color: 'rgba(0,0,0,0.06)' },
        },
      },
    },
  })
}

function makeDataset (account, index) {
  const color = CHART_COLORS[index % CHART_COLORS.length]
  return {
    label: account.number ? `${account.number} ${account.label}` : account.label,
    data: account.monthly,
    backgroundColor: color + '55',
    borderColor: color,
    borderWidth: 2,
    fill: true,
    tension: 0.3,
    pointRadius: 0,
    pointHitRadius: 10,
  }
}

function downloadCSV () {
  if (!data.value.accounts?.length) return
  const months = data.value.months || []
  const header = ['#Compte', 'Nom', ...months, 'Total']
  const rows = data.value.accounts.map(a =>
    [a.number, a.label, ...a.monthly.map(v => v.toFixed(2)), a.total.toFixed(2)]
  )
  const totals = months.map((_, i) =>
    data.value.accounts.reduce((s, a) => s + (a.monthly[i] || 0), 0).toFixed(2)
  )
  rows.push(['', 'TOTAL', ...totals, grandTotal.value.toFixed(2)])

  const csv = [header, ...rows].map(r => r.join(',')).join('\n')
  const blob = new Blob(['\uFEFF' + csv], { type: 'text/csv;charset=utf-8' })
  const a = document.createElement('a')
  a.href = URL.createObjectURL(blob)
  a.download = `revenus_${startDate.value}_${endDate.value}.csv`
  a.click()
}
</script>
