<?php

declare(strict_types=1);

use App\Models\ApiKey;
use App\Models\Tenant;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Hash;

uses(DatabaseTransactions::class);

beforeEach(function () {
    $this->tenant = Tenant::factory()->create();
    $this->user = User::factory()->create(['tenant_id' => $this->tenant->id]);
    $this->actingAs($this->user);
});

test('GET /api/api-keys возвращает активные ключи тенанта', function () {
    ApiKey::factory()->create(['tenant_id' => $this->tenant->id, 'user_id' => $this->user->id]);

    $response = $this->getJson('/api/api-keys');

    $response->assertOk();
    expect($response->json('data'))->toHaveCount(1);
    expect($response->json('data.0'))->toHaveKeys(['id', 'name', 'key_prefix', 'last_used_at', 'created_at']);
    expect($response->json('data.0'))->not->toHaveKey('key_hash');
});

test('GET /api/api-keys без auth: 401', function () {
    auth()->logout();
    $this->getJson('/api/api-keys')->assertStatus(401);
});

test('GET /api/api-keys изолирован по тенанту', function () {
    $otherTenant = Tenant::factory()->create();
    $otherUser = User::factory()->create(['tenant_id' => $otherTenant->id]);
    ApiKey::factory()->create(['tenant_id' => $otherTenant->id, 'user_id' => $otherUser->id]);

    $response = $this->getJson('/api/api-keys');

    $response->assertOk();
    expect($response->json('data'))->toHaveCount(0);
});

test('GET /api/api-keys не возвращает истёкшие ключи', function () {
    ApiKey::factory()->create([
        'tenant_id' => $this->tenant->id,
        'user_id' => $this->user->id,
        'is_active' => true,
        'expires_at' => now()->subDay(),
    ]);
    ApiKey::factory()->create([
        'tenant_id' => $this->tenant->id,
        'user_id' => $this->user->id,
        'is_active' => true,
        'expires_at' => now()->addYear(),
    ]);

    $response = $this->getJson('/api/api-keys');

    $response->assertOk();
    expect($response->json('data'))->toHaveCount(1);
});

test('POST /api/api-keys/regenerate создаёт ключ и возвращает plaintext один раз', function () {
    $response = $this->postJson('/api/api-keys/regenerate');

    $response->assertStatus(201);
    expect($response->json('key'))->toStartWith('lpkapi_');
    expect($response->json('key_prefix'))->toBe(substr($response->json('key'), 0, 10));
    expect($response->json())->toHaveKeys(['id', 'name', 'key', 'key_prefix']);

    $row = ApiKey::query()->where('tenant_id', $this->tenant->id)->where('is_active', true)->first();
    expect($row)->not->toBeNull();
    expect($row->key_hash)->not->toBe($response->json('key'));
    expect(Hash::check($response->json('key'), $row->key_hash))->toBeTrue();
});

test('POST /api/api-keys/regenerate деактивирует предыдущий активный ключ', function () {
    $old = ApiKey::factory()->create([
        'tenant_id' => $this->tenant->id,
        'user_id' => $this->user->id,
        'is_active' => true,
    ]);

    $this->postJson('/api/api-keys/regenerate')->assertStatus(201);

    $old->refresh();
    expect($old->is_active)->toBeFalse();
    expect(ApiKey::query()->where('tenant_id', $this->tenant->id)->where('is_active', true)->count())->toBe(1);
});

test('POST /api/api-keys/regenerate без auth: 401', function () {
    auth()->logout();
    $this->postJson('/api/api-keys/regenerate')->assertStatus(401);
});
