<?php

declare(strict_types=1);

namespace App\Console\Commands;

use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 * Создаёт project_routing_snapshots за указанную дату из текущего live-состояния.
 * Используется один раз при выкатке Этапа 2 + для ручного recovery после падения cron'а.
 *
 * Spec §4.2.6.
 */
final class SnapshotBackfillCommand extends Command
{
    protected $signature = 'snapshot:backfill {--date= : YYYY-MM-DD, по умолчанию сегодня}';

    protected $description = 'Заполнить project_routing_snapshots за указанную дату из live projects';

    public function handle(): int
    {
        $dateStr = (string) ($this->option('date') ?? Carbon::today('Europe/Moscow')->toDateString());
        $date = Carbon::parse($dateStr, 'Europe/Moscow');
        $weekdayBit = 1 << ($date->isoWeekday() - 1);

        $count = DB::connection('pgsql_supplier')->transaction(function () use ($dateStr, $weekdayBit) {
            return DB::connection('pgsql_supplier')->insert(<<<'SQL'
                INSERT INTO project_routing_snapshots (
                    snapshot_date, project_id, tenant_id,
                    daily_limit, delivery_days_mask, regions,
                    signal_type, signal_identifier, sms_senders, sms_keyword,
                    expected_volume
                )
                SELECT
                    ?::date,
                    p.id, p.tenant_id,
                    COALESCE(p.effective_daily_limit_today, p.daily_limit_target),
                    p.delivery_days_mask, p.regions,
                    p.signal_type, p.signal_identifier, p.sms_senders, p.sms_keyword,
                    COALESCE(p.effective_daily_limit_today, p.daily_limit_target)
                FROM projects p
                INNER JOIN tenants t ON t.id = p.tenant_id
                WHERE p.is_active = true
                  AND (p.delivery_days_mask & ?::int) <> 0
                  AND p.preflight_blocked_at IS NULL
                  AND t.frozen_by_balance_at IS NULL
                  AND t.deleted_at IS NULL
                ON CONFLICT (snapshot_date, project_id) DO NOTHING
            SQL, [$dateStr, $weekdayBit]);
        });

        $this->info("Snapshot backfilled for {$dateStr}: {$count} rows.");
        Log::info('snapshot.backfill', ['date' => $dateStr, 'rows' => $count]);

        return self::SUCCESS;
    }
}
