<?php

namespace Tests\Feature\Api\V1\Administrator;

use App\Services\Administrator\Trophy\TrophyReportService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Mockery;
use Tests\Concerns\CreatesApiTestUsers;
use Tests\TestCase;

class TrophyControllerTest extends TestCase
{
    use CreatesApiTestUsers;
    use RefreshDatabase;

    protected function tearDown(): void
    {
        Mockery::close();
        parent::tearDown();
    }

    public function test_index_requires_authentication(): void
    {
        $this->getJson('/api/v1/administrator/trophy')
            ->assertStatus(401);
    }

    public function test_index_is_forbidden_for_non_admin_users(): void
    {
        $teacher = $this->createApiUserWithRole('teacher');

        $this->actingAs($teacher, 'api')
            ->getJson('/api/v1/administrator/trophy')
            ->assertStatus(403);
    }

    public function test_index_returns_projection_for_admin(): void
    {
        $admin = $this->createApiUserWithRole('administrator');

        $mock = Mockery::mock(TrophyReportService::class);
        $mock->shouldReceive('projection')->once()->andReturn(['rows' => []]);
        $this->app->instance(TrophyReportService::class, $mock);

        $this->actingAs($admin, 'api')
            ->getJson('/api/v1/administrator/trophy')
            ->assertOk()
            ->assertJsonPath('ok', true)
            ->assertJsonPath('data.rows', []);
    }

    public function test_winners_returns_data_for_admin(): void
    {
        $admin = $this->createApiUserWithRole('administrator');

        $mock = Mockery::mock(TrophyReportService::class);
        $mock->shouldReceive('winners')->once()->andReturn(['winners' => []]);
        $this->app->instance(TrophyReportService::class, $mock);

        $this->actingAs($admin, 'api')
            ->getJson('/api/v1/administrator/trophy/winners')
            ->assertOk()
            ->assertJsonPath('ok', true);
    }

    public function test_final_returns_data_for_admin(): void
    {
        $admin = $this->createApiUserWithRole('administrator');

        $mock = Mockery::mock(TrophyReportService::class);
        $mock->shouldReceive('final')->once()->andReturn(['final' => []]);
        $this->app->instance(TrophyReportService::class, $mock);

        $this->actingAs($admin, 'api')
            ->getJson('/api/v1/administrator/trophy/final')
            ->assertOk()
            ->assertJsonPath('ok', true);
    }

    public function test_index_validates_percentile_range(): void
    {
        $admin = $this->createApiUserWithRole('administrator');

        $this->actingAs($admin, 'api')
            ->getJson('/api/v1/administrator/trophy?percentile=150')
            ->assertStatus(422)
            ->assertJsonValidationErrors(['percentile']);
    }
}
