<?php

declare(strict_types=1);

use App\Models\Project;
use App\Models\SupplierProject;
use App\Models\Tenant;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;

uses(RefreshDatabase::class);

test('Project has signal_type, signal_identifier in fillable', function () {
    $tenant = Tenant::factory()->create();
    DB::statement("SET LOCAL app.current_tenant_id = '{$tenant->id}'");

    $p = Project::factory()->for($tenant)->asSiteSignal('example.com')->create();

    expect($p->signal_type)->toBe('site');
    expect($p->signal_identifier)->toBe('example.com');
});

test('Project casts sms_senders as array + sms_keyword stored', function () {
    $tenant = Tenant::factory()->create();
    DB::statement("SET LOCAL app.current_tenant_id = '{$tenant->id}'");

    $p = Project::factory()
        ->for($tenant)
        ->asSmsSignal(['TINKOFF', 'SBERBANK'], 'ипотека')
        ->create();

    expect($p->fresh()->sms_senders)->toBe(['TINKOFF', 'SBERBANK']);
    expect($p->fresh()->sms_keyword)->toBe('ипотека');
});

test('Project SMS without keyword stores null keyword', function () {
    $tenant = Tenant::factory()->create();
    DB::statement("SET LOCAL app.current_tenant_id = '{$tenant->id}'");

    $p = Project::factory()
        ->for($tenant)
        ->asSmsSignal(['TINKOFF'], null)
        ->create();

    expect($p->fresh()->sms_keyword)->toBeNull();
    expect($p->fresh()->sms_senders)->toBe(['TINKOFF']);
});

test('Project has supplierB1/B2/B3 relations', function () {
    $tenant = Tenant::factory()->create();
    DB::statement("SET LOCAL app.current_tenant_id = '{$tenant->id}'");

    $sp = SupplierProject::factory()->create(['platform' => 'B1']);
    $p = Project::factory()->for($tenant)->create(['supplier_b1_project_id' => $sp->id]);

    expect($p->supplierB1)->toBeInstanceOf(SupplierProject::class);
    expect($p->supplierB1->id)->toBe($sp->id);
    expect($p->supplierB2)->toBeNull();
    expect($p->supplierB3)->toBeNull();
});

test('Project scopeActiveOnDay returns only projects with today bit set in delivery_days_mask', function () {
    $tenant = Tenant::factory()->create();
    DB::statement("SET LOCAL app.current_tenant_id = '{$tenant->id}'");

    // Все 7 дней (битмаска 0b1111111 = 127)
    Project::factory()->for($tenant)->create([
        'is_active' => true,
        'delivery_days_mask' => 0b1111111,
    ]);
    // Только Сб+Вс (биты 5,6 = 0b1100000 = 96)
    Project::factory()->for($tenant)->create([
        'is_active' => true,
        'delivery_days_mask' => 0b1100000,
    ]);
    // Неактивный — не попадает независимо от маски
    Project::factory()->for($tenant)->create([
        'is_active' => false,
        'delivery_days_mask' => 0b1111111,
    ]);

    $todayDow = (int) now()->dayOfWeekIso;

    // Проект на все дни должен пройти на любой день
    $count = Project::activeOnDay($todayDow)->count();
    expect($count)->toBeGreaterThanOrEqual(1);

    // Понедельник (ISO=1, bit 0): проходит только проект на все дни
    expect(Project::activeOnDay(1)->count())->toBe(1);
    // Суббота (ISO=6, bit 5): проходят оба активных
    expect(Project::activeOnDay(6)->count())->toBe(2);
});

test('Project scopeForSignal filters by (signal_type, signal_identifier)', function () {
    $tenant = Tenant::factory()->create();
    DB::statement("SET LOCAL app.current_tenant_id = '{$tenant->id}'");

    Project::factory()->for($tenant)->asSiteSignal('a.com')->create();
    Project::factory()->for($tenant)->asSiteSignal('b.com')->create();
    Project::factory()->for($tenant)->asCallSignal('79991234567')->create();

    expect(Project::forSignal('site', 'a.com')->count())->toBe(1);
    expect(Project::forSignal('site', 'b.com')->count())->toBe(1);
    expect(Project::forSignal('call', '79991234567')->count())->toBe(1);
    expect(Project::forSignal('site', 'nonexistent.com')->count())->toBe(0);
});
