<?php

declare(strict_types=1);

namespace App\Services\Supplier;

use App\Models\Project;

/**
 * DRY-хелперы для группировки Лидерра-проектов по (subject × platform-set).
 *
 * Используется в:
 *   - SyncSupplierProjectJob  (онлайн-режим, один проект)
 *   - SyncSupplierProjectsJob (ночной батч, все проекты)
 *
 * Spec: docs/superpowers/specs/2026-05-20-project-migration-redesign-design.md §4.3
 * Plan: docs/superpowers/plans/2026-05-20-project-migration-redesign-plan-3-export.md Task 6
 */
final class SupplierProjectGrouping
{
    /**
     * Unique identifier key — единая агностическая формула для всех платформ
     * (Stage 4 §4.4.1 R-17, ранее разделялась на platform-specific buildUniqueKey:
     * B3 использовал sender alone, B2 sender+keyword, что создавало orphan
     * supplier_projects при rebalance шеринга — мы не могли сопоставить B2/B3
     * как одну группу):
     *   site/call → signal_identifier
     *   sms+keyword → sender+keyword
     *   sms без keyword → sender
     */
    public static function buildUniqueKeyAgnostic(Project $project): string
    {
        if (in_array($project->signal_type, ['site', 'call'], true)) {
            return (string) $project->signal_identifier;
        }

        $sender = (string) ($project->sms_senders[0] ?? '');
        if ($project->sms_keyword !== null && $project->sms_keyword !== '') {
            return $sender.'+'.$project->sms_keyword;
        }

        return $sender;
    }

    /**
     * Возвращает список uppercase platform-кодов для данного project.
     * Коды соответствуют CHECK constraint: 'B1' / 'B2' / 'B3'.
     *
     * @return list<string>
     */
    public static function resolvePlatforms(Project $project): array
    {
        if (in_array($project->signal_type, ['site', 'call'], true)) {
            return ['B1', 'B2', 'B3'];
        }

        if ($project->signal_type === 'sms') {
            return ($project->sms_keyword !== null && $project->sms_keyword !== '')
                ? ['B2', 'B3']
                : ['B3'];
        }

        return [];
    }

    /**
     * Returns subjects (region codes 1..89) for a project.
     * Empty regions → [null] (one group, "Вся РФ" pool).
     *
     * @return list<int|null>
     */
    public static function subjectsOf(Project $project): array
    {
        $regions = array_values((array) $project->regions);
        if (count($regions) === 0) {
            return [null];
        }

        return array_map(fn ($r) => (int) $r, $regions);
    }
}
