<?php

declare(strict_types=1);

namespace BotGuard\Tests\Unit;

use BotGuard\Core\Crypto;
use BotGuard\Core\View;
use BotGuard\Services\Export\PdfReportExporter;
use BotGuard\Services\Export\PdfWriter;
use BotGuard\Services\Export\XlsxExporter;
use PHPUnit\Framework\TestCase;

/**
 * Tests for the export writers, the crypto helper and email rendering.
 */
final class ExportMailTest extends TestCase
{
    public function testXlsxProducesValidZip(): void
    {
        $bytes = (new XlsxExporter())->build(['A', 'B'], [['1', '2'], ['x', 'y']]);

        // .xlsx is a ZIP container — magic bytes "PK".
        $this->assertStringStartsWith('PK', $bytes);
        $this->assertGreaterThan(300, strlen($bytes));
    }

    public function testPdfWriterProducesValidDocument(): void
    {
        $pdf = new PdfWriter();
        $pdf->addPage();
        $pdf->text(40, 40, 'Hello');
        $out = $pdf->output();

        $this->assertStringStartsWith('%PDF-1.4', $out);
        $this->assertStringContainsString('xref', $out);
        $this->assertStringEndsWith('%%EOF', $out);
    }

    public function testPdfReportRendersRowsAcrossPage(): void
    {
        $rows = array_fill(0, 120, ['2026-07-10 10:00', '1.2.3.4', '90', 'human']);
        $columns = [
            ['label' => 'Time', 'width' => 120], ['label' => 'IP', 'width' => 100],
            ['label' => 'Score', 'width' => 60], ['label' => 'Class', 'width' => 100],
        ];

        $body = (new PdfReportExporter())->report('r.pdf', 'Report', ['Total' => 120], $columns, $rows)->body();

        // 120 rows must overflow one page — expect multiple /Page objects.
        $this->assertGreaterThan(1, substr_count($body, '/Type /Page '));
        $this->assertStringStartsWith('%PDF', $body);
    }

    public function testCryptoRoundTrip(): void
    {
        $secret = 'p@ssw0rd-with-ünicode-🔒';
        $cipher = Crypto::encrypt($secret);

        $this->assertTrue(Crypto::isEncrypted($cipher));
        $this->assertNotSame($secret, $cipher);
        $this->assertSame($secret, Crypto::decrypt($cipher));
    }

    public function testCryptoPassesThroughLegacyPlaintext(): void
    {
        // A non-prefixed (legacy/plaintext) value is returned unchanged.
        $this->assertSame('plain', Crypto::decrypt('plain'));
        $this->assertFalse(Crypto::isEncrypted('plain'));
    }

    public function testEmailTemplateRenders(): void
    {
        $view = new View(dirname(__DIR__, 2) . '/app/Views');
        $html = $view->render('emails.test', ['subject' => 'Test']);

        $this->assertStringContainsString('SMTP is working', $html);
        $this->assertStringContainsString('<html', $html);
    }
}
