<?php

namespace Tests\Feature\Api\V1\Administrator;

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

class AdministratorDashboardControllerTest extends TestCase
{
    use CreatesApiTestUsers;
    use RefreshDatabase;

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

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

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

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

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

        $mock = Mockery::mock(AdministratorDashboardService::class);
        $mock->shouldReceive('metrics')->once()->andReturn([
            'students' => 42,
            'teachers' => 5,
        ]);
        $this->app->instance(AdministratorDashboardService::class, $mock);

        $this->actingAs($admin, 'api')
            ->getJson('/api/v1/administrator/dashboard/metrics')
            ->assertOk()
            ->assertJson(['students' => 42, 'teachers' => 5]);
    }

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

        $mock = Mockery::mock(AdministratorDashboardService::class);
        $mock->shouldReceive('userSearch')
            ->once()
            ->with('smith')
            ->andReturn(['results' => [['id' => 1, 'name' => 'Smith']]]);
        $this->app->instance(AdministratorDashboardService::class, $mock);

        $this->actingAs($admin, 'api')
            ->getJson('/api/v1/administrator/dashboard/user-search?query=smith')
            ->assertOk()
            ->assertJsonPath('results.0.name', 'Smith');
    }
}
