<?php

namespace Tests\Feature\Api;

use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;

class RolePermissionTest extends ApiTestCase
{
    protected function setUp(): void
    {
        parent::setUp();
        $this->createAuthenticatedUser();
    }

    public function test_can_list_all_roles(): void
    {
        // Roles are already seeded in seedPermissionsAndRoles
        $response = $this->getJson('/api/v1/roles');

        $this->assertSuccessResponse($response);
        $this->assertGreaterThanOrEqual(1, count($response->json('data'))); // At least Super Admin
    }

    public function test_can_create_role(): void
    {
        $response = $this->postJson('/api/v1/roles', [
            'name' => 'New Role',
        ]);

        $this->assertSuccessResponse($response, 201);
        $this->assertDatabaseHas('roles', [
            'name' => 'New Role',
            'guard_name' => 'sanctum',
        ]);
    }

    public function test_role_name_must_be_unique(): void
    {
        Role::create(['name' => 'Unique Role', 'guard_name' => 'sanctum']);

        $response = $this->postJson('/api/v1/roles', [
            'name' => 'Unique Role',
        ]);

        $response->assertStatus(422);
    }

    public function test_can_show_single_role(): void
    {
        $role = Role::create(['name' => 'Test Role', 'guard_name' => 'sanctum']);

        $response = $this->getJson("/api/v1/roles/{$role->id}");

        $this->assertSuccessResponse($response);
        $response->assertJson([
            'data' => [
                'name' => 'Test Role',
            ],
        ]);
    }

    public function test_can_update_role(): void
    {
        $role = Role::create(['name' => 'Old Role', 'guard_name' => 'sanctum']);

        $response = $this->putJson("/api/v1/roles/{$role->id}", [
            'name' => 'Updated Role',
        ]);

        $this->assertSuccessResponse($response);
        $this->assertDatabaseHas('roles', [
            'id' => $role->id,
            'name' => 'Updated Role',
        ]);
    }

    public function test_can_delete_role(): void
    {
        $role = Role::create(['name' => 'Delete Me', 'guard_name' => 'sanctum']);

        $response = $this->deleteJson("/api/v1/roles/{$role->id}");

        $this->assertSuccessResponse($response, 200, false);
        $this->assertDatabaseMissing('roles', ['id' => $role->id]);
    }

    public function test_can_sync_permissions_to_role(): void
    {
        $role = Role::create(['name' => 'Test Role Sync', 'guard_name' => 'sanctum']);

        $response = $this->postJson("/api/v1/roles/{$role->id}/permissions", [
            'permissions' => ['products.view', 'products.create'],
        ]);

        $this->assertSuccessResponse($response);
        $this->assertTrue($role->fresh()->hasPermissionTo('products.view'));
        $this->assertTrue($role->fresh()->hasPermissionTo('products.create'));
    }

    public function test_can_get_role_permissions(): void
    {
        $role = Role::create(['name' => 'Test Role', 'guard_name' => 'sanctum']);
        $role->givePermissionTo('products.view', 'products.create');

        $response = $this->getJson("/api/v1/roles/{$role->id}/permissions");

        $this->assertSuccessResponse($response);
        $this->assertCount(2, $response->json('data'));
    }

    public function test_can_list_all_permissions(): void
    {
        $response = $this->getJson('/api/v1/permissions');

        $this->assertSuccessResponse($response);
        $this->assertNotEmpty($response->json('data'));
    }

    public function test_can_get_permissions_by_module(): void
    {
        $response = $this->getJson('/api/v1/permissions/by-module');

        $this->assertSuccessResponse($response);
        $data = $response->json('data');
        $this->assertArrayHasKey('products', $data);
        $this->assertArrayHasKey('orders', $data);
    }

    public function test_can_assign_role_to_user(): void
    {
        $newUser = $this->createUser(['email' => 'newuser@test.com']);
        $role = Role::create(['name' => 'Test Role', 'guard_name' => 'sanctum']);

        $response = $this->postJson("/api/v1/users/{$newUser->id}/assign-role", [
            'role' => 'Test Role',
        ]);

        $this->assertSuccessResponse($response);
        $this->assertTrue($newUser->fresh()->hasRole('Test Role'));
    }

    public function test_can_revoke_role_from_user(): void
    {
        $newUser = $this->createUser(['email' => 'revokeuser@test.com']);
        $role = Role::create(['name' => 'Revoke Role', 'guard_name' => 'sanctum']);
        $newUser->assignRole('Revoke Role');

        $response = $this->postJson("/api/v1/users/{$newUser->id}/revoke-role", [
            'role' => 'Revoke Role',
        ]);

        $this->assertSuccessResponse($response);
        $this->assertFalse($newUser->fresh()->hasRole('Revoke Role'));
    }

    public function test_can_get_user_permissions(): void
    {
        $response = $this->getJson("/api/v1/users/{$this->user->id}/permissions");

        $this->assertSuccessResponse($response);
    }
}
