<?php

declare(strict_types=1);

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

uses(DatabaseTransactions::class);

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

function insertSession(int $userId, string $token, string $ua = 'Mozilla/5.0 (Windows NT 10.0) Chrome/120'): int
{
    return DB::table('user_sessions')->insertGetId([
        'user_id' => $userId,
        'token_hash' => $token,
        'ip_address' => '10.0.0.1',
        'user_agent' => $ua,
        'last_active_at' => now(),
        'created_at' => now(),
        'expires_at' => now()->addHours(2),
    ]);
}

test('GET /api/account/security возвращает активные сессии', function () {
    insertSession($this->user->id, 'sess-token-aaa');

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

    $response->assertOk();
    expect($response->json('sessions'))->toBeArray()->toHaveCount(1);
    expect($response->json('sessions.0.device'))->toContain('Chrome');
    expect($response->json('sessions.0.id'))->toBeInt();
});

test('DELETE /api/account/sessions/{id} отзывает свою сессию', function () {
    $id = insertSession($this->user->id, 'sess-token-bbb');

    $this->deleteJson("/api/account/sessions/{$id}")->assertOk();

    expect(DB::table('user_sessions')->where('id', $id)->exists())->toBeFalse();
});

test('DELETE чужой сессии: 404, чужая строка цела', function () {
    $other = User::factory()->create(['tenant_id' => $this->tenant->id]);
    $id = insertSession($other->id, 'sess-token-ccc');

    $this->deleteJson("/api/account/sessions/{$id}")->assertStatus(404);

    expect(DB::table('user_sessions')->where('id', $id)->exists())->toBeTrue();
});

test('просроченные сессии не показываются', function () {
    DB::table('user_sessions')->insert([
        'user_id' => $this->user->id,
        'token_hash' => 'sess-token-expired',
        'ip_address' => '10.0.0.2',
        'user_agent' => 'old',
        'last_active_at' => now()->subDay(),
        'created_at' => now()->subDay(),
        'expires_at' => now()->subHour(),
    ]);

    $response = $this->getJson('/api/account/security');
    $response->assertOk();
    expect($response->json('sessions'))->toHaveCount(0);
});
