<template>
  <div>
    <div class="page-header">
      <h1>Toner Report</h1>
      <div class="header-actions">
        <button v-if="!loading && !error" class="btn btn-secondary" @click="exportCSV">Export CSV</button>
        <EmailReportButton v-if="!loading && !error" subject="Toner / Supply Report"
          :columns="emailColumns" :rows="emailRows" />
        <router-link to="/reports" class="btn btn-secondary">Back to Reports</router-link>
      </div>
    </div>

    <div v-if="loading" class="loading">Loading supply data...</div>

    <div v-else-if="error" class="card">
      <p class="text-danger">{{ error }}</p>
    </div>

    <template v-else>
      <!-- Summary Bar -->
      <div class="summary-bar">
        <div class="summary-stat card">
          <div class="stat-value">{{ summary.total_checked }}</div>
          <div class="stat-label">Printers Checked</div>
        </div>
        <div class="summary-stat card stat-low">
          <div class="stat-value">{{ summary.low }}</div>
          <div class="stat-label">Low Supply</div>
        </div>
        <div class="summary-stat card stat-critical">
          <div class="stat-value">{{ summary.critical }}</div>
          <div class="stat-label">Critical Supply</div>
        </div>
      </div>

      <!-- Filter Buttons -->
      <div class="filters">
        <button
          v-for="f in filterOptions"
          :key="f.value"
          class="btn"
          :class="filter === f.value ? 'btn-primary' : 'btn-secondary'"
          @click="filter = f.value"
        >
          {{ f.label }}
        </button>
      </div>

      <!-- Printers Table -->
      <div class="card">
        <div class="table-container">
          <table v-if="filteredPrinters.length">
            <thead>
              <tr>
                <th>Printer Name</th>
                <th>Hostname</th>
                <th>Supplies</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="printer in filteredPrinters" :key="printer.printerid">
                <td>
                  <!-- Coordinates give the name the same floor-plan preview the
                       printer's own page uses; it replaces the Location column. -->
                  <LocationMapTooltip
                    v-if="printer.mapx != null && printer.mapy != null"
                    :left="printer.mapx"
                    :top="printer.mapy"
                    :machineName="printer.printername || printer.assetnumber"
                  >
                    <router-link :to="`/printers/${printer.printerid}`">
                      {{ printer.printername || 'Unknown' }}
                    </router-link>
                  </LocationMapTooltip>
                  <router-link v-else :to="`/printers/${printer.printerid}`">
                    {{ printer.printername || 'Unknown' }}
                  </router-link>
                </td>
                <td>
                  <!-- Opens the printer's own web page. New tab: the report is a
                       worklist, and losing your place in it to visit one printer
                       means finding your row again. -->
                  <a
                    v-if="fqdnFor(printer)"
                    :href="`http://${fqdnFor(printer)}`"
                    target="_blank"
                    rel="noopener noreferrer"
                    :title="printer.ipaddress"
                  >{{ fqdnFor(printer) }}</a>
                  <span v-else>{{ printer.ipaddress || '-' }}</span>
                </td>
                <td class="supplies-cell">
                  <div
                    v-for="(supply, idx) in printer.supplies"
                    :key="idx"
                    class="supply-row"
                  >
                    <span class="supply-name">{{ supply.name }}</span>
                    <div class="supply-bar-track">
                      <div
                        class="supply-bar-fill"
                        :class="'supply-' + supply.status"
                        :style="{ width: Math.max(supply.level, 2) + '%' }"
                      ></div>
                    </div>
                    <span class="supply-level" :class="'supply-text-' + supply.status">
                      {{ supply.level }}%
                    </span>
                    <span class="supply-parts">
                      <span
                        v-for="part in supply.partnumbers"
                        :key="part.partnumber"
                        class="part-chip"
                        :title="partTooltip(part)"
                      >{{ part.partnumber }}</span>
                      <span v-if="!supply.partnumbers || !supply.partnumbers.length"
                            class="part-none" title="No part number on file for this model and color">-</span>
                    </span>
                  </div>
                </td>
              </tr>
            </tbody>
          </table>
          <p v-else class="empty-state">No printers match the selected filter.</p>
        </div>
      </div>
    </template>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { printersApi } from '@/api'
import EmailReportButton from '@/components/EmailReportButton.vue'
import LocationMapTooltip from '@/components/LocationMapTooltip.vue'
import { getPrinterHostnameTemplate } from '@/utils/siteSettings'

const emailColumns = [
  { key: 'printer', label: 'Printer' },
  { key: 'hostname', label: 'Hostname' },
  { key: 'supply', label: 'Supply' },
  { key: 'partnumber', label: 'Part Number' },
  { key: 'level', label: 'Level' },
  { key: 'status', label: 'Status' },
]

const loading = ref(true)
const error = ref(null)
const printers = ref([])
const summary = ref({ total_checked: 0, low: 0, critical: 0 })
const filter = ref('all')

const filterOptions = [
  { label: 'All', value: 'all' },
  { label: 'Critical', value: 'critical' },
  { label: 'Low', value: 'low' }
]

