/**
 * Portal receipts routes — invoice-receipt-document (wave R2d).
 *
 * GET /api/portal/receipts
 * GET /api/portal/receipts/:id/pdf
 */
import { Hono } from 'hono'
import { listReceipts, getReceiptWithLines } from '@zync/db/queries'
import type { AppEnv } from '../../types'
import {
  portalAuthMiddleware,
  requirePortalScope,
  type PortalAuthVariables,
} from '../../middleware/portalAuth'
import {
  fetchReceiptHtmlSnapshot,
  generateAndStoreReceiptSnapshot,
  loadReceiptRenderContext,
  resolveOriginatingInvoiceNumber,
} from '../../lib/receipt-snapshot'
import { renderReceiptHtml } from '../../receipts/render'

type PortalDataEnv = {
  Bindings: AppEnv['Bindings']
  Variables: PortalAuthVariables
}

export const portalReceiptsRoutes = new Hono<PortalDataEnv>()

portalReceiptsRoutes.use('*', portalAuthMiddleware)

portalReceiptsRoutes.get('/', async (c) => {
  const portal = c.get('portal')
  const db = c.get('db')

  const result = await listReceipts(db, portal.tenantId, {
    customer: portal.customerId,
    status: 'ISSUED',
    limit: 100,
  })

  const items = await Promise.all(
    result.items.map(async (receipt) => ({
      id: receipt.id,
      receiptNumber: receipt.receiptNumber,
      docType: receipt.docType,
      amount: receipt.amount,
      currency: receipt.currency,
      issuedAt: receipt.issuedAt,
      invoiceNumber: await resolveOriginatingInvoiceNumber(db, portal.tenantId, receipt),
    })),
  )

  return c.json({ items }, 200)
})

portalReceiptsRoutes.get('/:id/pdf', async (c) => {
  const portal = c.get('portal')
  const db = c.get('db')
  const receiptId = c.req.param('id')

  const receipt = await getReceiptWithLines(db, portal.tenantId, receiptId)
  if (!receipt) return c.json({ error: 'Not found' }, 404)

  const scopeErr = requirePortalScope(receipt.customerId, portal)
  if (scopeErr) return c.json({ error: 'Not found' }, 404)

  if (receipt.status !== 'ISSUED') {
    return c.json({ error: 'Not found' }, 404)
  }

  const htmlResponseHeaders = {
    'Content-Type': 'text/html; charset=utf-8',
    'Content-Security-Policy':
      "default-src 'none'; style-src 'unsafe-inline' https://fonts.googleapis.com; font-src https://fonts.gstatic.com; img-src 'self' data:",
    'X-Content-Type-Options': 'nosniff',
  } as const

  const r2 = c.env.INVOICE_SNAPSHOTS_BUCKET
  let snapshotKey = receipt.pdfR2Key

  if (snapshotKey) {
    const snapshotHtml = await fetchReceiptHtmlSnapshot(r2, snapshotKey)
    if (snapshotHtml) {
      return new Response(snapshotHtml, { status: 200, headers: htmlResponseHeaders })
    }
  }

  if (r2) {
    try {
      const snapshotted = await generateAndStoreReceiptSnapshot(
        { db, env: c.env },
        portal.tenantId,
        receiptId,
      )
      snapshotKey = snapshotted?.pdfR2Key ?? snapshotKey
      if (snapshotKey) {
        const snapshotHtml = await fetchReceiptHtmlSnapshot(r2, snapshotKey)
        if (snapshotHtml) {
          return new Response(snapshotHtml, { status: 200, headers: htmlResponseHeaders })
        }
      }
    } catch (backfillErr) {
      console.error('[portal/receipts/pdf] snapshot backfill failed:', backfillErr)
    }
  }

  const ctx = await loadReceiptRenderContext(db, c.env, portal.tenantId, receipt)
  const html = renderReceiptHtml(receipt, ctx)

  return new Response(html, {
    status: 200,
    headers: htmlResponseHeaders,
  })
})
