<?php

declare(strict_types=1);

namespace BotGuard\Services\Export;

use BotGuard\Core\Response;

/**
 * Builds a branded, paginated tabular PDF report on top of PdfWriter.
 *
 * Used for the dashboard "Export PDF" of verification results. Handles the
 * header band, a summary strip, column headers and automatic page breaks with
 * repeating headers and a page footer.
 */
final class PdfReportExporter
{
    private const MARGIN = 40.0;
    private const ROW_HEIGHT = 18.0;
    private const HEADER_RGB = [37, 99, 235];   // brand blue
    private const LIGHT_RGB = [243, 244, 246];
    private const TEXT_RGB = [17, 24, 39];
    private const MUTED_RGB = [107, 114, 128];

    /**
     * @param array<string, string|int>            $summary  label => value strip
     * @param array<int, array{label:string, width:float}> $columns
     * @param array<int, array<int, string>>       $rows
     */
    public function report(string $filename, string $title, array $summary, array $columns, array $rows): Response
    {
        $pdf = new PdfWriter();
        $bottom = $pdf->pageHeight() - self::MARGIN;

        $pdf->addPage();
        $y = $this->drawHeader($pdf, $title, $summary);
        $y = $this->drawColumnHeader($pdf, $columns, $y);

        foreach ($rows as $row) {
            if ($y + self::ROW_HEIGHT > $bottom) {
                $this->drawFooter($pdf);
                $pdf->addPage();
                $y = $this->drawHeader($pdf, $title, $summary);
                $y = $this->drawColumnHeader($pdf, $columns, $y);
            }

            $x = self::MARGIN;
            foreach ($columns as $i => $col) {
                $value = (string) ($row[$i] ?? '');
                $pdf->text($x + 4, $y + 12, $this->truncate($value, $col['width']), 9, self::TEXT_RGB);
                $x += $col['width'];
            }
            $pdf->line(self::MARGIN, $y + self::ROW_HEIGHT, $pdf->pageWidth() - self::MARGIN, $y + self::ROW_HEIGHT, [229, 231, 235], 0.4);
            $y += self::ROW_HEIGHT;
        }

        if ($rows === []) {
            $pdf->text(self::MARGIN + 4, $y + 14, 'No records for this period.', 10, self::MUTED_RGB);
        }

        $this->drawFooter($pdf);

        $binary = $pdf->output();

        return (new Response($binary))
            ->withHeader('Content-Type', 'application/pdf')
            ->withHeader('Content-Disposition', 'attachment; filename="' . $filename . '"')
            ->withHeader('Content-Length', (string) strlen($binary))
            ->withHeader('Cache-Control', 'no-store');
    }

    /**
     * @param array<string, string|int> $summary
     */
    private function drawHeader(PdfWriter $pdf, string $title, array $summary): float
    {
        $width = $pdf->pageWidth();

        $pdf->rect(0, 0, $width, 64, self::HEADER_RGB);
        $pdf->text(self::MARGIN, 30, (string) config('app.name', 'BotGuard'), 18, [255, 255, 255], true);
        $pdf->text(self::MARGIN, 48, $title, 11, [219, 234, 254]);
        $pdf->text($width - self::MARGIN - 150, 30, 'Generated ' . now() . ' UTC', 8, [219, 234, 254]);

        $y = 84.0;
        if ($summary !== []) {
            $x = self::MARGIN;
            foreach ($summary as $label => $value) {
                $pdf->text($x, $y, (string) $label, 8, self::MUTED_RGB);
                $pdf->text($x, $y + 14, (string) $value, 13, self::TEXT_RGB, true);
                $x += 110;
            }
            $y += 32;
        }

        return $y;
    }

    /**
     * @param array<int, array{label:string, width:float}> $columns
     */
    private function drawColumnHeader(PdfWriter $pdf, array $columns, float $y): float
    {
        $width = $pdf->pageWidth() - self::MARGIN * 2;
        $pdf->rect(self::MARGIN, $y, $width, self::ROW_HEIGHT, self::LIGHT_RGB);

        $x = self::MARGIN;
        foreach ($columns as $col) {
            $pdf->text($x + 4, $y + 13, $col['label'], 9, self::TEXT_RGB, true);
            $x += $col['width'];
        }

        return $y + self::ROW_HEIGHT;
    }

    private function drawFooter(PdfWriter $pdf): void
    {
        $y = $pdf->pageHeight() - 24;
        $pdf->line(self::MARGIN, $y, $pdf->pageWidth() - self::MARGIN, $y, [229, 231, 235], 0.5);
        $pdf->text(self::MARGIN, $y + 12, (string) config('app.name', 'BotGuard') . ' — Verification Report', 8, self::MUTED_RGB);
    }

    /**
     * Trim a value to roughly fit its column width (points).
     */
    private function truncate(string $value, float $width): string
    {
        $maxChars = (int) max(3, ($width - 8) / (9 * 0.5));
        if (mb_strlen($value) <= $maxChars) {
            return $value;
        }

        return mb_substr($value, 0, $maxChars - 1) . '…';
    }
}
