<template>
  <div class="page-header">
    <h1>Reports</h1>
  </div>

  <!-- Card grid hides while a report is open so results sit at the top. -->
  <template v-if="!currentReport">
    <div class="filters">
      <input
        v-model="search"
        type="text"
        class="form-control"
        placeholder="Search reports..."
      />
    </div>

    <!-- All report cards, grouped by category. Cards come from GET /api/reports,
         which merges core reports with plugin-contributed cards (get_reports). -->
    <div v-for="group in groupedReports" :key="group.category" class="report-group">
      <h2 class="group-title">{{ titleCase(group.category) }}</h2>
      <div class="reports-grid">
        <div
          v-for="report in group.reports"
          :key="report.id"
          class="report-card card"
          @click="openReport(report)"
        >
          <h3>{{ report.name }}</h3>
          <p>{{ report.description }}</p>
          <span class="badge">{{ report.category }}</span>
        </div>
      </div>
    </div>

    <div v-if="!groupedReports.length" class="empty-state">
      No reports match your search.
    </div>
  </template>

  <!-- Inline report results (endpoint-backed reports) -->
  <div v-if="currentReport" class="report-results card">
    <div class="report-header">
      <h2>{{ currentReport.name }}</h2>
      <div class="report-actions">
        <button class="btn btn-secondary" @click="exportCSV">Export CSV</button>
        <button class="btn btn-secondary" @click="clearReport">Back to Reports</button>
      </div>
    </div>

    <!-- Server-side filters this report accepts (see reportFilterFields) -->
    <div v-if="activeFilterFields.length" class="filters">
      <select
        v-if="activeFilterFields.includes('businessunit')"
        v-model="filterState.businessunitid"
        class="form-control"
        @change="refreshReport"
      >
        <option value="">All business units</option>
        <option v-for="bu in filterOptions.businessunits" :key="bu.businessunitid" :value="bu.businessunitid">
          {{ bu.businessunit }}
        </option>
      </select>
      <select
        v-if="activeFilterFields.includes('assettype')"
        v-model="filterState.assettypeid"
        class="form-control"
        @change="refreshReport"
      >
        <option value="">All asset types</option>
        <option v-for="at in filterOptions.assettypes" :key="at.assettypeid" :value="at.assettypeid">
          {{ titleCase(at.assettype) }}
        </option>
      </select>
      <select
        v-if="activeFilterFields.includes('location')"
        v-model="filterState.locationid"
        class="form-control"
        @change="refreshReport"
      >
        <option value="">All locations</option>
        <option v-for="loc in filterOptions.locations" :key="loc.locationid" :value="loc.locationid">
          {{ loc.locationname }}
        </option>
      </select>
      <select
        v-if="activeFilterFields.includes('application')"
        v-model="filterState.appid"
        class="form-control"
        @change="refreshReport"
      >
        <option value="">All required applications</option>
        <option v-for="app in filterOptions.applications" :key="app.appid" :value="app.appid">
          {{ app.appname }}
        </option>
      </select>
      <input
        v-if="activeFilterFields.includes('limit')"
        v-model.number="filterState.limit"
        type="number"
        min="1"
        max="100"
        class="form-control limit-input"
        placeholder="Limit (20)"
        @change="refreshReport"
      />
    </div>

    <div v-if="loading" class="loading">Loading report...</div>
    <div v-else-if="reportData">
      <!-- Machines by Type -->
      <div v-if="currentReport.id === 'machines-by-type'" class="report-content">
        <p class="report-summary">Total: {{ reportData.total }}</p>
        <table>
          <thead>
            <tr>
              <th>Machine Type</th>
              <th>Description</th>
              <th>Count</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="item in reportData.data" :key="item.machinetype">
              <td>{{ item.machinetype }}</td>
              <td>{{ item.description }}</td>
              <td>{{ item.count }}</td>
            </tr>
          </tbody>
        </table>
      </div>

      <!-- Assets by Status -->
      <div v-else-if="currentReport.id === 'assets-by-status'" class="report-content">
        <p class="report-summary">Total: {{ reportData.total }}</p>
        <table>
          <thead>
            <tr>
              <th>Status</th>
              <th>Count</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="item in reportData.data" :key="item.status">
              <td>
                <span class="badge" :style="{ backgroundColor: item.color }">{{ item.status }}</span>
              </td>
              <td>{{ item.count }}</td>
            </tr>
          </tbody>
        </table>
      </div>

      <!-- KB Popularity -->
      <div v-else-if="currentReport.id === 'kb-popularity'" class="report-content">
        <table>
          <thead>
            <tr>
              <th>Article</th>
              <th>Application</th>
              <th>Clicks</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="item in reportData.data" :key="item.linkid">
              <td>
                <a v-if="item.linkurl" :href="item.linkurl" target="_blank">{{ item.shortdescription }}</a>
                <span v-else>{{ item.shortdescription }}</span>
              </td>
              <td>{{ item.application || '-' }}</td>
              <td>{{ item.clicks }}</td>
            </tr>
          </tbody>
        </table>
      </div>

      <!-- Asset Inventory -->
      <div v-else-if="currentReport.id === 'asset-inventory'" class="report-content">
        <p class="report-summary">Total Assets: {{ reportData.total }}</p>

        <h3>By Type</h3>
        <table>
          <thead><tr><th>Type</th><th>Count</th></tr></thead>
          <tbody>
            <tr v-for="item in reportData.data.bytype" :key="item.type">
              <td>{{ item.type }}</td><td>{{ item.count }}</td>
            </tr>
          </tbody>
        </table>

        <h3>By Status</h3>
        <table>
          <thead><tr><th>Status</th><th>Count</th></tr></thead>
          <tbody>
            <tr v-for="item in reportData.data.bystatus" :key="item.status">
              <td><span class="badge" :style="{ backgroundColor: item.color }">{{ item.status }}</span></td>
              <td>{{ item.count }}</td>
            </tr>
          </tbody>
        </table>

        <h3>By Location</h3>
        <table>
          <thead><tr><th>Location</th><th>Count</th></tr></thead>
          <tbody>
            <tr v-for="item in reportData.data.bylocation" :key="item.location">
              <td>{{ item.location }}</td><td>{{ item.count }}</td>
            </tr>
          </tbody>
        </table>
      </div>

      <!-- Generic fallback -->
      <div v-else class="report-content">
        <pre>{{ JSON.stringify(reportData, null, 2) }}</pre>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { reportsApi, businessunitsApi, assetsApi, locationsApi, applicationsApi } from '@/api'
