<?php

declare(strict_types=1);

namespace Tests\Feature;

use App\Features\Agent\Models\Agent;
use App\Features\Auth\Models\User;
use App\Features\Monitoring\Models\AuditLog;
use App\Features\Monitoring\Models\MalwareReport;
use App\Features\Monitoring\Models\PerformanceMetric;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Str;
use Tests\TestCase;

class MonitoringAdminTest extends TestCase
{
    use RefreshDatabase;

    private User $admin;
    private Agent $agent;

    protected function setUp(): void
    {
        parent::setUp();

        $this->admin = User::create([
            'name' => 'Manager Admin',
            'email' => 'manager@gmail.com',
            'password' => bcrypt('Abc@@123'),
        ]);

        $this->agent = Agent::create([
            'id' => (string) Str::uuid(),
            'domain' => 'site-a.com',
            'site_name' => 'Site A',
            'status' => 'active',
            'hmac_secret' => Str::random(32),
        ]);
    }

    public function test_unauthenticated_requests_are_rejected()
    {
        $this->getJson('/api/v1/audit-logs')->assertStatus(401);
        $this->getJson('/api/v1/malware-reports')->assertStatus(401);
        $this->getJson('/api/v1/performance-metrics/' . $this->agent->id)->assertStatus(401);
    }

    public function test_authenticated_admin_can_retrieve_audit_logs()
    {
        AuditLog::create([
            'agent_id' => $this->agent->id,
            'severity' => 'warning',
            'event' => 'login.failed',
            'message' => 'Login attempt failed',
            'context' => ['user' => 'admin'],
        ]);

        $response = $this->actingAs($this->admin)->getJson('/api/v1/audit-logs');

        $response->assertStatus(200)
            ->assertJsonPath('success', true)
            ->assertJsonCount(1, 'logs')
            ->assertJsonPath('logs.0.event', 'login.failed')
            ->assertJsonPath('logs.0.agent.site_name', 'Site A');
    }

    public function test_authenticated_admin_can_retrieve_malware_reports()
    {
        MalwareReport::create([
            'agent_id' => $this->agent->id,
            'files_scanned' => 4500,
            'malicious_files_found' => 0,
            'threat_details' => [],
        ]);

        $response = $this->actingAs($this->admin)->getJson('/api/v1/malware-reports');

        $response->assertStatus(200)
            ->assertJsonPath('success', true)
            ->assertJsonCount(1, 'reports')
            ->assertJsonPath('reports.0.files_scanned', 4500)
            ->assertJsonPath('reports.0.agent.site_name', 'Site A')
            ->assertJsonPath('reports.0.threat_files', []);
    }

    public function test_malware_reports_include_normalized_threat_files(): void
    {
        MalwareReport::create([
            'agent_id' => $this->agent->id,
            'files_scanned' => 1200,
            'malicious_files_found' => 1,
            'threat_details' => [
                'files' => [
                    ['path' => 'wp-content/evil.php', 'type' => 'PHP.Malware.Eval', 'score' => 90],
                ],
            ],
        ]);

        $response = $this->actingAs($this->admin)->getJson('/api/v1/malware-reports');

        $response->assertStatus(200)
            ->assertJsonPath('reports.0.threat_files.0.path', 'wp-content/evil.php')
            ->assertJsonPath('reports.0.threat_files.0.type', 'PHP.Malware.Eval')
            ->assertJsonPath('reports.0.threat_files.0.score', 90);
    }

    public function test_authenticated_admin_can_retrieve_performance_metrics()
    {
        PerformanceMetric::create([
            'agent_id' => $this->agent->id,
            'page_load_time' => 0.320,
            'db_queries_count' => 12,
            'memory_usage' => 18.4,
            'slow_queries' => null,
        ]);

        $response = $this->actingAs($this->admin)->getJson('/api/v1/performance-metrics/' . $this->agent->id);

        $response->assertStatus(200)
            ->assertJsonPath('success', true)
            ->assertJsonCount(1, 'metrics')
            ->assertJsonPath('metrics.0.page_load_time', 0.32);
    }
}
