<?php

namespace App\Tests\Admin;

use App\Tests\ApiTestCase;

/**
 * GET /api/v1/admin/logs — admin-only, paginated, filterable by level.
 */
class AdminLogsTest extends ApiTestCase
{
    private function seedLog(string $level, string $message): void
    {
        $this->em->getConnection()->insert('app_log', [
            'level'      => $level,
            'message'    => $message,
            'channel'    => 'app',
            'path'       => '/test',
            'created_at' => time(),
        ]);
    }

    public function testNonAdminForbidden(): void
    {
        $user = $this->createUser(['ROLE_USER']);
        $this->authJson('GET', '/api/v1/admin/logs', $user);
        self::assertSame(403, $this->responseCode());
    }

    public function testAdminSeesLogsFilteredByLevel(): void
    {
        $marker = 'ADMINLOGTEST_' . bin2hex(random_bytes(5));
        $this->seedLog('error', $marker . '_err');
        $this->seedLog('warning', $marker . '_warn');

        $admin = $this->createUser(['ROLE_ADMIN']);
        $body  = $this->authJson('GET', '/api/v1/admin/logs?level=error&search=' . $marker, $admin);

        self::assertSame(200, $this->responseCode());
        self::assertTrue($body['success']);
        self::assertCount(1, $body['data']);
        self::assertSame('error', $body['data'][0]['level']);
        self::assertSame($marker . '_err', $body['data'][0]['message']);
        self::assertArrayHasKey('totalRecords', $body['meta']);

        $this->em->getConnection()->executeStatement('DELETE FROM app_log WHERE message LIKE ?', [$marker . '%']);
    }

    public function testExportNonAdminForbidden(): void
    {
        $user = $this->createUser(['ROLE_USER']);
        $this->authJson('GET', '/api/v1/admin/logs/export', $user);
        self::assertSame(403, $this->responseCode());
    }

    public function testAdminExportsCsvFilteredByLevel(): void
    {
        $marker = 'ADMINLOGEXPORT_' . bin2hex(random_bytes(5));
        $this->seedLog('error', $marker . '_err');
        $this->seedLog('warning', $marker . '_warn');

        $admin = $this->createUser(['ROLE_ADMIN']);
        $this->client->request(
            'GET',
            '/api/v1/admin/logs/export?level=error&search=' . $marker,
            server: ['HTTP_AUTHORIZATION' => 'Bearer ' . $this->jwtFor($admin)],
        );
        $response = $this->client->getResponse();

        self::assertSame(200, $response->getStatusCode());
        self::assertStringContainsString('text/csv', (string) $response->headers->get('Content-Type'));
        self::assertStringContainsString('attachment', (string) $response->headers->get('Content-Disposition'));

        // StreamedResponse body is captured by BrowserKit into the internal response.
        $csv = $this->client->getInternalResponse()->getContent();

        self::assertStringContainsString('id,level,message', $csv);
        self::assertStringContainsString($marker . '_err', $csv);
        self::assertStringNotContainsString($marker . '_warn', $csv);

        $this->em->getConnection()->executeStatement('DELETE FROM app_log WHERE message LIKE ?', [$marker . '%']);
    }
}
