<?php

declare(strict_types=1);

namespace App\Services\Supplier\Dto;

use App\Models\SupplierProject;

/**
 * Read-only DTO для передачи aggregate-состояния supplier_project
 * между SupplierQuotaAllocator и SupplierPortalClient.
 *
 * Spec: docs/superpowers/specs/2026-05-10-supplier-integration-design.md §4.4
 */
final readonly class SupplierProjectDto
{
    /** @var array<int, int> */
    public array $workdays;

    /** @var array<int, int|string> */
    public array $regions;

    /**
     * @param  array<int, int>  $workdays  [1,2,3,4,5,6,7] (Пн..Вс)
     * @param  array<int, int|string>  $regions  массив кодов регионов РФ
     */
    public function __construct(
        public string $platform,           // B1 / B2 / B3
        public string $signalType,         // site / call / sms
        public string $uniqueKey,          // domain / phone / sender+keyword / sender
        public int $limit,                 // daily quota
        array $workdays,
        array $regions,
        public bool $regionsReverse,       // false = include (default), true = exclude
        public string $status,             // active / paused
        public string $tag = '_lidpotok',
        /** @var array<int, string> */
        public array $platforms = [],
    ) {
        // Canonical order for deterministic equals() vs PG jsonb non-deterministic order.
        // sort() reorders in-place AND re-indexes keys 0..N-1 (PHP guarantees list-semantics).
        $sortedWorkdays = $workdays;
        sort($sortedWorkdays, SORT_NUMERIC);
        $this->workdays = $sortedWorkdays;

        $sortedRegions = $regions;
        sort($sortedRegions, SORT_NUMERIC);
        $this->regions = $sortedRegions;
    }

    public static function fromModel(SupplierProject $sp): self
    {
        return new self(
            platform: $sp->platform,
            signalType: $sp->signal_type,
            uniqueKey: $sp->unique_key,
            limit: $sp->current_limit,
            workdays: (array) ($sp->current_workdays ?? []),
            regions: (array) ($sp->current_regions ?? []),
            regionsReverse: false,
            status: $sp->inactive_since === null ? 'active' : 'paused',
        );
    }

    public function equals(self $other): bool
    {
        return $this->platform === $other->platform
            && $this->signalType === $other->signalType
            && $this->uniqueKey === $other->uniqueKey
            && $this->limit === $other->limit
            && $this->workdays === $other->workdays
            && $this->regions === $other->regions
            && $this->regionsReverse === $other->regionsReverse
            && $this->status === $other->status;
    }
}