// Printers have no stored FQDN; the site builds one from the IP via the
// printer_hostname_template setting, the same way PrinterForm does.
const hostnameTemplate = ref('')

function fqdnFor(printer) {
  if (!printer.ipaddress || !hostnameTemplate.value) return ''
  return hostnameTemplate.value.replace('{ip}', printer.ipaddress.replace(/\./g, '-'))
}

// A model can list several capacity tiers for one color, so the chip shows the
// part number and the tooltip says which one it is.
function partTooltip(part) {
  const bits = [part.marketingname, part.capacitytier]
  if (part.pageyield) bits.push(part.pageyield + ' pages')
  return bits.filter(Boolean).join(' - ')
}

// One flat row per part number so an ordering list is copy-pasteable; supplies
// with no part on file still get a row.
function reportRows() {
  const rows = []
  for (const printer of filteredPrinters.value) {
    for (const supply of printer.supplies || []) {
      const parts = supply.partnumbers && supply.partnumbers.length
        ? supply.partnumbers.map(p => p.partnumber)
        : ['']
      for (const partnumber of parts) {
        rows.push({
          printer: printer.printername || '',
          hostname: fqdnFor(printer) || printer.ipaddress || '',
          supply: supply.name || '',
          partnumber: partnumber,
          level: supply.level,
          status: supply.status || '',
        })
      }
    }
  }
  return rows
}

const filteredPrinters = computed(() => {
  if (filter.value === 'all') return printers.value
  return printers.value.filter(p =>
    p.supplies.some(s => s.status === filter.value)
  )
})

// Emailed table, honoring the active filter.
const emailRows = computed(() =>
  reportRows().map(row => ({ ...row, level: row.level + '%' }))
)

function exportCSV() {
  const quote = value => `"${String(value ?? '').replace(/"/g, '""')}"`
  const header = ['printer', 'hostname', 'supply', 'partnumber', 'level', 'status']
  const rows = [header]
  for (const row of reportRows()) {
    rows.push(header.map(key => row[key]))
  }
  const csv = rows.map(row => row.map(quote).join(',')).join('\n')
  const link = document.createElement('a')
  link.href = URL.createObjectURL(new Blob([csv], { type: 'text/csv' }))
  link.download = 'toner_report.csv'
  link.click()
  URL.revokeObjectURL(link.href)
}

onMounted(async () => {
  try {
    hostnameTemplate.value = await getPrinterHostnameTemplate()
    const response = await printersApi.lowSupplies()
    const data = response.data.data
    printers.value = data.printers || []
    summary.value = data.summary || { total_checked: 0, low: 0, critical: 0 }
  } catch (err) {
    console.error('Error loading toner report:', err)
    error.value = 'Failed to load supply data. Zabbix may not be configured or reachable.'
  } finally {
    loading.value = false
  }
})
</script>

<style scoped>
.summary-bar {
  display: flex;
  gap: 1.5rem;
  margin-bottom: 1.5rem;
}

.summary-stat {
  flex: 1;
  text-align: center;
  padding: 1.25rem;
}

.stat-value {
  font-size: 2rem;
  font-weight: 700;
  color: var(--text);
}

.stat-label {
  color: var(--text-light);
  margin-top: 0.25rem;
}

.stat-low .stat-value {
  color: var(--warning);
}

.stat-critical .stat-value {
  color: var(--danger);
}

/* One grid for the whole cell, with each supply row contributing its cells
   directly (display: contents). Cartridge names were being ellipsised inside a
   fixed 120px column, which hid the very thing being reordered; a max-content
   column sizes to the longest name instead, and the columns still line up
   across the rows of one printer. */
.supplies-cell {
  min-width: 460px;
  display: grid;
  grid-template-columns: max-content minmax(80px, 1fr) auto max-content;
  column-gap: 0.5rem;
  row-gap: 0.35rem;
  align-items: center;
}

.supply-row {
  display: contents;
}

.supply-name {
  font-size: 0.85rem;
  color: var(--text-light);
  white-space: nowrap;
}

.supply-bar-track {
  height: 8px;
  background: var(--border);
  border-radius: 4px;
  overflow: hidden;
}

.supply-bar-fill {
  height: 100%;
  border-radius: 4px;
  transition: width 0.3s ease;
}

.supply-ok {
  background: var(--success);
}

.supply-low {
  background: var(--warning);
}

.supply-critical {
  background: var(--danger);
}

.supply-level {
  min-width: 40px;
  text-align: right;
  font-size: 0.85rem;
  font-weight: 600;
}

.supply-parts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}

.part-chip {
  font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
  font-size: 0.75rem;
  padding: 0.05rem 0.35rem;
  border: 1px solid var(--border);
  border-radius: 3px;
  color: var(--text);
  white-space: nowrap;
}

.part-none {
  font-size: 0.85rem;
  color: var(--text-light);
}

.supply-text-ok {
  color: var(--success);
}

.supply-text-low {
  color: var(--warning);
}

.supply-text-critical {
  color: var(--danger);
}

.empty-state {
  text-align: center;
  padding: 2rem;
  color: var(--text-light);
}

.text-danger {
  color: var(--danger);
}

.header-actions {
  display: flex;
  gap: 0.5rem;
}
</style>
