<?php

declare(strict_types=1);

namespace App\Tests\Integration\Settings;

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

final class SettingsPageTest extends AppTestCase
{
    protected function setUp(): void
    {
        $this->bootApp();
    }

    public function testAdminSeesConfigAndJobs(): void
    {
        $_SESSION['_user'] = (new UserContext(1, 'Admin', 'admin', null, UserContext::SOURCE_LOCAL))->toArray();
        $_SESSION['_last_active'] = time();
        $_SESSION['_authenticated_at'] = time();

        // First call: getConfig
        $this->enqueueApiResponse(200, [
            'sections' => [
                'app' => ['APP_ENV' => 'development', 'LOG_LEVEL' => 'Info'],
                'database' => ['DB_DRIVER' => 'sqlite'],
                'auth' => ['INTERNAL_JOB_TOKEN' => '***', 'UI_SERVICE_TOKEN' => 'irdb_svc...'],
                'reputation' => ['SCORE_REPORT_HARD_CUTOFF_DAYS' => 365],
                'jobs' => ['JOB_AUDIT_RETENTION_DAYS' => 180],
                'geoip' => ['GEOIP_PROVIDER' => 'dbip', 'GEOIP_COUNTRY_DB' => '/data/geoip/country.mmdb', 'GEOIP_ASN_DB' => '/data/geoip/asn.mmdb', 'MAXMIND_LICENSE_KEY' => '', 'IPINFO_TOKEN' => ''],
            ],
        ]);
        // Second call: getJobsStatus
        $this->enqueueApiResponse(200, [
            'now' => '2026-04-29T10:00:00Z',
            'jobs' => [
                'recompute-scores' => [
                    'name' => 'recompute-scores',
                    'default_interval_seconds' => 300,
                    'max_runtime_seconds' => 240,
                    'overdue' => false,
                    'lock' => null,
                    'last_run' => [
                        'id' => 1,
                        'status' => 'success',
                        'items_processed' => 0,
                        'triggered_by' => 'schedule',
                        'started_at' => '2026-04-29T09:55:00Z',
                        'finished_at' => '2026-04-29T09:55:01Z',
                        'error_message' => null,
                    ],
                ],
            ],
        ]);
        // Third call: getAppSettings (audit toggles)
        $this->enqueueApiResponse(200, [
            'audit_report_received_enabled' => true,
            'audit_blocklist_request_enabled' => true,
        ]);

        $resp = $this->request('GET', '/app/settings');

        self::assertSame(200, $resp->getStatusCode());
        $body = (string) $resp->getBody();
        self::assertStringContainsString('Configuration', $body);
        self::assertStringContainsString('Jobs', $body);
        self::assertStringContainsString('GeoIP', $body);
        self::assertStringContainsString('recompute-scores', $body);
        self::assertStringContainsString('Run now', $body);
        self::assertStringContainsString('dbip', $body);
    }

    public function testViewerRedirectsToNoAccess(): void
    {
        $_SESSION['_user'] = (new UserContext(2, 'Viewer', 'viewer', null, UserContext::SOURCE_LOCAL))->toArray();
        $_SESSION['_last_active'] = time();
        $_SESSION['_authenticated_at'] = time();

        $resp = $this->request('GET', '/app/settings');
        self::assertSame(303, $resp->getStatusCode());
        self::assertSame('/no-access', $resp->getHeaderLine('Location'));
    }

    public function testAnonymousRedirectsToLogin(): void
    {
        $_SESSION = [];
        $resp = $this->request('GET', '/app/settings');
        self::assertSame(302, $resp->getStatusCode());
        self::assertSame('/login', $resp->getHeaderLine('Location'));
    }
}
