import { requireAuth, hasCap } from '../auth.js'
import { pool } from '../db.js'
import { registry } from '../reports/index.js'
import * as newbook from '../lib/newbook.js'
import * as resos from '../lib/resos.js'
import * as sambapos from '../lib/sambapos.js'

const PUBLIC_META = registry.map(r => ({
  id:            r.id,
  name:          r.name,
  category:      r.category,
  categoryLabel: r.categoryLabel,
  subcategory:   r.subcategory ?? null,
  description:   r.description,
}))

export async function reportRoutes(fastify) {
  fastify.addHook('preHandler', requireAuth)

  fastify.get('/api/reports', async () => PUBLIC_META)

  fastify.post('/api/reports/:id/run', async (request, reply) => {
    if (!hasCap(request, 'view')) {
      return reply.status(403).send({ error: 'Missing capability: view' })
    }

    const { id } = request.params
    const { dateFrom, dateTo } = request.body ?? {}

    const report = registry.find(r => r.id === id)
    if (!report) return reply.status(404).send({ error: 'Report not found' })

    const ctx = { db: pool, newbook, resos, sambapos, env: process.env }
    const start = Date.now()

    try {
      const result = await report.run({ dateFrom, dateTo }, ctx)
      const duration = Date.now() - start

      pool.query(
        `INSERT INTO report_runs (report_id, report_name, user_email, date_from, date_to, row_count, duration_ms)
         VALUES ($1, $2, $3, $4, $5, $6, $7)`,
        [report.id, report.name, request.user.email, dateFrom ?? null, dateTo ?? null, result.rows.length, duration]
      ).catch(() => {})

      return result
    } catch (err) {
      const duration = Date.now() - start
      request.log.error(err)

      pool.query(
        `INSERT INTO report_runs (report_id, report_name, user_email, date_from, date_to, error, duration_ms)
         VALUES ($1, $2, $3, $4, $5, $6, $7)`,
        [report.id, report.name, request.user.email, dateFrom ?? null, dateTo ?? null, err.message, duration]
      ).catch(() => {})

      return reply.status(500).send({ error: err.message || 'Report failed' })
    }
  })
}
