/**
 * Financial report generators — scheduled-reports (wave-15).
 *
 * Handles: pl, cashflow, revenue, expenses report types.
 */
import type { Db, ReportScheduleRow } from '@zync/db/queries'
import { getProfitLoss, getCashFlow } from '@zync/db/queries'
import type { Env } from '@zync/types'
import type { ReportPeriod } from '../schedule-math'
import type { ReportData, ReportSection } from './index'

export async function generateFinancialReport(
  schedule: ReportScheduleRow,
  period: ReportPeriod,
  db: Db,
  _env: Env,
): Promise<ReportData> {
  const { reportType, tenantId } = schedule
  const sections: ReportSection[] = []
  let title = ''

  if (reportType === 'pnl') {
    const report = await getProfitLoss(db, tenantId, {
      from: period.from,
      to: period.to,
    })
    title = `Profit & Loss — ${period.label}`

    sections.push({
      heading: 'Revenue',
      columns: ['Category', 'Amount'],
      rows: [
        ['Gross', report.revenue.gross],
        ['Credit Notes', report.revenue.credit_notes],
        ['Bad Debts', report.revenue.bad_debts],
        ['Net', report.revenue.net],
      ],
    })
    sections.push({
      heading: 'Expenses',
      columns: ['Category', 'Amount'],
      rows: [
        ['Total', report.expenses.total],
        ...Object.entries(report.expenses.by_category).map(([cat, amt]) => [cat, amt] as [string, number]),
      ],
    })
    sections.push({
      heading: 'Summary',
      columns: ['Metric', 'Value'],
      rows: [
        ['Contractor Payouts', report.contractor_payouts],
        ['Gross Profit', report.gross_profit],
        ['Net Profit', report.net_profit],
        ['Gross Margin %', report.gross_margin_pct],
      ],
    })
  } else if (reportType === 'cashflow') {
    const report = await getCashFlow(db, tenantId, {
      from: period.from,
      to: period.to,
    })
    title = `Cash Flow — ${period.label}`

    sections.push({
      heading: 'Cash Flow',
      columns: ['Category', 'Amount'],
      rows: [
        ['Received from Customers', report.received_from_customers],
        ['Expenses Paid', report.expenses_paid],
        ['Contractor Payouts', report.contractor_payouts],
        ['Net Operating', report.net_operating],
        ['Tax Issued (Receivable)', report.receivables.tax_issued],
        ['Partially Paid Balance', report.receivables.partially_paid_balance],
      ],
    })
  } else if (reportType === 'revenue') {
    const report = await getProfitLoss(db, tenantId, {
      from: period.from,
      to: period.to,
    })
    title = `Revenue Report — ${period.label}`
    sections.push({
      heading: 'Revenue',
      columns: ['Category', 'Amount'],
      rows: [
        ['Gross', report.revenue.gross],
        ['Credit Notes', report.revenue.credit_notes],
        ['Bad Debts', report.revenue.bad_debts],
        ['Net', report.revenue.net],
      ],
    })
  } else {
    // expenses
    const report = await getProfitLoss(db, tenantId, {
      from: period.from,
      to: period.to,
    })
    title = `Expenses Report — ${period.label}`
    sections.push({
      heading: 'Expenses',
      columns: ['Category', 'Amount'],
      rows: [
        ['Total', report.expenses.total],
        ...Object.entries(report.expenses.by_category).map(([cat, amt]) => [cat, amt] as [string, number]),
      ],
    })
  }

  return { reportType, period, title, sections }
}
