/**
 * financial-export.ts — RTL/Hebrew Excel + CSV export helpers.
 *
 * Shared by financial-statements (spec 170) and israeli-tax-reports (spec 176).
 * Provides:
 *   - newRtlWorksheet: RTL workbook sheet with Hebrew-capable font
 *   - writeFinancialWorkbook: xlsx bytes from a build callback
 *   - sanitizeCell: formula-injection guard
 *   - toCsvRow: CSV-escaped, sanitized row string
 */
import type ExcelJS from 'exceljs'

export type { Workbook, Worksheet } from 'exceljs'

// ── Formula-injection guard ───────────────────────────────────────────────────

const INJECTION_CHARS = new Set(['=', '+', '-', '@', '\t', '\r'])

/**
 * Guard against CSV/xlsx formula injection.
 * Any string value whose first character is one of `= + - @ \t \r`
 * is prefixed with a single quote `'` before writing.
 * Non-string values are returned as-is.
 */
export function sanitizeCell(value: unknown): unknown {
  if (typeof value !== 'string') return value
  if (value.length === 0) return value
  const first = value.charAt(0)
  if (INJECTION_CHARS.has(first)) return `'${value}`
  return value
}

// ── RTL Worksheet factory ─────────────────────────────────────────────────────

const HEBREW_FONT: Partial<ExcelJS.Font> = { name: 'Arial', charset: 177 }

/**
 * Add a new worksheet to `wb` with RTL direction and a Hebrew-capable font.
 * All cells added to this worksheet should have the `HEBREW_FONT` applied.
 */
export function newRtlWorksheet(wb: ExcelJS.Workbook, name: string): ExcelJS.Worksheet {
  const ws = wb.addWorksheet(name)
  ws.views = [{ rightToLeft: true, state: 'normal' as const }]
  // Default row/cell style with Hebrew-capable font
  ws.properties.defaultRowHeight = 15
  return ws
}

/**
 * Apply Hebrew-capable font to a cell.
 */
export function applyHebrewFont(cell: ExcelJS.Cell): void {
  cell.font = HEBREW_FONT as ExcelJS.Font
}

// ── Workbook writer ───────────────────────────────────────────────────────────

/**
 * Build an xlsx workbook using `build` callback, then return raw bytes.
 */
export async function writeFinancialWorkbook(
  build: (wb: ExcelJS.Workbook) => void | Promise<void>,
): Promise<Uint8Array> {
  const ExcelJS = (await import('exceljs')).default
  const wb = new ExcelJS.Workbook()
  wb.creator = 'Zync'
  wb.lastModifiedBy = 'Zync'
  wb.created = new Date()
  wb.modified = new Date()
  await build(wb)
  const buffer = await wb.xlsx.writeBuffer()
  return new Uint8Array(buffer as ArrayBuffer)
}

// ── CSV helpers ───────────────────────────────────────────────────────────────

/**
 * Produce a single CSV row string from an array of field values.
 * Each field is sanitized for formula injection, then quoted/escaped per RFC 4180.
 * Returns the row WITHOUT a trailing newline (caller appends \r\n for CP1255 encoding).
 */
export function toCsvRow(fields: string[], options?: { sanitize?: boolean }): string {
  const sanitize = options?.sanitize !== false
  return fields
    .map((f) => {
      const safe = (sanitize ? sanitizeCell(f) : f) as string
      // Quote fields that contain comma, double-quote, or newline
      if (safe.includes(',') || safe.includes('"') || safe.includes('\n') || safe.includes('\r')) {
        return `"${safe.replace(/"/g, '""')}"`
      }
      return safe
    })
    .join(',')
}
