<?php

namespace Tests\Feature;

use App\Models\ApiRequestLog;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

final class ApiLogControllerTest extends TestCase
{
    use RefreshDatabase;

    public function test_api_log_index_zeigt_die_api_logs_seite_mit_paginated_logs(): void
    {
        $this->withoutVite();
        $user = User::factory()->create();

        ApiRequestLog::create([
            'method' => 'fetchEvents',
            'endpoint' => 'events',
            'status' => 'success',
            'duration_ms' => 124,
        ]);

        $response = $this->actingAs($user)->get(route('api-logs.index'));

        $response->assertOk();
        $response->assertInertia(
            fn ($page) => $page
                ->component('ApiLogs/Index')
                ->has('logs.data', 1)
                ->where('logs.data.0.method', 'fetchEvents')
                ->where('filters.search', '')
                ->where('filters.status', '')
        );
    }

    public function test_api_log_index_filtert_nach_suche(): void
    {
        $this->withoutVite();
        $user = User::factory()->create();

        ApiRequestLog::create([
            'method' => 'fetchEvents',
            'endpoint' => 'events',
            'status' => 'success',
            'duration_ms' => 101,
        ]);

        ApiRequestLog::create([
            'method' => 'syncAgenda',
            'endpoint' => 'agenda',
            'status' => 'error',
            'error_message' => 'Agenda not found',
            'duration_ms' => 222,
        ]);

        $response = $this->actingAs($user)->get(route('api-logs.index', ['search' => 'fetchEvents']));

        $response->assertOk();
        $response->assertInertia(
            fn ($page) => $page
                ->component('ApiLogs/Index')
                ->has('logs.data', 1)
                ->where('logs.data.0.method', 'fetchEvents')
                ->where('filters.search', 'fetchEvents')
        );
    }

    public function test_api_log_index_filtert_nach_status(): void
    {
        $this->withoutVite();
        $user = User::factory()->create();

        ApiRequestLog::create([
            'method' => 'fetchSongs',
            'endpoint' => 'songs',
            'status' => 'success',
            'duration_ms' => 77,
        ]);

        ApiRequestLog::create([
            'method' => 'getEventServices',
            'endpoint' => 'event_services',
            'status' => 'error',
            'error_message' => 'Service not found',
            'duration_ms' => 309,
        ]);

        $response = $this->actingAs($user)->get(route('api-logs.index', ['status' => 'error']));

        $response->assertOk();
        $response->assertInertia(
            fn ($page) => $page
                ->component('ApiLogs/Index')
                ->has('logs.data', 1)
                ->where('logs.data.0.status', 'error')
                ->where('filters.status', 'error')
        );
    }

    public function test_api_log_index_enthaelt_request_context_und_response_summary(): void
    {
        $this->withoutVite();
        $user = User::factory()->create();

        ApiRequestLog::create([
            'method' => 'fetchEvents',
            'endpoint' => 'events',
            'status' => 'success',
            'request_context' => ['eventId' => 42, 'includeAgenda' => true],
            'response_summary' => 'Array mit 3 Eintraegen',
            'duration_ms' => 150,
        ]);

        $response = $this->actingAs($user)->get(route('api-logs.index'));

        $response->assertOk();
        $response->assertInertia(
            fn ($page) => $page
                ->component('ApiLogs/Index')
                ->has('logs.data', 1)
                ->where('logs.data.0.request_context', ['eventId' => 42, 'includeAgenda' => true])
                ->where('logs.data.0.response_summary', 'Array mit 3 Eintraegen')
        );
    }

    public function test_api_log_index_behandelt_null_context_und_summary(): void
    {
        $this->withoutVite();
        $user = User::factory()->create();

        ApiRequestLog::create([
            'method' => 'fetchSongs',
            'endpoint' => 'songs',
            'status' => 'success',
            'request_context' => null,
            'response_summary' => null,
            'duration_ms' => 80,
        ]);

        $response = $this->actingAs($user)->get(route('api-logs.index'));

        $response->assertOk();
        $response->assertInertia(
            fn ($page) => $page
                ->component('ApiLogs/Index')
                ->has('logs.data', 1)
                ->where('logs.data.0.request_context', null)
                ->where('logs.data.0.response_summary', null)
        );
    }

    public function test_api_request_log_scopes_funktionieren(): void
    {
        ApiRequestLog::create([
            'method' => 'fetchEvents',
            'endpoint' => 'events',
            'status' => 'success',
            'duration_ms' => 51,
        ]);

        ApiRequestLog::create([
            'method' => 'syncAgenda',
            'endpoint' => 'agenda',
            'status' => 'error',
            'error_message' => 'Agenda not found',
            'duration_ms' => 120,
        ]);

        $countErrorWithSearch = ApiRequestLog::query()
            ->byStatus('error')
            ->search('agenda')
            ->count();

        $countWithoutFilter = ApiRequestLog::query()
            ->byStatus('')
            ->search('')
            ->count();

        $this->assertSame(1, $countErrorWithSearch);
        $this->assertSame(2, $countWithoutFilter);
    }
}
