<?php

declare(strict_types=1);

namespace HyperfTest\Cases\Integration\Auth;

use App\Model\ApiKey;
use HyperfTest\TestCase;
use HyperfTest\Traits\AuthenticatedTestTrait;

/**
 * API Key 认证端到端集成测试
 *
 * 验证 API Key 能正确访问各业务端点（products / orders / refunds / api-keys），
 * 以及无效 Key 被拒绝、JWT 认证仍然正常。
 *
 * @internal
 * @coversNothing
 */
class ApiKeyAuthEndToEndTest extends TestCase
{
    use AuthenticatedTestTrait;

    /**
     * 获取 admin 用户的 API Key 明文
     */
    protected function getAdminApiKey(): string
    {
        // 确保 admin 用户已开启 api_key_enabled
        $admin_role = $this->fetchAdminRole();
        $user = $this->fetchUser(static function ($query) use ($admin_role): void {
            $query->where('status', 1)->where('role_id', $admin_role->id);
        });
        $this->runInCoroutine(static function () use ($user): void {
            if (!$user->api_key_enabled) {
                $user->api_key_enabled = true;
                $user->save();
            }
            // 清理旧测试 keys，确保不超过上限
            ApiKey::query()->where('user_id', $user->id)
                ->where('name', 'like', 'E2E Test Key%')
                ->delete();
        });

        $token = $this->getAdminToken();

        $response = $this->post('/api/v1/me/api-keys', [
            'name' => 'E2E Test Key ' . bin2hex(random_bytes(4)),
        ], [
            'Authorization' => 'Bearer ' . $token,
        ]);

        $response->assertStatus(200);

        return $response->json('data.plain_key');
    }

    protected function apiKeyHeaders(): array
    {
        return ['X-API-Key' => $this->getAdminApiKey()];
    }

    // ========== 业务端点 API Key 认证 ==========

    public function test_apikey_auth_products_endpoint(): void
    {
        $response = $this->get('/api/v1/products', [], $this->apiKeyHeaders());

        $response->assertStatus(200);
        $response->assertJsonPath('code', 0);
    }

    public function test_apikey_auth_orders_endpoint(): void
    {
        $response = $this->get('/api/v1/orders', [], $this->apiKeyHeaders());

        $response->assertStatus(200);
        $response->assertJsonPath('code', 0);
    }

    public function test_apikey_auth_refunds_endpoint(): void
    {
        $response = $this->get('/api/v1/refunds', [], $this->apiKeyHeaders());

        $response->assertStatus(200);
        $response->assertJsonPath('code', 0);
    }

    public function test_apikey_auth_list_own_keys(): void
    {
        $response = $this->get('/api/v1/me/api-keys', [], $this->apiKeyHeaders());

        $response->assertStatus(200);
        $response->assertJsonPath('code', 0);
    }

    // ========== 认证失败场景 ==========

    public function test_invalid_apikey_returns_401(): void
    {
        $response = $this->get('/api/v1/products', [], [
            'X-API-Key' => 'dh_invalid_key_that_does_not_exist_00000000',
        ]);

        $response->assertStatus(401);
    }

    // ========== JWT 认证仍正常 ==========

    public function test_jwt_auth_still_works(): void
    {
        $response = $this->get('/api/v1/products', [], $this->authHeaders());

        $response->assertStatus(200);
        $response->assertJsonPath('code', 0);
    }
}
