<?php

namespace Tests\Feature\Api;

use App\Models\Permission;
use App\Models\Role;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\Concerns\CreatesApiTestUsers;
use Tests\TestCase;

class ApiRolePermissionFeatureTest extends TestCase
{
    use CreatesApiTestUsers;
    use RefreshDatabase;

    public function test_admin_can_manage_roles_permissions_and_assign_roles(): void
    {
        $this->actingAsApiAdministrator();
        $roles = $this->seedApiRoles();
        $target = User::factory()->create(['email' => 'assign-role-target@example.test']);

        $roleResponse = $this->postJson('/api/v1/administrator/role-permission/roles', [
            'name' => 'finance_manager',
            'slug' => 'finance-manager',
            'description' => 'Finance Manager',
            'dashboard_route' => 'finance/dashboard',
            'priority' => 20,
            'is_active' => 1,
        ])
            ->assertCreated()
            ->assertJsonPath('status', true);

        $roleId = (int) data_get($roleResponse->json(), 'data.role.id');
        $this->assertGreaterThan(0, $roleId);

        $this->getJson('/api/v1/administrator/role-permission/roles')
            ->assertOk()
            ->assertJsonFragment(['name' => 'finance_manager']);

        $this->patchJson("/api/v1/administrator/role-permission/roles/$roleId", [
            'description' => 'Updated Finance Manager',
            'priority' => 21,
        ])
            ->assertOk()
            ->assertJsonPath('status', true);

        $permissionResponse = $this->postJson('/api/v1/administrator/role-permission/permissions', [
            'name' => 'finance.reports.view',
            'description' => 'View finance reports',
        ])
            ->assertCreated()
            ->assertJsonPath('status', true);

        $permissionId = (int) data_get($permissionResponse->json(), 'data.permission.id');
        $this->assertGreaterThan(0, $permissionId);

        $this->putJson("/api/v1/administrator/role-permission/roles/$roleId/permissions", [
            'permissions' => [
                (string) $permissionId => [
                    'read' => true,
                    'create' => false,
                    'update' => false,
                    'delete' => false,
                    'manage' => false,
                ],
            ],
        ])
            ->assertOk()
            ->assertJsonPath('status', true);

        $this->postJson("/api/v1/administrator/role-permission/users/{$target->id}/roles", [
            'role_ids' => [$roles['parent']->id, $roleId],
        ])
            ->assertOk()
            ->assertJsonPath('status', true);

        $this->assertDatabaseHas('roles', ['id' => $roleId, 'priority' => 21]);
        $this->assertDatabaseHas('permissions', ['id' => $permissionId, 'name' => 'finance.reports.view']);
        $this->assertContains('finance_manager', $target->fresh()->roleNames());

        $this->deleteJson("/api/v1/administrator/role-permission/permissions/$permissionId")
            ->assertOk()
            ->assertJsonPath('status', true);

        $this->deleteJson("/api/v1/administrator/role-permission/roles/$roleId")
            ->assertOk()
            ->assertJsonPath('status', true);
    }

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

        $this->postJson('/api/v1/administrator/role-permission/roles', [
            'name' => 'ab',
            'dashboard_route' => 'bad route with spaces',
            'priority' => -1,
            'is_active' => 2,
        ])
            ->assertStatus(422)
            ->assertJsonValidationErrors(['name', 'dashboard_route', 'priority', 'is_active']);

        $this->postJson('/api/v1/administrator/role-permission/permissions', [])
            ->assertStatus(422)
            ->assertJsonValidationErrors(['name']);
    }
}
