<?php

declare(strict_types=1);

namespace App\Tests\Integration\App;

use App\Auth\UserContext;
use App\Tests\Integration\Support\AppTestCase;

final class DashboardPageTest extends AppTestCase
{
    protected function setUp(): void
    {
        $this->bootApp();
        $_SESSION['_user'] = (new UserContext(1, 'Admin', 'admin', null, UserContext::SOURCE_LOCAL))->toArray();
        $_SESSION['_last_active'] = time();
        $_SESSION['_authenticated_at'] = time();
    }

    public function testDashboardRendersStatsAndChartCanvas(): void
    {
        $this->enqueueApiResponse(200, [
            'active_blocks' => 12,
            'manual_blocks_count' => 3,
            'allowlist_count' => 1,
            'reports_24h' => 42,
            'reports_24h_by_hour' => [
                ['hour' => '2026-04-29T10:00:00Z', 'count' => 7],
                ['hour' => '2026-04-29T11:00:00Z', 'count' => 35],
            ],
            'top_reporters_24h' => [['name' => 'web-prod-01', 'count' => 30]],
            'top_categories_24h' => [['slug' => 'brute_force', 'count' => 25]],
            'blocked_ips_by_day_7d' => [
                'days' => [
                    '2026-04-23', '2026-04-24', '2026-04-25', '2026-04-26',
                    '2026-04-27', '2026-04-28', '2026-04-29',
                ],
                'series' => [
                    ['category' => 'brute_force', 'counts' => [0, 2, 1, 0, 3, 5, 1]],
                    ['category' => 'spam',        'counts' => [0, 1, 0, 0, 1, 2, 0]],
                ],
            ],
            'jobs_status' => [['name' => 'recompute-scores', 'last_finished_at' => '2026-04-29T10:55:00Z', 'status' => 'success', 'overdue' => false]],
            'reference_policy' => 'moderate',
        ]);

        $response = $this->request('GET', '/app/dashboard');

        self::assertSame(200, $response->getStatusCode());
        $body = (string) $response->getBody();
        self::assertStringContainsString('Dashboard', $body);
        self::assertStringContainsString('reports', $body);
        self::assertStringContainsString('id="reports-chart"', $body);
        self::assertStringContainsString('id="top-reporters-chart"', $body);
        self::assertStringContainsString('id="top-categories-chart"', $body);
        self::assertStringContainsString('id="blocked-ips-chart"', $body);
        self::assertStringContainsString('Blocked IPs', $body);
        self::assertStringContainsString('web-prod-01', $body);
        self::assertStringContainsString('brute_force', $body);
        self::assertStringContainsString('recompute-scores', $body);
        self::assertStringContainsString('moderate', $body);
    }

    public function testDashboardDegradesWhenApiUnreachable(): void
    {
        $this->enqueueApiException(new \GuzzleHttp\Exception\ConnectException(
            'down',
            new \GuzzleHttp\Psr7\Request('GET', '/'),
        ));
        $this->enqueueApiException(new \GuzzleHttp\Exception\ConnectException(
            'down',
            new \GuzzleHttp\Psr7\Request('GET', '/'),
        ));

        $response = $this->request('GET', '/app/dashboard');

        self::assertSame(200, $response->getStatusCode());
        $body = (string) $response->getBody();
        self::assertStringContainsString('Dashboard', $body);
        self::assertStringContainsString('API unreachable', $body);
    }
}
