<?php

declare(strict_types=1);

use App\Models\ImpersonationToken;
use App\Models\Tenant;
use App\Services\Pd\ImpersonationAuditService;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Tests\TestCase;

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

beforeEach(function () {
    $this->tenant = Tenant::factory()->create();
    $this->adminId = DB::table('saas_admin_users')->insertGetId([
        'email' => 'admin-imp-'.uniqid().'@liderra.ru',
        'full_name' => 'SaaS Admin',
        'password_hash' => '$2y$04$dummy-hash-for-test',
        'role' => 'support',
        'is_active' => true,
        'sso_provider' => 'local',
        'is_break_glass' => false,
    ]);
    $this->token = ImpersonationToken::create([
        'tenant_id' => $this->tenant->id,
        'requested_by' => $this->adminId,
        'code_hash' => 'h',
        'reason' => 'support case '.str_repeat('x', 30),
        'sent_to_email' => 'a@b.ru',
        'expires_at' => now()->addMinutes(15),
    ]);
});

it('recordInit writes saas_admin_audit_log action=impersonation.init', function () {
    app(ImpersonationAuditService::class)->recordInit($this->token, adminId: $this->adminId, ip: '1.2.3.4');
    $row = DB::table('saas_admin_audit_log')->where('action', 'impersonation.init')->latest('id')->first();
    expect($row)->not->toBeNull()
        ->and((int) $row->target_id)->toBe($this->tenant->id)
        ->and($row->reason)->toBe($this->token->reason);
});

it('recordVerify writes BOTH saas_audit and pd_processing_log', function () {
    app(ImpersonationAuditService::class)->recordVerify($this->token, adminId: $this->adminId, ip: '1.2.3.4');
    expect(DB::table('saas_admin_audit_log')->where('action', 'impersonation.verify')->count())->toBe(1)
        ->and(DB::table('pd_processing_log')
            ->where('action', 'viewed')
            ->where('purpose', 'impersonation_session_'.$this->token->id)
            ->where('actor_admin_user_id', $this->adminId)
            ->count())->toBe(1);
});

it('recordEnd writes saas_admin_audit_log action=impersonation.end', function () {
    app(ImpersonationAuditService::class)->recordEnd($this->token, adminId: $this->adminId, ip: '1.2.3.4');
    expect(DB::table('saas_admin_audit_log')->where('action', 'impersonation.end')->count())->toBe(1);
});
