<?php

declare(strict_types=1);

/**
 * 152-ФЗ integration: pd_processing_log captures the full deal lifecycle
 * for one tenant — create → view → export → delete.
 *
 * Uses the deterministic manual-API path (no supplier/webhook jobs) so the
 * test is robust and self-contained.
 *
 * Convention mirrors: DealCreateTest / DealExportPdLogTest /
 *   DealViewAccessLogTest / ReportFileDeletePdLogTest
 */

use App\Models\Deal;
use App\Models\Project;
use App\Models\ReportJob;
use App\Models\Tenant;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;

uses(DatabaseTransactions::class);

beforeEach(function () {
    Storage::fake('local');

    $this->tenant = Tenant::factory()->create(['balance_leads' => 100]);
    $this->user = User::factory()->for($this->tenant)->create();
    $this->actingAs($this->user);
    DB::statement('SET app.current_tenant_id = '.(int) $this->tenant->id);
    $this->project = Project::factory()->for($this->tenant)->create(['name' => 'PD Flow Test']);
});

it('records pd events through the whole deal lifecycle (create → view → export → delete)', function () {

    // ── 1. CREATE (manual) → pd action='created', purpose='lead_create_manual' ──
    $created = $this->postJson('/api/deals', [
        'project_name' => $this->project->name,
        'phone' => '+7 (999) 123-45-67',
    ]);
    $created->assertStatus(201);
    $dealId = (int) $created->json('deal.id');
    expect($dealId)->toBeGreaterThan(0);

    // ── 2. VIEW → pd action='viewed', purpose='lead_card_view' ──
    $this->getJson("/api/deals/{$dealId}")->assertOk();

    // ── 3. EXPORT → pd action='exported', purpose='deals_export_csv' ──
    //    Mirror: DealExportPdLogTest — POST /api/deals/export with format=csv
    //    We need at least one deal in the tenant for a non-empty export; the
    //    deal we just created qualifies.
    $exported = $this->post('/api/deals/export', ['format' => 'csv']);
    $exported->assertStatus(200);

    // ── 4. DELETE report file → pd action='deleted', purpose='report_file_{id}' ──
    //    Mirror: ReportFileDeletePdLogTest — create a DONE ReportJob with file_path,
    //    then DELETE /api/reports/jobs/{id}.
    $job = ReportJob::create([
        'tenant_id' => $this->tenant->id,
        'user_id' => $this->user->id,
        'type' => 'deals_export',
        'parameters' => ['format' => 'csv', 'date_from' => '2026-01-01', 'date_to' => '2026-12-31'],
        'status' => ReportJob::STATUS_DONE,
        'file_path' => 'reports/'.(int) $this->tenant->id.'/pd_flow_test.csv',
    ]);

    $this->deleteJson("/api/reports/jobs/{$job->id}")->assertOk();

    // ── ASSERT — scoped to THIS tenant ────────────────────────────────────────
    $rows = DB::table('pd_processing_log')
        ->where('tenant_id', $this->tenant->id)
        ->get();
    $byAction = $rows->groupBy('action');

    // All four lifecycle actions must be present.
    expect($byAction->has('created'))->toBeTrue()
        ->and($byAction->has('viewed'))->toBeTrue()
        ->and($byAction->has('exported'))->toBeTrue()
        ->and($byAction->has('deleted'))->toBeTrue();

    // Correct purpose for each action.
    expect($rows->firstWhere('action', 'created')->purpose)->toBe('lead_create_manual');
    expect($rows->firstWhere('action', 'viewed')->purpose)->toBe('lead_card_view');
    expect($rows->contains(fn ($r) => $r->action === 'exported' && $r->purpose === 'deals_export_csv'))->toBeTrue();
    expect($rows->firstWhere('action', 'deleted')->purpose)->toBe('report_file_'.$job->id);

    // 'created' and 'viewed' rows are tied to the deal we created.
    expect((int) $rows->firstWhere('action', 'created')->subject_id)->toBe($dealId);
    expect((int) $rows->firstWhere('action', 'viewed')->subject_id)->toBe($dealId);

    // All rows carry the correct actor.
    foreach (['created', 'viewed', 'exported', 'deleted'] as $action) {
        $row = $rows->firstWhere('action', $action);
        expect((int) $row->actor_tenant_user_id)->toBe($this->user->id);
        expect($row->actor_admin_user_id)->toBeNull();
    }
});
