/**
 * Payout ledger routes — contractor-payouts (P049, wave 7).
 * Mounted at /api/payouts in apps/zync-api/src/routes/index.ts.
 *
 * Routes:
 *   GET /  → payout ledger (all contractors, filterable, paginated)
 *            Includes totalDue (unpaid, non-void) summary.
 */
import { Hono } from 'hono'
import type { AppEnv } from '../../types'
import { authMiddleware } from '../../middleware/auth'
import { requirePermission } from '../../middleware/guards'
import { requireModuleEnabled } from '../../middleware/require-module-enabled'
import { listAllPayouts, listPayoutsSchema } from '@zync/db/queries'
import { buildPayoutLedgerXlsx } from '../../lib/contractor-payout-exports'

export const payoutRoutes = new Hono<AppEnv>()

payoutRoutes.use('*', authMiddleware)
payoutRoutes.use('*', requireModuleEnabled('contractor_payouts'))

// ── GET /api/payouts ──────────────────────────────────────────────────────────

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

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

  const db = c.get('db')
  const result = await listAllPayouts(db, session.tid, query.data)
  return c.json(result)
})

payoutRoutes.get('/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 query = listPayoutsSchema.safeParse(Object.fromEntries(new URL(c.req.url).searchParams))
  if (!query.success) {
    return c.json({ error: 'Invalid query', issues: query.error.issues }, 400)
  }

  const db = c.get('db')
  const result = await listAllPayouts(db, session.tid, query.data)
  const bytes = await buildPayoutLedgerXlsx({
    totalDue: result.totalDue,
    items: result.items.map((item) => ({
      ...item,
      bill: {
        ...item.bill,
        paidAt: item.bill.paidAt ? item.bill.paidAt.toISOString() : null,
      },
    })),
  })
  return new Response(bytes, {
    status: 200,
    headers: {
      'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      'Content-Disposition': 'attachment; filename="contractor-payout-ledger.xlsx"',
      'Content-Length': String(bytes.byteLength),
      'X-Content-Type-Options': 'nosniff',
    },
  })
})
