<?php

declare(strict_types=1);

namespace HyperfTest\Cases\Integration\Auth;

use App\Model\ApiKey;
use App\Model\User;
use HyperfTest\TestCase;

/**
 * api_key_enabled 全局开关集成测试
 *
 * @internal
 * @coversNothing
 */
class ApiKeyGlobalSwitchTest extends TestCase
{
    protected function createTestUser(string $suffix, array $overrides = []): User
    {
        return User::query()->create(array_merge([
            'username' => 'gs_test_' . $suffix,
            'password' => 'Pass_' . $suffix,
            'email' => 'gs_test_' . $suffix . '@example.com',
            'status' => 1,
            'api_key_enabled' => true,
        ], $overrides));
    }

    public function test_api_key_auth_rejected_when_global_switch_off(): void
    {
        $user = $this->createTestUser('off_' . uniqid(), ['api_key_enabled' => false]);
        $result = ApiKey::generate($user->id, 'Global Off Key');

        // 手动启用 key（generate 默认 enabled=true），但全局开关关闭
        $response = $this->get('/api/v1/me', [], [
            'X-API-Key' => $result['plain_key'],
        ]);

        $response->assertStatus(403);
        $body = json_decode($response->getBody()->getContents(), true);
        $this->assertStringContainsString('API Key 功能未启用', $body['message']);

        $user->forceDelete();
    }

    public function test_api_key_auth_works_when_global_switch_on(): void
    {
        $user = $this->createTestUser('on_' . uniqid(), ['api_key_enabled' => true]);
        $result = ApiKey::generate($user->id, 'Global On Key');

        $response = $this->get('/api/v1/me', [], [
            'X-API-Key' => $result['plain_key'],
        ]);

        $response->assertStatus(200);
        $response->assertJsonPath('code', 0);
        $response->assertJsonPath('data.id', $user->id);

        $user->forceDelete();
    }

    public function test_api_key_auth_restored_after_reenable(): void
    {
        $user = $this->createTestUser('restore_' . uniqid(), ['api_key_enabled' => true]);
        $result = ApiKey::generate($user->id, 'Restore Key');

        // 关闭全局开关
        $user->api_key_enabled = false;
        $user->save();

        $response = $this->get('/api/v1/me', [], [
            'X-API-Key' => $result['plain_key'],
        ]);
        $response->assertStatus(403);

        // 重新开启
        $user->api_key_enabled = true;
        $user->save();

        $response = $this->get('/api/v1/me', [], [
            'X-API-Key' => $result['plain_key'],
        ]);
        $response->assertStatus(200);
        $response->assertJsonPath('data.id', $user->id);

        $user->forceDelete();
    }

    public function test_disabled_key_still_rejected_after_global_reenable(): void
    {
        $user = $this->createTestUser('disabled_key_' . uniqid(), ['api_key_enabled' => true]);
        $result = ApiKey::generate($user->id, 'Disabled Key');

        // 禁用单个 Key
        $result['api_key']->enabled = false;
        $result['api_key']->save();

        // 全局开关开启，但单 Key 已禁用
        $response = $this->get('/api/v1/me', [], [
            'X-API-Key' => $result['plain_key'],
        ]);

        // 禁用的 Key 返回 403（已被禁用），区别于无效/过期 Key 的 401
        $response->assertStatus(403);
        $body = json_decode($response->getBody()->getContents(), true);
        $this->assertStringContainsString('已被禁用', $body['message']);

        $user->forceDelete();
    }
}
