/**
 * Cash Flow report routes — financial-statements (wave-13).
 * Mounted under /api/reports in the main reports router.
 *
 * GET /api/reports/cashflow        → CashFlowReport (JSON)
 * GET /api/reports/cashflow/xlsx   → RTL Hebrew Excel download (Business+ only)
 *
 * Guards: authMiddleware + requireTier('business') + requirePermission('reports:read')
 * Export guard adds requirePermission('reports:export').
 */
import { Hono } from 'hono'
import { z } from 'zod'
import type { AppEnv } from '../../types'
import { authMiddleware } from '../../middleware/auth'
import { requirePermission, requireTier } from '../../middleware/guards'
import { createDb, getCashFlow, logAuditEvent } from '@zync/db/queries'
import { TenantTier } from '@zync/types'
import type ExcelJS from 'exceljs'

// ── Helpers ────────────────────────────────────────────────────────────────────

function safe(v: unknown): string {
  const s = String(v ?? '')
  return /^[=+\-@\t\r]/.test(s) ? `'${s}` : s
}

// ── Query schema ───────────────────────────────────────────────────────────────

const cashflowQuerySchema = z.object({
  from: z.string().date(),
  to: z.string().date(),
})

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

export const cashflowReportRoutes = new Hono<AppEnv>()

cashflowReportRoutes.use('*', authMiddleware)
cashflowReportRoutes.use('*', requireTier(TenantTier.BUSINESS))

// GET /cashflow/xlsx — export first (avoid prefix-match)
cashflowReportRoutes.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 tenantId = session.tid

    const parsed = cashflowQuerySchema.safeParse(c.req.query())
    if (!parsed.success) {
      return c.json({ error: 'Invalid query params', details: parsed.error.flatten() }, 400)
    }

    const { from, to } = parsed.data
    if (to < from) {
      return c.json({ error: "'to' must be >= 'from'" }, 400)
    }

    const db = createDb(c.env)
    const report = await getCashFlow(db, tenantId, { from, to })

    // Audit log — fire-and-forget inside same request context
    void logAuditEvent(c, {
      tenantId,
      userId: session.sub,
      actorName: undefined,
      actorEmail: undefined,
      eventType: 'report.export',
      entityType: 'cashflow',
      entityLabel: `${from}_${to}`,
      metadata: { from, to },
    })

    // Build RTL Hebrew workbook
    const ExcelJS = (await import('exceljs')).default
    const wb = new ExcelJS.Workbook()
    const ws = wb.addWorksheet('תזרים מזומנים', { views: [{ rightToLeft: true }] })

    ws.columns = [
      { header: safe('שורה'), key: 'label', width: 36 },
      { header: safe(`${from} – ${to}`), key: 'amount', width: 18 },
    ]
    const headerRow = ws.getRow(1)
    headerRow.font = { bold: true, name: 'Arial' }
    headerRow.fill = {
      type: 'pattern',
      pattern: 'solid',
      fgColor: { argb: 'FFE8E8E8' },
    } as ExcelJS.Fill

    const rows: Array<{ label: string; amount: number | string }> = [
      { label: 'תקבולים מלקוחות', amount: report.received_from_customers },
      { label: 'תשלומי הוצאות', amount: -report.expenses_paid },
      { label: 'תשלומים לקבלני משנה', amount: -report.contractor_payouts },
      { label: 'תזרים תפעולי נטו', amount: report.net_operating },
      { label: '', amount: '' },
      { label: '— חייבים (נקודת זמן) —', amount: '' },
      { label: 'חשבוניות מס שהוצאו', amount: report.receivables.tax_issued },
      { label: 'שולם חלקית — יתרה', amount: report.receivables.partially_paid_balance },
    ]

    for (const row of rows) {
      const r = ws.addRow([safe(row.label), typeof row.amount === 'number' ? row.amount : ''])
      r.font = { name: 'Arial' }
    }

    ws.getColumn('B').numFmt = '#,##0.00'

    const buffer = await wb.xlsx.writeBuffer()
    const filename = `cash-flow-${from}_${to}.xlsx`

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

// GET /cashflow — JSON report
cashflowReportRoutes.get(
  '/',
  requirePermission('reports:read'),
  async (c) => {
    const session = c.get('session')
    if (!session || session.type !== 'user' || !session.tid) {
      return c.json({ error: 'Unauthorized' }, 401)
    }
    const tenantId = session.tid

    const parsed = cashflowQuerySchema.safeParse(c.req.query())
    if (!parsed.success) {
      return c.json({ error: 'Invalid query params', details: parsed.error.flatten() }, 400)
    }

    const { from, to } = parsed.data
    if (to < from) {
      return c.json({ error: "'to' must be >= 'from'" }, 400)
    }

    const db = createDb(c.env)
    const report = await getCashFlow(db, tenantId, { from, to })
    return c.json(report)
  },
)
