/**
 * Invoice PDF template settings routes — invoice-pdf-customization (wave-11).
 * Mounted at /api/settings/invoicing/pdf-template.
 *
 * GET   / → current PDF template settings
 * PATCH / → update PDF template settings
 * GET   /preview → sample invoice PDF preview
 */
import { Hono } from 'hono'
import type { AppEnv } from '../../types'
import { authMiddleware } from '../../middleware/auth'
import { requirePermission } from '../../middleware/guards'
import {
  createDb,
  getInvoicePdfTemplate,
  updateInvoicePdfTemplate,
  invoicePdfTemplateSchema,
  type InvoicePdfTemplate,
} from '@zync/db/queries'
import { renderInvoicePdfPreview } from '../../invoices/pdf-preview'

export const pdfTemplateSettingsRoute = new Hono<AppEnv>()
const HTML_TO_PDF_URL = 'https://api.html-to-pdf.zync.is'

pdfTemplateSettingsRoute.use('*', authMiddleware)

// GET /api/settings/invoicing/pdf-template
pdfTemplateSettingsRoute.get('/', requirePermission('settings:read'), async (c) => {
  const session = c.get('session')
  if (!session || session.type !== 'user' || !session.tid) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  const db = createDb(c.env)
  const template = await getInvoicePdfTemplate(db, session.tid)
  return c.json(template, 200)
})

// PATCH /api/settings/invoicing/pdf-template
pdfTemplateSettingsRoute.patch('/', requirePermission('settings:write'), async (c) => {
  const session = c.get('session')
  if (!session || session.type !== 'user' || !session.tid) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  const body = await c.req.json().catch(() => null)
  const parsed = invoicePdfTemplateSchema.safeParse(body)
  if (!parsed.success) {
    return c.json({ error: 'Validation failed', issues: parsed.error.issues }, 400)
  }

  const db = createDb(c.env)
  const updated = await updateInvoicePdfTemplate(db, session.tid, parsed.data)
  return c.json(updated, 200)
})

// GET /api/settings/invoicing/pdf-template/preview
pdfTemplateSettingsRoute.get('/preview', requirePermission('settings:read'), async (c) => {
  const session = c.get('session')
  if (!session || session.type !== 'user' || !session.tid) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  const parsed = invoicePdfTemplateSchema.safeParse({
    layout: c.req.query('layout') || undefined,
    showProject: parseBooleanQuery(c.req.query('showProject')),
    showSku: parseBooleanQuery(c.req.query('showSku')),
    dateFormat: c.req.query('dateFormat') || undefined,
    accentHex: c.req.query('accentHex') || undefined,
  })
  if (!parsed.success) {
    return c.json({ error: 'Validation failed', issues: parsed.error.issues }, 400)
  }

  const db = createDb(c.env)
  const template = await getInvoicePdfTemplate(db, session.tid)
  const effectiveTemplate = mergePreviewTemplate(template, parsed.data)
  const html = renderInvoicePdfPreview(effectiveTemplate)

  const pdfRes = await fetch(HTML_TO_PDF_URL, {
    method: 'POST',
    headers: { 'Content-Type': 'text/html; charset=utf-8' },
    body: html,
  })
  if (!pdfRes.ok) {
    return c.json({ error: 'PDF generation failed' }, 502)
  }

  const pdfBytes = await pdfRes.arrayBuffer()
  return new Response(pdfBytes, {
    status: 200,
    headers: {
      'Content-Type': 'application/pdf',
      'Content-Disposition': 'inline; filename="sample-invoice.pdf"',
      'Cache-Control': 'no-store',
    },
  })
})

function parseBooleanQuery(value: string | undefined): boolean | undefined {
  if (value === undefined) return undefined
  if (value === 'true') return true
  if (value === 'false') return false
  return undefined
}

function mergePreviewTemplate(
  stored: InvoicePdfTemplate,
  patch: Partial<InvoicePdfTemplate>,
): InvoicePdfTemplate {
  return {
    layout: patch.layout ?? stored.layout,
    showProject: patch.showProject ?? stored.showProject,
    showSku: patch.showSku ?? stored.showSku,
    dateFormat: patch.dateFormat ?? stored.dateFormat,
    accentHex: patch.accentHex === undefined ? stored.accentHex : patch.accentHex,
  }
}
