<?php

declare(strict_types=1);

namespace HyperfTest\Cases\Integration\Role;

use App\Model\Role;
use App\Model\User;
use HyperfTest\TestCase;
use Qbhy\HyperfAuth\AuthManager;

use function Hyperf\Support\make;

/**
 * 角色列表 API 集成测试（P14.1）
 *
 * @internal
 * @coversNothing
 */
class RoleControllerTest extends TestCase
{
    protected function getAuthToken(User $user): string
    {
        $auth = make(AuthManager::class);
        return $auth->guard('jwt')->login($user);
    }

    protected function authHeaders(User $user): array
    {
        return ['Authorization' => 'Bearer ' . $this->getAuthToken($user)];
    }

    protected function getAdmin(): User
    {
        $admin_role = Role::query()->where('name', 'administrator')->firstOrFail();
        $user = User::query()->where('status', 1)->where('role_id', $admin_role->id)->first();
        if (!$user) {
            $suffix = bin2hex(random_bytes(4));
            $user = User::query()->create([
                'username' => 'role_test_admin_' . $suffix,
                'email' => 'role_test_admin_' . $suffix . '@example.com',
                'password' => 'Pass_' . $suffix,
                'status' => 1,
                'role_id' => $admin_role->id,
            ]);
        }
        return $user;
    }

    public function test_role_list_returns_users_count(): void
    {
        $admin = $this->getAdmin();

        $response = $this->get('/api/v1/roles', [], $this->authHeaders($admin));
        $response->assertStatus(200);
        $response->assertJsonPath('code', 0);

        $data = $response->json('data');
        $this->assertIsArray($data);
        $this->assertNotEmpty($data);

        // 每个角色都应包含 users_count 字段
        foreach ($data as $role) {
            $this->assertArrayHasKey('users_count', $role, '角色应包含 users_count 字段');
            $this->assertIsInt($role['users_count']);
        }
    }

    public function test_role_list_returns_route_groups_count(): void
    {
        $admin = $this->getAdmin();

        $response = $this->get('/api/v1/roles', [], $this->authHeaders($admin));
        $response->assertStatus(200);

        $data = $response->json('data');
        $this->assertIsArray($data);
        $this->assertNotEmpty($data);

        // 每个角色都应包含 route_groups_count 字段
        foreach ($data as $role) {
            $this->assertArrayHasKey('route_groups_count', $role, '角色应包含 route_groups_count 字段');
            $this->assertIsInt($role['route_groups_count']);
        }
    }

    public function test_role_list_returns_label_and_description(): void
    {
        $admin = $this->getAdmin();

        $response = $this->get('/api/v1/roles', [], $this->authHeaders($admin));
        $response->assertStatus(200);

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

        foreach ($data as $role) {
            $this->assertArrayHasKey('label', $role, '角色应包含 label 字段');
            $this->assertArrayHasKey('description', $role, '角色应包含 description 字段');
        }
    }

    public function test_role_list_requires_auth(): void
    {
        $response = $this->get('/api/v1/roles');
        $response->assertStatus(401);
    }
}