import { withBase } from '@/utils/basePath'

const router = useRouter()
const route = useRoute()

const reports = ref([])
const search = ref('')
const currentReport = ref(null)
const reportData = ref(null)
const loading = ref(false)

// Preferred category order; anything else falls in after, sorted alphabetically.
const categoryOrder = ['inventory', 'compliance', 'usage']

// server-side filters each inline report accepts (query params on its endpoint)
const reportFilterFields = {
  'machines-by-type': ['businessunit'],
  'assets-by-status': ['assettype', 'businessunit'],
  'asset-inventory': ['businessunit', 'location'],
  'kb-popularity': ['limit'],
  'software-compliance': ['application']
}

const filterState = ref({ businessunitid: '', assettypeid: '', locationid: '', appid: '', limit: '' })
const filterOptions = ref({ businessunits: [], assettypes: [], locations: [], applications: [] })

const activeFilterFields = computed(() =>
  currentReport.value ? (reportFilterFields[currentReport.value.id] || []) : []
)

function resetFilters() {
  filterState.value = { businessunitid: '', assettypeid: '', locationid: '', appid: '', limit: '' }
}

// fetch dropdown options once, only for the fields the open report needs
async function loadFilterOptions(fields) {
  try {
    if (fields.includes('businessunit') && !filterOptions.value.businessunits.length) {
      const response = await businessunitsApi.list({ perpage: 100 })
      filterOptions.value.businessunits = response.data.data || []
    }
    if (fields.includes('assettype') && !filterOptions.value.assettypes.length) {
      const response = await assetsApi.types.list()
      filterOptions.value.assettypes = response.data.data || []
    }
    if (fields.includes('location') && !filterOptions.value.locations.length) {
      const response = await locationsApi.list({ perpage: 100 })
      filterOptions.value.locations = response.data.data || []
    }
    if (fields.includes('application') && !filterOptions.value.applications.length) {
      // listAll: 100 is the server-side cap, not a generous limit, and the
      // catalogue is past it - a report filtered by a late-alphabet
      // application could not be built.
      filterOptions.value.applications = await applicationsApi.listAll()
    }
  } catch (error) {
    console.error('Error loading filter options:', error)
  }
}

function filterParams() {
  const params = {}
  const state = filterState.value
  if (state.businessunitid) params.businessunitid = state.businessunitid
  if (state.assettypeid) params.assettypeid = state.assettypeid
  if (state.locationid) params.locationid = state.locationid
  if (state.appid) params.appid = state.appid
  if (state.limit) params.limit = state.limit
  return params
}

function refreshReport() {
  if (currentReport.value) runReport(currentReport.value)
}

