<?php

declare(strict_types=1);

namespace Tests\Support\Imitation;

use Carbon\Carbon;
use Illuminate\Support\Facades\Artisan;

/**
 * Генератор снапшота маршрутизации для имитационного стенда (Phase 1).
 *
 * Делегирует команде `snapshot:rebuild` (DELETE+INSERT, детерминированно):
 *   - activeDate()  — зеркало LeadRouter::activeSnapshotDate(): до 21:00 МСК — сегодня,
 *                     с 21:00 МСК — завтра (§4.2.3 slepok-routing spec).
 *   - rebuild()     — вызывает Artisan::call('snapshot:rebuild', ['--date' => activeDate()])
 *                     для перестройки project_routing_snapshots за активную дату.
 *
 * Механизм выбора (per README §4):
 *   «Для живого портала (Task 14) — `php artisan snapshot:rebuild --date=<activeDate>`
 *    (DELETE+INSERT, детерминированно)».
 *
 * В тестах `rebuild()` вызывается статически ПОСЛЕ создания проекта (фабрика),
 * до вызова LeadRouter. SnapshotRebuildCommand работает через pgsql_supplier
 * (BYPASSRLS crm_supplier_worker) — совместимо с SharesSupplierPdo.
 *
 * activeDate() возвращает строку 'YYYY-MM-DD' — ровно то, что LeadRouter передаёт
 * в SQL WHERE snap.snapshot_date = ?::date.
 *
 * Task 3 — Phase 1 Portal Client Imitation Harness.
 * Spec: docs/superpowers/specs/2026-06-03-portal-client-imitation-phase1-design.md
 */
final class SnapshotForge
{
    /**
     * Активная дата слепка — зеркало LeadRouter::activeSnapshotDate().
     *
     * До 21:00 МСК — сегодня, с 21:00 МСК — завтра (§4.2.3).
     *
     * Возвращает строку 'YYYY-MM-DD' (как LeadRouter передаёт в SQL).
     */
    public static function activeDate(): string
    {
        $msk = Carbon::now('Europe/Moscow');

        return $msk->hour >= 21
            ? $msk->copy()->addDay()->toDateString()
            : $msk->toDateString();
    }

    /**
     * Перестраивает project_routing_snapshots за активную дату из live-проектов.
     *
     * Использует команду `snapshot:rebuild --date=<activeDate>` (DELETE+INSERT),
     * которая отбирает все active + unfrozen проекты с подходящим delivery_days_mask
     * и вставляет строки в project_routing_snapshots.
     *
     * Вызывать ПОСЛЕ создания тестовых проектов (фабрика) — команда читает
     * projects из БД на момент вызова.
     */
    public static function rebuild(): void
    {
        Artisan::call('snapshot:rebuild', [
            '--date' => self::activeDate(),
        ]);
    }
}
