<?php
/**
 * ExportHelper — reusable XLSX + PDF exporters for tabular reports.
 *
 * Column spec:
 *   [
 *     ['label' => 'Code',   'width' => 22, 'align' => 'L', 'type' => 'string'],
 *     ['label' => 'Amount', 'width' => 32, 'align' => 'R', 'type' => 'money'],
 *   ]
 * Rows: array of arrays, one value per column in order.
 * Totals: [['label' => 'Totals', 'values' => [null, null, 12345.67, ...]], ...]
 *
 * Both formats use a light neutral palette:
 *   header fill = slate-100 (#F1F5F9)   header ink = soft charcoal (#334155)
 *   footer fill = slate-200 (#E2E8F0)   footer ink = soft charcoal
 *   money positive = light sage (#7A9E7E)  money negative = soft rose (#C48579)
 *
 * Font: Roboto Condensed (Regular + Bold) — set on every XLSX cell style,
 *   embedded in PDF via /fonts/fpdf/.
 */
class ExportHelper
{
    /* ── XLSX ──────────────────────────────────────────────────────────── */

    /**
     * Stream an XLSX file to the browser (Content-Disposition: attachment).
     * $meta: ['title','subtitle','as_at'] optional — rendered as leading rows.
     */
    public static function xlsxDownload(string $filename, string $sheetName, array $columns, array $rows, array $totals = [], array $meta = []): void
    {
        if (!class_exists('XLSXWriter')) require ROOT . '/app/models/XLSXWriter.php';

        $writer = new XLSXWriter();
        $writer->setTitle($meta['title'] ?? $sheetName);
        $writer->setAuthor('RS Flow · rsflow.dspera');
        $writer->setCompany('Dspera');

        // Reusable styles — light neutral palette, Roboto Condensed on every cell
        $FONT = 'Roboto Condensed';
        $sTitle    = ['font' => $FONT, 'font-size' => 14, 'font-style' => 'bold', 'color' => '#334155'];
        $sSubtitle = ['font' => $FONT, 'font-size' => 10, 'color' => '#64748B'];
        $sHeader   = ['font' => $FONT, 'font-style' => 'bold', 'fill' => '#F1F5F9', 'color' => '#334155',
                      'border' => 'top,bottom,left,right', 'border-color' => '#E2E8F0', 'halign' => 'center'];
        $sMoney    = ['font' => $FONT, 'halign' => 'right', 'color' => '#334155'];
        $sBody     = ['font' => $FONT, 'color' => '#334155'];
        $sFooter   = ['font' => $FONT, 'font-style' => 'bold', 'fill' => '#E2E8F0', 'color' => '#334155',
                      'border' => 'top', 'border-color' => '#E2E8F0'];

        // Widths + header types for XLSXWriter (needed for a well-formed sheet)
        $headerTypes = [];
        $widths = [];
        foreach ($columns as $c) {
            $type = $c['type'] ?? 'string';
            $xtype = $type === 'money' ? '#,##0;-#,##0' : ($type === 'date' ? 'yyyy-mm-dd' : 'string');
            $headerTypes[$c['label']] = $xtype;
            $widths[] = ['widths' => [$c['width'] ?? 18]];
        }

        // Title + subtitle rows (blank column headers so they don't clash with real header row)
        $blankHeader = [];
        foreach ($columns as $c) $blankHeader[$c['label']] = 'string';

        // We stream two "virtual" rows before the real header via writeSheetRow with generic types
        $writer->writeSheetHeader($sheetName, $blankHeader, ['suppress_row' => true, 'widths' => array_map(fn($c) => $c['width'] ?? 18, $columns)]);

        if (!empty($meta['title']))    $writer->writeSheetRow($sheetName, [$meta['title']],    ['height' => 22, 0 => $sTitle]);
        if (!empty($meta['subtitle'])) $writer->writeSheetRow($sheetName, [$meta['subtitle']], [0 => $sSubtitle]);
        if (!empty($meta['title']) || !empty($meta['subtitle'])) $writer->writeSheetRow($sheetName, []);

        // Real header row
        $writer->writeSheetRow($sheetName, array_map(fn($c) => $c['label'], $columns), $sHeader);

        // Data rows — every cell gets Roboto Condensed via $sBody, money cells get right-align
        foreach ($rows as $r) {
            $rowStyle = [];
            foreach ($columns as $i => $c) {
                $rowStyle[$i] = (($c['type'] ?? '') === 'money') ? $sMoney : $sBody;
            }
            $writer->writeSheetRow($sheetName, array_values($r), $rowStyle);
        }

        // Footer / totals
        foreach ($totals as $t) {
            $row = [];
            $label = $t['label'] ?? '';
            $values = $t['values'] ?? [];
            foreach ($columns as $i => $c) {
                if ($i === 0) $row[] = $label;
                else          $row[] = $values[$i] ?? '';
            }
            $writer->writeSheetRow($sheetName, $row, $sFooter);
        }

        // Send headers + body
        self::sendDownloadHeaders($filename, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        $writer->writeToStdOut();
    }

    /* ── PDF ───────────────────────────────────────────────────────────── */

    /**
     * Stream a PDF file to the browser.
     * $orientation 'P' (portrait) or 'L' (landscape).
     */
    public static function pdfDownload(string $filename, string $title, string $subtitle, array $columns, array $rows, array $totals = [], string $orientation = 'P'): void
    {
        self::ensureFpdf();
        $pdf = new RsPdfReport($orientation, 'mm', 'A4');
        $pdf->AliasNbPages();
        $pdf->setReportMeta($title, $subtitle);
        $pdf->setColumns($columns);
        $pdf->AddPage();
        $pdf->drawTableHeader();
        foreach ($rows as $r) $pdf->drawRow(array_values($r));
        foreach ($totals as $t) $pdf->drawFooter($t['label'] ?? '', $t['values'] ?? []);

        self::sendDownloadHeaders($filename, 'application/pdf');
        $pdf->Output('I', $filename);
    }

    /* ── Shared helpers ────────────────────────────────────────────────── */

    public static function sendDownloadHeaders(string $filename, string $mime): void
    {
        header('Content-Type: ' . $mime);
        header('Content-Disposition: attachment; filename="' . str_replace('"', '', $filename) . '"');
        header('Cache-Control: max-age=0');
        header('Pragma: public');
    }

    private static function ensureFpdf(): void
    {
        if (!defined('FPDF_FONTPATH')) define('FPDF_FONTPATH', ROOT . '/fonts/fpdf/');
        if (!class_exists('FPDF')) require ROOT . '/core/FPDF.php';
        if (!class_exists('RsPdfReport')) require ROOT . '/app/models/RsPdfReport.php';
    }
}