onMounted(async () => {
  await loadReports()
  // Honor a deep link / refresh with ?report=<id> already in the URL.
  applyQuery(route.query.report)
})

async function loadReports() {
  try {
    const response = await reportsApi.list()
    reports.value = response.data.data.reports
  } catch (error) {
    console.error('Error loading reports:', error)
  }
}

function titleCase(text) {
  return String(text || '')
    .split(/[\s_-]+/)
    .map(word => word.charAt(0).toUpperCase() + word.slice(1))
    .join(' ')
}

// Filter by name/description/category, then group by category in the fixed order.
const groupedReports = computed(() => {
  const term = search.value.trim().toLowerCase()
  const matches = reports.value.filter(report => {
    if (!term) return true
    return (
      (report.name || '').toLowerCase().includes(term) ||
      (report.description || '').toLowerCase().includes(term) ||
      (report.category || '').toLowerCase().includes(term)
    )
  })

  const byCategory = {}
  for (const report of matches) {
    const category = report.category || 'other'
    if (!byCategory[category]) byCategory[category] = []
    byCategory[category].push(report)
  }

  const categories = Object.keys(byCategory).sort((a, b) => {
    const ai = categoryOrder.indexOf(a)
    const bi = categoryOrder.indexOf(b)
    if (ai !== -1 || bi !== -1) {
      return (ai === -1 ? Infinity : ai) - (bi === -1 ? Infinity : bi)
    }
    return a.localeCompare(b)
  })

  return categories.map(category => ({ category, reports: byCategory[category] }))
})

function openReport(report) {
  // Cards with a dedicated frontend page carry a route; navigate to it.
  if (report.route) {
    router.push(report.route)
    return
  }
  // PC Relationships has its own dedicated page.
  if (report.id === 'pc-relationships') {
    router.push('/reports/pc-relationships')
    return
  }
  // Inline reports live in the URL query so browser back/forward works:
  // back pops the query and returns to the card grid.
  router.push({ query: { report: report.id } })
}

// The query param is the source of truth for the open inline report.
watch(() => route.query.report, applyQuery)

function applyQuery(id) {
  if (!id) {
    currentReport.value = null
    reportData.value = null
    return
  }
  const report = reports.value.find(r => r.id === id)
  if (report) {
    resetFilters()
    loadFilterOptions(reportFilterFields[id] || [])
    runReport(report)
  }
}

async function runReport(report) {
  currentReport.value = report
  loading.value = true
  reportData.value = null
  window.scrollTo(0, 0)

  const params = filterParams()
  try {
    let response
    switch (report.id) {
      case 'machines-by-type':
        response = await reportsApi.machinesByType(params)
        break
      case 'assets-by-status':
        response = await reportsApi.assetsByStatus(params)
        break
      case 'kb-popularity':
        response = await reportsApi.kbPopularity(params)
        break
      case 'software-compliance':
        response = await reportsApi.softwareCompliance(params)
        break
      case 'asset-inventory':
        response = await reportsApi.assetInventory(params)
        break
      default:
        console.error('Unknown report:', report.id)
        return
    }
    reportData.value = response.data.data
  } catch (error) {
    console.error('Error running report:', error)
  } finally {
    loading.value = false
  }
}

function exportCSV() {
  if (!currentReport.value) return
  const params = new URLSearchParams({ format: 'csv', ...filterParams() })
  window.open(withBase(`/api/reports/${currentReport.value.id}?${params}`), '_blank')
}

function clearReport() {
  // Drop the query param; the watcher clears the panel state.
  router.push({ query: {} })
}
</script>

<style scoped>
.report-group {
  margin-bottom: 2rem;
}

.group-title {
  margin: 0 0 1rem;
  font-size: 1.25rem;
  color: var(--text);
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.5rem;
}

.reports-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 1.5rem;
}

.report-card {
  cursor: pointer;
  transition: transform 0.2s, box-shadow 0.2s;
}

.report-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.report-card h3 {
  margin-top: 0;
  margin-bottom: 0.5rem;
}

.report-card p {
  color: var(--text-light);
  margin-bottom: 1rem;
}

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

.report-results {
  margin-top: 0.5rem;
}

.report-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1.5rem;
}

.report-header h2 {
  margin: 0;
}

.report-actions {
  display: flex;
  gap: 0.5rem;
}

.report-summary {
  font-size: 1.1rem;
  font-weight: 500;
  margin-bottom: 1rem;
}

.report-content h3 {
  margin-top: 1.5rem;
  margin-bottom: 0.5rem;
}

.report-content table {
  width: 100%;
  margin-bottom: 1rem;
}

.limit-input {
  max-width: 140px;
}
</style>
