<?php

declare(strict_types=1);

use App\Models\Tenant;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Tests\Concerns\SharesSupplierPdo;

uses(DatabaseTransactions::class, SharesSupplierPdo::class);

/**
 * Создаёт активную impersonation-сессию через init→verify и возвращает
 * ['tenant' => $tenant, 'token' => $machineToken].
 */
function g7bActiveMachineToken(): array
{
    $tenant = Tenant::factory()->create([
        'contact_email' => 'g7b-machine-tenant-'.uniqid().'@example.ru',
    ]);

    User::factory()->create([
        'tenant_id' => $tenant->id,
        'is_active' => true,
    ]);

    $adminId = DB::table('saas_admin_users')->insertGetId([
        'email' => 'admin-g7b-'.uniqid().'@liderra.ru',
        'full_name' => 'G7B Machine Admin',
        'password_hash' => '$2y$04$dummy-hash-for-test',
        'role' => 'support',
        'is_active' => true,
        'sso_provider' => 'local',
        'is_break_glass' => false,
    ]);

    $init = test()->postJson('/api/admin/impersonation/init', [
        'tenant_id' => $tenant->id,
        'requested_by' => $adminId,
        'reason' => str_repeat('основание для теста машинного ключа ', 2),
    ])->assertOk()->json();

    $verify = test()->postJson('/api/admin/impersonation/verify', [
        'token_id' => $init['token_id'],
        'code' => $init['_dev_plain_code'],
    ])->assertOk()->json();

    // Сбрасываем сессию и auth-state Laravel после verify, чтобы следующие
    // запросы шли только через машинный ключ, не через cookie/session-auth.
    test()->flushSession();
    Auth::logout();

    return [
        'tenant' => $tenant,
        'token' => $verify['machine_token'],
    ];
}

it('машинный ключ авторизует чтение сделок в периметре тенанта', function () {
    ['token' => $token] = g7bActiveMachineToken();

    $this->withHeader('Authorization', 'Bearer '.$token)
        ->getJson('/api/deals')
        ->assertOk();
});

it('битый/несуществующий ключ не авторизует', function () {
    $this->withHeader('Authorization', 'Bearer lpimp_999999_deadbeefdeadbeef')
        ->getJson('/api/deals')
        ->assertUnauthorized();
});

it('машинный ключ НЕ авторизует опасные группы (ключи/деньги)', function () {
    ['token' => $token] = g7bActiveMachineToken();

    $this->withHeader('Authorization', 'Bearer '.$token)
        ->getJson('/api/api-keys')
        ->assertUnauthorized();

    $this->withHeader('Authorization', 'Bearer '.$token)
        ->postJson('/api/billing/topup', [])
        ->assertUnauthorized();
});

it('при активном impersonation вход в админ-зону запрещён (bearer)', function () {
    ['token' => $token] = g7bActiveMachineToken();
    $this->withHeader('Authorization', 'Bearer '.$token)
        ->getJson('/api/admin/tenants')->assertForbidden();
});

it('обычная cookie-сессия по-прежнему работает на разрешённой группе', function () {
    $tenant = Tenant::factory()->create();
    $user = User::factory()->create([
        'tenant_id' => $tenant->id,
        'is_active' => true,
    ]);

    $this->actingAs($user)
        ->withHeader('X-Tenant-Id', (string) $user->tenant_id)
        ->getJson('/api/deals')
        ->assertOk();
});
