<?php

declare(strict_types=1);

namespace App\Jobs\Supplier;

use App\Jobs\SyncSupplierProjectJob;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 * Досыл отложенной онлайн-очереди (Task 4.2).
 *
 * Онлайн-правки, попавшие в окно 18:00→00:00 МСК, складываются в supplier_deferred_sync
 * (SyncSupplierProjectJob::handle, Task 4.1). Этот джоб в 00:05 МСК (вне окна) для каждого
 * отложенного проекта диспатчит SyncSupplierProjectJob — тот уже отработает немедленно —
 * и очищает строку. Запускается ПОСЛЕ сброса счётчиков в 00:00.
 *
 * Системная очередь под crm_supplier_worker (BYPASSRLS), как все supplier-flow джобы.
 *
 * Spec: docs/superpowers/specs/2026-06-25-snapshot-source-routing-design.md (Эпик 4).
 */
class FlushDeferredOnlineSyncJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public int $tries = 3;

    public int $backoff = 60;

    public const string DB_CONNECTION = 'pgsql_supplier';

    public function handle(): void
    {
        $projectIds = DB::connection(self::DB_CONNECTION)
            ->table('supplier_deferred_sync')
            ->orderBy('project_id')
            ->pluck('project_id');

        foreach ($projectIds as $projectId) {
            SyncSupplierProjectJob::dispatch((int) $projectId);

            DB::connection(self::DB_CONNECTION)
                ->table('supplier_deferred_sync')
                ->where('project_id', $projectId)
                ->delete();
        }

        if ($projectIds->isNotEmpty()) {
            Log::info('FlushDeferredOnlineSyncJob: flushed '.$projectIds->count().' deferred online sync(s)');
        }
    }
}
