<?php

declare(strict_types=1);

use App\Jobs\Supplier\SyncSupplierProjectsJob;
use App\Models\Project;
use App\Models\Tenant;
use Carbon\Carbon;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Tests\Concerns\SharesSupplierPdo;

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

/**
 * Helper: вставка snapshot за tomorrow MSK.
 */
function insertTomorrowSnapshot(
    Project $project,
    string $signalType = 'call',
    ?string $signalIdentifier = '79161234567',
    int $dailyLimit = 10,
    int $deliveryDaysMask = 127,
    string $regions = '{}',
): void {
    $tomorrow = Carbon::tomorrow('Europe/Moscow')->toDateString();
    DB::table('project_routing_snapshots')->insert([
        'snapshot_date' => $tomorrow,
        'project_id' => $project->id,
        'tenant_id' => $project->tenant_id,
        'daily_limit' => $dailyLimit,
        'delivery_days_mask' => $deliveryDaysMask,
        'regions' => $regions,
        'signal_type' => $signalType,
        'signal_identifier' => $signalIdentifier,
        'sms_senders' => null,
        'sms_keyword' => null,
        'expected_volume' => $dailyLimit,
        'delivered_count' => 0,
        'created_at' => now(),
    ]);
}

it('reads from snapshot for tomorrow, picks up live-paused project (race 18:02→18:05)', function (): void {
    Carbon::setTestNow('2026-05-27 18:04:00', 'Europe/Moscow');

    $tenant = Tenant::factory()->create(['frozen_by_balance_at' => null]);
    // ↓ Клиент paus'нул проект между 18:02 (snapshot) и 18:05 (sync).
    $project = Project::factory()->for($tenant)->create([
        'is_active' => false, // live state — paused
        'daily_limit_target' => 10,
        'delivery_days_mask' => 127,
    ]);
    insertTomorrowSnapshot($project);

    $projects = (new SyncSupplierProjectsJob)->collectEligibleProjects();

    // Изолируем от leftover dev data в pgsql_supplier (SharesSupplierPdo шарит PDO,
    // но не транзакции — данные между тестами остаются).
    $ours = $projects->where('id', $project->id);
    expect($ours)->toHaveCount(1);

    Carbon::setTestNow();
});

it('skips project that has NO snapshot for tomorrow (live is_active=true ignored)', function (): void {
    Carbon::setTestNow('2026-05-27 18:04:00', 'Europe/Moscow');

    $tenant = Tenant::factory()->create(['frozen_by_balance_at' => null]);
    $project = Project::factory()->for($tenant)->create([
        'is_active' => true, // live state — active
        'daily_limit_target' => 10,
        'delivery_days_mask' => 127,
    ]);
    // НЕТ snapshot за tomorrow — sync должен пропустить.

    $projects = (new SyncSupplierProjectsJob)->collectEligibleProjects();

    $ours = $projects->where('id', $project->id);
    expect($ours)->toHaveCount(0);

    Carbon::setTestNow();
});

it('overrides daily_limit_target / regions / delivery_days_mask with snapshot values', function (): void {
    Carbon::setTestNow('2026-05-27 18:04:00', 'Europe/Moscow');

    $tenant = Tenant::factory()->create(['frozen_by_balance_at' => null]);
    $project = Project::factory()->for($tenant)->create([
        'is_active' => true,
        'daily_limit_target' => 100, // live = 100
        'delivery_days_mask' => 127, // live = mon-sun
    ]);
    // Snapshot имеет другой лимит / маску.
    insertTomorrowSnapshot(
        $project,
        dailyLimit: 7,   // snapshot = 7
        deliveryDaysMask: 31, // mon-fri only
        regions: '{77}', // только Москва
    );

    $projects = (new SyncSupplierProjectsJob)->collectEligibleProjects();

    $ours = $projects->where('id', $project->id);
    expect($ours)->toHaveCount(1);
    $p = $ours->first();
    expect((int) $p->daily_limit_target)->toBe(7);
    expect((int) $p->delivery_days_mask)->toBe(31);
    expect((array) $p->regions)->toBe([77]);

    Carbon::setTestNow();
});

it('skips frozen tenants regardless of snapshot presence', function (): void {
    Carbon::setTestNow('2026-05-27 18:04:00', 'Europe/Moscow');

    $tenant = Tenant::factory()->create(['frozen_by_balance_at' => now()->subDay()]);
    $project = Project::factory()->for($tenant)->create([
        'is_active' => true,
        'daily_limit_target' => 10,
        'delivery_days_mask' => 127,
    ]);
    insertTomorrowSnapshot($project);

    $projects = (new SyncSupplierProjectsJob)->collectEligibleProjects();

    $ours = $projects->where('id', $project->id);
    expect($ours)->toHaveCount(0); // frozen tenant — sync должен пропустить

    Carbon::setTestNow();
});
