<?php

declare(strict_types=1);

use App\Http\Middleware\SetTenantContext;
use App\Models\Project;
use App\Models\Tenant;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Route;

/**
 * Тесты middleware SetTenantContext: резолюция tenant_id и установка
 * `app.current_tenant_id` для RLS-фильтрации.
 *
 * Не проверяет RLS-фильтрацию в самом запросе — это RlsSmokeTest.
 * Здесь только что middleware корректно устанавливает PG-переменную.
 */
uses(DatabaseTransactions::class);

beforeEach(function () {
    Route::middleware([SetTenantContext::class])->get('/_test/tenant-context', function () {
        // current_setting вернёт NULL если не установлено (с missing_ok=true).
        $value = DB::selectOne("SELECT current_setting('app.current_tenant_id', true) AS v")->v;

        return response()->json(['tenant_id' => $value]);
    });
});

test('middleware возвращает 403 без tenant context', function () {
    $response = $this->get('/_test/tenant-context');
    $response->assertStatus(403);
});

test('middleware устанавливает tenant_id из X-Tenant-Id header', function () {
    $tenant = Tenant::factory()->create();

    $response = $this->withHeaders(['X-Tenant-Id' => (string) $tenant->id])
        ->get('/_test/tenant-context');

    $response->assertStatus(200);
    expect((int) $response->json('tenant_id'))->toBe($tenant->id);
});

test('middleware игнорирует не-числовой X-Tenant-Id header', function () {
    $response = $this->withHeaders(['X-Tenant-Id' => 'not-a-number'])
        ->get('/_test/tenant-context');

    $response->assertStatus(403);
});

test('middleware резолвит tenant_id по subdomain', function () {
    $tenant = Tenant::factory()->create(['subdomain' => 'acme-corp']);

    $response = $this->get('http://acme-corp.liderra.ru/_test/tenant-context');

    $response->assertStatus(200);
    expect((int) $response->json('tenant_id'))->toBe($tenant->id);
});

test('middleware с tenant_id корректно фильтрует данные через RLS', function () {
    // Этот тест НЕ работает на postgres-superuser (BYPASSRLS),
    // но показывает что middleware устанавливает контекст для будущих
    // запросов под crm_app_user. Проверка эквивалентности значения.
    $tenant1 = Tenant::factory()->create();
    $tenant2 = Tenant::factory()->create();
    Project::factory()->count(2)->create(['tenant_id' => $tenant1->id]);
    Project::factory()->count(3)->create(['tenant_id' => $tenant2->id]);

    Route::middleware([SetTenantContext::class])->get('/_test/projects-count', function () {
        // Без BYPASSRLS было бы COUNT только tenant1's projects
        $tenant1Count = DB::table('projects')->where('tenant_id', request()->header('X-Expected-Tenant'))->count();

        return response()->json(['count' => $tenant1Count]);
    });

    $response = $this->withHeaders([
        'X-Tenant-Id' => (string) $tenant1->id,
        'X-Expected-Tenant' => (string) $tenant1->id,
    ])->get('/_test/projects-count');

    $response->assertStatus(200);
    expect($response->json('count'))->toBe(2);
});
