<?php

declare(strict_types=1);

use App\Models\Project;
use App\Models\SupplierProject;
use App\Models\Tenant;
use App\Services\Project\SupplierSnapshotGuard;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Foundation\Testing\DatabaseTransactions;

uses(DatabaseTransactions::class);

it('returns N.21:00 MSK for edit before 18:00 MSK on slepok-sensitive field', function (): void {
    Carbon::setTestNow('2026-05-28 14:00:00', 'Europe/Moscow');

    $tenant = Tenant::factory()->create();
    $project = Project::factory()->for($tenant)->create();
    $sp = SupplierProject::factory()->create();
    linkProjectToSupplier($project, $sp);

    $applies = (new SupplierSnapshotGuard)->appliesFrom($project, 'daily_limit_target');

    expect($applies)->toBeInstanceOf(CarbonImmutable::class);
    expect($applies->format('Y-m-d H:i'))->toBe('2026-05-28 21:00');

    Carbon::setTestNow();
});

it('returns (N+1).21:00 MSK for edit after 18:00 MSK on slepok-sensitive field', function (): void {
    Carbon::setTestNow('2026-05-28 19:00:00', 'Europe/Moscow');

    $tenant = Tenant::factory()->create();
    $project = Project::factory()->for($tenant)->create();
    $sp = SupplierProject::factory()->create();
    linkProjectToSupplier($project, $sp);

    $applies = (new SupplierSnapshotGuard)->appliesFrom($project, 'daily_limit_target');

    expect($applies)->toBeInstanceOf(CarbonImmutable::class);
    expect($applies->format('Y-m-d H:i'))->toBe('2026-05-29 21:00');

    Carbon::setTestNow();
});

it('returns null for non-slepok-sensitive field (e.g. name)', function (): void {
    Carbon::setTestNow('2026-05-28 14:00:00', 'Europe/Moscow');

    $tenant = Tenant::factory()->create();
    $project = Project::factory()->for($tenant)->create();
    $sp = SupplierProject::factory()->create();
    linkProjectToSupplier($project, $sp);

    $applies = (new SupplierSnapshotGuard)->appliesFrom($project, 'name');

    expect($applies)->toBeNull();

    Carbon::setTestNow();
});

it('returns null when project has no pivot links to supplier (no slepok-risk)', function (): void {
    Carbon::setTestNow('2026-05-28 14:00:00', 'Europe/Moscow');

    $tenant = Tenant::factory()->create();
    $project = Project::factory()->for($tenant)->create();
    // НЕТ linkProjectToSupplier — проект не связан с поставщиком.

    $applies = (new SupplierSnapshotGuard)->appliesFrom($project, 'daily_limit_target');

    expect($applies)->toBeNull();

    Carbon::setTestNow();
});

it('covers all 7 slepok-sensitive fields', function (string $field): void {
    Carbon::setTestNow('2026-05-28 14:00:00', 'Europe/Moscow');

    $tenant = Tenant::factory()->create();
    $project = Project::factory()->for($tenant)->create();
    $sp = SupplierProject::factory()->create();
    linkProjectToSupplier($project, $sp);

    $applies = (new SupplierSnapshotGuard)->appliesFrom($project, $field);

    expect($applies)->toBeInstanceOf(CarbonImmutable::class);
    expect($applies->format('Y-m-d H:i'))->toBe('2026-05-28 21:00');

    Carbon::setTestNow();
})->with([
    'is_active',
    'daily_limit_target',
    'delivery_days_mask',
    'regions',
    'signal_identifier',
    'sms_senders',
    'sms_keyword',
]);
