<?php

declare(strict_types=1);

namespace App\Services\SupplierProjects;

use App\Models\SupplierProject;
use DomainException;
use InvalidArgumentException;

/**
 * Резолвер supplier-проекта по ключу (platform, signal_type, unique_key).
 *
 * Если supplier-проект для этой комбинации уже существует — возвращает его.
 * Если нет — создаёт stub в статусе `pending` (физическая синхронизация
 * с поставщиком произойдёт следующим cron'ом, см. Plan 3 SyncSupplierProjectsJob).
 *
 * Защищает от создания B1+SMS комбинации (chk_supplier_projects_b1_not_for_sms).
 *
 * Spec: docs/superpowers/specs/2026-05-10-supplier-integration-design.md §2.2, §4.1
 */
class SupplierProjectResolver
{
    private const ALLOWED_PLATFORMS = ['B1', 'B2', 'B3', 'DIRECT'];

    private const ALLOWED_SIGNAL_TYPES = ['site', 'call', 'sms'];

    /**
     * @throws InvalidArgumentException — некорректные платформа/тип сигнала.
     * @throws DomainException — комбинация B1+SMS (поставщик не поддерживает).
     */
    public function resolveOrStub(string $platform, string $signalType, string $uniqueKey): SupplierProject
    {
        if (! in_array($platform, self::ALLOWED_PLATFORMS, true)) {
            throw new InvalidArgumentException("Unknown platform: {$platform}");
        }

        if (! in_array($signalType, self::ALLOWED_SIGNAL_TYPES, true)) {
            throw new InvalidArgumentException("Unknown signal_type: {$signalType}");
        }

        if ($platform === 'B1' && $signalType === 'sms') {
            throw new DomainException(
                'B1 platform does not support SMS signals (supplier limitation: chk_supplier_projects_b1_not_for_sms)'
            );
        }

        $resolved = SupplierProject::firstOrCreate(
            ['platform' => $platform, 'unique_key' => $uniqueKey],
            [
                'signal_type' => $signalType,
                'sync_status' => 'pending',
                'current_limit' => 0,
                'current_workdays' => [1, 2, 3, 4, 5, 6, 7],
            ]
        );

        if ($resolved->signal_type !== $signalType) {
            throw new DomainException(
                "Resolved supplier_project ({$platform}, {$uniqueKey}) has signal_type='{$resolved->signal_type}', "
                ."requested signal_type='{$signalType}'. unique_key collision across signal types is not allowed."
            );
        }

        return $resolved;
    }
}
