<?php

declare(strict_types=1);

use App\Models\Deal;
use App\Models\Project;
use App\Models\SupplierLead;
use App\Models\SupplierProject;
use App\Models\SystemSetting;
use App\Models\Tenant;
use Database\Seeders\PricingTierSeeder;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Tests\Concerns\SharesSupplierPdo;

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

beforeEach(function (): void {
    // Plan 4 Task 4: LedgerService требует наличия активных PricingTier'ов
    // для tier-resolve в chargeForDelivery (вызывается из RouteSupplierLeadJob).
    $this->seed(PricingTierSeeder::class);
    SystemSetting::query()->where('key', 'supplier_webhook_secret')
        ->update(['value' => 'test-secret-32chars-aaaaaaaaaaaaaa']);
});

it('end-to-end: 1 webhook → 3 deal copies for 3 active tenants', function (): void {
    $supplier = SupplierProject::factory()->create([
        'platform' => 'B1',
        'signal_type' => 'site',
        'unique_key' => 'vashinvestor.ru',
    ]);

    $tenants = collect();
    $projects = collect();
    for ($i = 0; $i < 3; $i++) {
        $t = Tenant::factory()->create(['balance_leads' => 0, 'balance_rub' => '1000.00']);
        $tenants->push($t);
        $project = Project::factory()->create([
            'tenant_id' => $t->id,
            'supplier_b1_project_id' => $supplier->id,
            'signal_type' => 'site',
            'signal_identifier' => 'vashinvestor.ru',
            'is_active' => true,
            'delivered_today' => 0,
            'delivered_in_month' => 0,
            'delivery_days_mask' => 127,
            'region_mask' => 255,
            'region_mode' => 'include',
            'daily_limit_target' => 10,
            'effective_daily_limit_today' => null,
        ]);
        $projects->push($project);
        // v8.26 (Plan 1-2): LeadRouter eligibility — через pivot project_supplier_links,
        // не legacy supplier_b1_project_id. Без pivot-связи проект не eligible → 0 сделок.
        linkProjectToSupplier($project, $supplier);
        createRoutingSnapshotFromProject($project, null, 'site', 'vashinvestor.ru');
    }

    // 4-й tenant — paused (is_active=false). Связь в pivot есть, чтобы проверялся
    // именно фильтр is_active, а не отсутствие связи.
    $pausedTenant = Tenant::factory()->create(['balance_leads' => 0, 'balance_rub' => '1000.00']);
    $pausedProject = Project::factory()->create([
        'tenant_id' => $pausedTenant->id,
        'supplier_b1_project_id' => $supplier->id,
        'signal_type' => 'site',
        'signal_identifier' => 'vashinvestor.ru',
        'is_active' => false,
    ]);
    linkProjectToSupplier($pausedProject, $supplier);
    // NB: snapshot для paused-проекта НЕ создаём — SnapshotBackfillCommand в prod
    // фильтрует `WHERE p.is_active = true`. Это и есть Task 2.5 R-01 защита от
    // обратного case'а: paused after slepok всё равно НЕ получит лиды (потому что
    // snapshot fix'нут до его paused).

    $vid = 432176649;
    $response = $this->postJson('/api/webhook/supplier/test-secret-32chars-aaaaaaaaaaaaaa', [
        'vid' => $vid,
        'project' => 'B1_vashinvestor.ru',
        'tag' => 'Ваш инвестор',
        'phone' => '79991234567',
        'phones' => ['79991234567'],
        'time' => time(),
    ]);

    $response->assertStatus(202);

    foreach ($projects as $i => $project) {
        $tenant = $tenants[$i];
        DB::statement("SET LOCAL app.current_tenant_id = '{$tenant->id}'");

        $deals = Deal::query()
            ->where('tenant_id', $tenant->id)
            ->where('source_crm_id', $vid)
            ->get();
        expect($deals)->toHaveCount(1, "tenant {$tenant->id} expected 1 deal copy");

        $deal = $deals->first();
        expect($deal->phone)->toBe('79991234567');
        expect($deal->project_id)->toBe($project->id);
        expect($deal->duplicate_of_id)->toBeNull();

        expect((string) $tenant->fresh()->balance_rub)->toBe('500.00');
        expect($project->fresh()->delivered_today)->toBe(1);
        expect($project->fresh()->delivered_in_month)->toBe(1);
    }

    DB::statement("SET LOCAL app.current_tenant_id = '{$pausedTenant->id}'");
    expect(Deal::query()
        ->where('tenant_id', $pausedTenant->id)
        ->where('source_crm_id', $vid)
        ->count())->toBe(0);
});

it('end-to-end: lead orphan (no matching projects) — 0 deals, lead stored', function (): void {
    $vid = 999_888_777;

    $response = $this->postJson('/api/webhook/supplier/test-secret-32chars-aaaaaaaaaaaaaa', [
        'vid' => $vid,
        'project' => 'B1_orphan.ru',
        'phone' => '79991234567',
        'time' => time(),
    ]);

    $response->assertStatus(202);

    $lead = SupplierLead::where('vid', $vid)->firstOrFail();
    expect($lead->processed_at)->not->toBeNull();
    expect($lead->deals_created_count)->toBe(0);
    expect($lead->supplier_project_id)->not->toBeNull(); // resolveOrStub stub
});
