/**
 * reports-tax.ts — Israeli tax compliance report routes.
 * Spec: 2026-06-01-israeli-tax-reports (wave-14)
 *
 * Mounted at /api/reports in the reports router.
 *
 * Routes:
 *   GET /vat             ?from&to   reports:read   → Pcn874Report JSON
 *   GET /vat/csv         ?from&to   reports:export → CP1255 CSV (windows-1255)
 *   GET /annual-summary  ?year      reports:read   → AnnualIncomeSummary JSON
 *   GET /annual-summary/xlsx ?year  reports:export → xlsx
 *   GET /advance-tax     ?year      reports:read   → AdvanceTaxEstimate JSON
 */
import { Hono } from 'hono'
import { z } from 'zod'
import {
  createDb,
  getTenantById,
  getPcn874Report,
  getAnnualIncomeSummary,
  getAnnualSummaryDetail,
  getAdvanceTaxEstimate,
} from '@zync/db/queries'
import type { AppEnv } from '../types'
import { authMiddleware } from '../middleware/auth'
import { requirePermission } from '../middleware/guards'
import { buildPcn874Csv } from '../lib/pcn874-csv'
import { buildAnnualSummaryXlsx } from '../lib/annual-summary-xlsx'

// ── Zod schemas ───────────────────────────────────────────────────────────────

const vatPeriodSchema = z.object({
  from: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, 'from must be YYYY-MM-DD'),
  to: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, 'to must be YYYY-MM-DD'),
})

const yearSchema = z.object({
  year: z
    .string()
    .regex(/^\d{4}$/, 'year must be a 4-digit integer')
    .transform((s) => parseInt(s, 10)),
})

// ── Router ────────────────────────────────────────────────────────────────────

export const taxReportRoutes = new Hono<AppEnv>()

taxReportRoutes.use('*', authMiddleware)

// ── GET /vat — PCN874 report JSON ─────────────────────────────────────────────

taxReportRoutes.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 raw = Object.fromEntries(url.searchParams.entries())
  const parsed = vatPeriodSchema.safeParse(raw)
  if (!parsed.success) {
    return c.json({ error: 'Invalid query', issues: parsed.error.issues }, 400)
  }

  const db = createDb(c.env)
  const report = await getPcn874Report(db, session.tid, parsed.data.from, parsed.data.to)
  return c.json(report, 200)
})

// ── GET /vat/csv — PCN874 CP1255 CSV download ─────────────────────────────────

taxReportRoutes.get('/vat/csv', 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 = vatPeriodSchema.safeParse(raw)
  if (!parsed.success) {
    return c.json({ error: 'Invalid query', issues: parsed.error.issues }, 400)
  }

  const db = createDb(c.env)
  const report = await getPcn874Report(db, session.tid, parsed.data.from, parsed.data.to)

  const tenant = await getTenantById(db, session.tid)
  if (!tenant) {
    return c.json({ error: 'Tenant not found' }, 404)
  }
  const settings = (tenant.settings as Record<string, unknown>) ?? {}
  const businessTaxId = String(settings['vat_number'] ?? settings['business_primary_id'] ?? '')

  const bytes = buildPcn874Csv(report, { businessTaxId })

  const filename = `pcn874-${parsed.data.from}-${parsed.data.to}.csv`
  return new Response(bytes, {
    status: 200,
    headers: {
      'Content-Type': 'text/csv; charset=windows-1255',
      'Content-Disposition': `attachment; filename="${filename}"`,
      'Content-Length': String(bytes.byteLength),
      'X-Content-Type-Options': 'nosniff',
    },
  })
})

// ── GET /annual-summary — Annual income summary JSON ─────────────────────────

taxReportRoutes.get('/annual-summary', 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 = yearSchema.safeParse(raw)
  if (!parsed.success) {
    return c.json({ error: 'Invalid query', issues: parsed.error.issues }, 400)
  }

  const db = createDb(c.env)
  const summary = await getAnnualIncomeSummary(db, session.tid, parsed.data.year)
  return c.json(summary, 200)
})

// ── GET /annual-summary/xlsx — Annual income summary xlsx export ──────────────

taxReportRoutes.get('/annual-summary/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 = yearSchema.safeParse(raw)
  if (!parsed.success) {
    return c.json({ error: 'Invalid query', issues: parsed.error.issues }, 400)
  }

  const db = createDb(c.env)
  const [summary, supporting] = await Promise.all([
    getAnnualIncomeSummary(db, session.tid, parsed.data.year),
    getAnnualSummaryDetail(db, session.tid, parsed.data.year),
  ])
  const bytes = await buildAnnualSummaryXlsx(summary, supporting)

  const filename = `annual-summary-${parsed.data.year}.xlsx`
  return new Response(bytes, {
    status: 200,
    headers: {
      'Content-Type':
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      'Content-Disposition': `attachment; filename="${filename}"`,
      'Content-Length': String(bytes.byteLength),
      'X-Content-Type-Options': 'nosniff',
    },
  })
})

// ── GET /advance-tax — Advance tax estimate JSON ─────────────────────────────

taxReportRoutes.get('/advance-tax', 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 = yearSchema.safeParse(raw)
  if (!parsed.success) {
    return c.json({ error: 'Invalid query', issues: parsed.error.issues }, 400)
  }

  const db = createDb(c.env)
  const estimate = await getAdvanceTaxEstimate(db, session.tid, parsed.data.year)
  return c.json(estimate, 200)
})
