<?php

namespace Tests\Feature\Api;

use App\Models\Role;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Hash;
use Tests\Concerns\CreatesApiTestUsers;
use Tests\TestCase;

class ApiUserManagementFeatureTest extends TestCase
{
    use CreatesApiTestUsers;
    use RefreshDatabase;

    public function test_admin_can_create_list_update_and_delete_a_user_through_api(): void
    {
        $this->actingAsApiAdministrator();
        $roles = $this->seedApiRoles();

        $createPayload = $this->validUserPayload((int) $roles['parent']->id, [
            'email' => 'api-user-crud@example.test',
            'firstname' => 'Original',
        ]);

        $create = $this->postJson('/api/v1/users', $createPayload)
            ->assertCreated()
            ->assertJsonPath('ok', true);

        $userId = (int) $create->json('user_id');
        $this->assertGreaterThan(0, $userId);

        $created = User::query()->findOrFail($userId);
        $this->assertSame('api-user-crud@example.test', $created->email);
        $this->assertTrue(Hash::check('password', (string) $created->password));
        $this->assertSame(['parent'], $created->roleNames());

        $this->getJson('/api/v1/users')
            ->assertOk()
            ->assertJsonPath('ok', true)
            ->assertJsonFragment(['email' => 'api-user-crud@example.test']);

        $this->putJson("/api/v1/users/$userId", [
            'firstname' => 'Updated',
            'status' => 'Inactive',
        ])
            ->assertOk()
            ->assertJsonPath('ok', true);

        $this->assertDatabaseHas('users', [
            'id' => $userId,
            'firstname' => 'Updated',
            'status' => 'Inactive',
        ]);

        $this->deleteJson("/api/v1/users/$userId")
            ->assertOk()
            ->assertJsonPath('ok', true);
    }

    public function test_user_creation_validates_required_payload_and_unique_email(): void
    {
        $this->actingAsApiAdministrator();
        $roles = $this->seedApiRoles();

        $this->postJson('/api/v1/users', [])
            ->assertStatus(422)
            ->assertJsonValidationErrors(['firstname', 'lastname', 'cellphone', 'email', 'address_street', 'city', 'state', 'zip', 'accept_school_policy', 'role_id', 'password', 'semester']);

        User::factory()->create(['email' => 'already-used@example.test']);

        $this->postJson('/api/v1/users', $this->validUserPayload((int) $roles['teacher']->id, [
            'email' => 'already-used@example.test',
        ]))
            ->assertStatus(422)
            ->assertJsonValidationErrors(['email']);
    }

    public function test_user_creation_rejects_nonexistent_role_id(): void
    {
        $this->actingAsApiAdministrator();

        $this->postJson('/api/v1/users', $this->validUserPayload(999999))
            ->assertStatus(422)
            ->assertJsonValidationErrors(['role_id']);
    }
}
