/**
 * Expense reports routes — expenses-module.
 * All routes require reports:read permission.
 *
 * GET /api/expenses/reports/expense       → expense reports UI payload
 * GET /api/expenses/reports/vat           → PCN874 VAT UI payload
 * GET /api/expenses/reports/vendors       → vendor analysis UI payload
 * GET /api/expenses/reports/expense/xlsx  → RTL Hebrew Excel download
 * GET /api/expenses/reports/vat/xlsx      → PCN874 Excel download
 */
import { Hono } from 'hono'
import { z } from 'zod'
import type { AppEnv } from '../../types'
import { authMiddleware } from '../../middleware/auth'
import { requireModuleEnabled } from '../../middleware/require-module-enabled'
import { requirePermission } from '../../middleware/guards'
import {
  expenseReport,
  vatSummaryPcn874,
  buildExpenseReportXlsx,
  buildVatXlsx,
} from '@zync/expenses'
import { expenseReportDetail, vatSummaryPcn874Ui, vendorAnalysisUi } from '@zync/db/queries'
import type { ExpenseCategoryId } from '@zync/types'

const reportFiltersSchema = z.object({
  from: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
  to: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
  category: z.string().optional(),
  projectId: z.string().uuid().optional(),
  userId: z.string().uuid().optional(),
})

export const expenseReportsRoute = new Hono<AppEnv>()

expenseReportsRoute.use('*', authMiddleware)
expenseReportsRoute.use('*', requireModuleEnabled('expenses'))

// ── GET /reports/expense ───────────────────────────────────────────────────────

expenseReportsRoute.get('/expense', requirePermission('reports:read'), async (c) => {
  const session = c.get('session')
  if (!session || session.type !== 'user' || !session.tid) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  const url = new URL(c.req.url)
  const raw = Object.fromEntries(url.searchParams.entries())
  const parsed = reportFiltersSchema.safeParse(raw)
  if (!parsed.success) {
    return c.json({ error: 'Invalid query', issues: parsed.error.issues }, 400)
  }

  const db = c.get('db')
  const report = await expenseReportDetail(db, session.tid, {
    ...parsed.data,
    category: parsed.data.category as ExpenseCategoryId | undefined,
  })
  return c.json(report, 200)
})

// ── GET /reports/expense/xlsx ──────────────────────────────────────────────────

expenseReportsRoute.get('/expense/xlsx', requirePermission('reports:export'), async (c) => {
  const session = c.get('session')
  if (!session || session.type !== 'user' || !session.tid) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  const url = new URL(c.req.url)
  const raw = Object.fromEntries(url.searchParams.entries())
  const parsed = reportFiltersSchema.safeParse(raw)
  if (!parsed.success) {
    return c.json({ error: 'Invalid query', issues: parsed.error.issues }, 400)
  }

  const db = c.get('db')
  const rows = await expenseReport(db, session.tid, {
    dateFrom: parsed.data.from,
    dateTo: parsed.data.to,
    category: parsed.data.category as ExpenseCategoryId | undefined,
  })
  const buffer = await buildExpenseReportXlsx(rows)

  const filename = `expense-report-${new Date().toISOString().slice(0, 10)}.xlsx`
  return new Response(buffer, {
    status: 200,
    headers: {
      'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      'Content-Disposition': `attachment; filename="${filename}"`,
    },
  })
})

// ── GET /reports/vat ───────────────────────────────────────────────────────────

expenseReportsRoute.get('/vat', requirePermission('reports:read'), async (c) => {
  const session = c.get('session')
  if (!session || session.type !== 'user' || !session.tid) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  const url = new URL(c.req.url)
  const parsed = reportFiltersSchema.safeParse(Object.fromEntries(url.searchParams.entries()))
  if (!parsed.success) {
    return c.json({ error: 'from and to (YYYY-MM-DD) are required for VAT report', issues: parsed.error.issues }, 400)
  }

  const db = c.get('db')
  const summary = await vatSummaryPcn874Ui(db, session.tid, parsed.data)
  return c.json(summary, 200)
})

// ── GET /reports/vat/xlsx ──────────────────────────────────────────────────────

expenseReportsRoute.get('/vat/xlsx', requirePermission('reports:export'), async (c) => {
  const session = c.get('session')
  if (!session || session.type !== 'user' || !session.tid) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  const url = new URL(c.req.url)
  const parsed = reportFiltersSchema.safeParse(Object.fromEntries(url.searchParams.entries()))
  if (!parsed.success) {
    return c.json({ error: 'from and to (YYYY-MM-DD) are required', issues: parsed.error.issues }, 400)
  }

  const db = c.get('db')
  const summary = await vatSummaryPcn874(db, session.tid, parsed.data)
  const buffer = await buildVatXlsx(summary)

  const filename = `pcn874-${parsed.data.from}-${parsed.data.to}.xlsx`
  return new Response(buffer, {
    status: 200,
    headers: {
      'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      'Content-Disposition': `attachment; filename="${filename}"`,
    },
  })
})

// ── GET /reports/vendors ───────────────────────────────────────────────────────

expenseReportsRoute.get('/vendors', requirePermission('reports:read'), async (c) => {
  const session = c.get('session')
  if (!session || session.type !== 'user' || !session.tid) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  const url = new URL(c.req.url)
  const parsed = reportFiltersSchema.safeParse(Object.fromEntries(url.searchParams.entries()))
  if (!parsed.success) {
    return c.json({ error: 'from and to (YYYY-MM-DD) are required for vendor analysis', issues: parsed.error.issues }, 400)
  }

  const db = c.get('db')
  const rows = await vendorAnalysisUi(db, session.tid, {
    ...parsed.data,
    category: parsed.data.category as ExpenseCategoryId | undefined,
  })
  return c.json(rows, 200)
})
