<?php

declare(strict_types=1);

use App\Models\SupplierProject;
use App\Services\SupplierProjects\SupplierProjectResolver;
use Illuminate\Foundation\Testing\DatabaseTransactions;

uses(DatabaseTransactions::class);

test('resolveOrStub returns existing supplier_project for matching (platform, unique_key)', function () {
    $existing = SupplierProject::factory()->create([
        'platform' => 'B1',
        'signal_type' => 'site',
        'unique_key' => 'example.com',
    ]);

    $resolver = new SupplierProjectResolver;
    $resolved = $resolver->resolveOrStub('B1', 'site', 'example.com');

    expect($resolved->id)->toBe($existing->id);
});

test('resolveOrStub creates pending stub when no existing project', function () {
    $resolver = new SupplierProjectResolver;
    $resolved = $resolver->resolveOrStub('B2', 'call', '79991234567');

    expect($resolved->exists)->toBeTrue();
    expect($resolved->platform)->toBe('B2');
    expect($resolved->signal_type)->toBe('call');
    expect($resolved->unique_key)->toBe('79991234567');
    expect($resolved->sync_status)->toBe('pending');
    expect($resolved->current_limit)->toBe(0);
    expect($resolved->current_workdays)->toBe([1, 2, 3, 4, 5, 6, 7]);
});

test('resolveOrStub returns same row on second call (no duplicates)', function () {
    $resolver = new SupplierProjectResolver;
    $first = $resolver->resolveOrStub('B3', 'sms', 'TINKOFF');
    $second = $resolver->resolveOrStub('B3', 'sms', 'TINKOFF');

    expect($first->id)->toBe($second->id);
    expect(SupplierProject::where('unique_key', 'TINKOFF')->count())->toBe(1);
});

test('resolveOrStub throws DomainException for B1+sms (forbidden combo)', function () {
    $resolver = new SupplierProjectResolver;
    expect(fn () => $resolver->resolveOrStub('B1', 'sms', 'TINKOFF'))
        ->toThrow(DomainException::class);
});

test('resolveOrStub throws InvalidArgumentException for invalid platform', function () {
    $resolver = new SupplierProjectResolver;
    expect(fn () => $resolver->resolveOrStub('B9', 'site', 'a.com'))
        ->toThrow(InvalidArgumentException::class);
});

test('resolveOrStub throws InvalidArgumentException for invalid signal_type', function () {
    $resolver = new SupplierProjectResolver;
    expect(fn () => $resolver->resolveOrStub('B1', 'unknown_type', 'a.com'))
        ->toThrow(InvalidArgumentException::class);
});

test('resolveOrStub throws DomainException when unique_key collides across signal_types', function () {
    SupplierProject::factory()->create([
        'platform' => 'B2',
        'signal_type' => 'sms',
        'unique_key' => 'TINKOFF',
    ]);

    $resolver = new SupplierProjectResolver;

    expect(fn () => $resolver->resolveOrStub('B2', 'site', 'TINKOFF'))
        ->toThrow(DomainException::class);
});
