<?php

declare(strict_types=1);

namespace App\Jobs\Supplier;

use App\Services\Supplier\PlaywrightBridge;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Cache\LockProvider;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

/**
 * Plan 3 Task 5: real implementation.
 * Запускает PlaywrightBridge (Node.js + headless chromium) для обновления
 * supplier session cookie + CSRF, записывает в Redis с TTL 6h.
 *
 * Triggers:
 *   1. Schedule::hourly()
 *   2. Schedule::dailyAt('20:15') МСК (за 15 мин до supplier sync cron)
 *   3. Inline dispatch_sync() из SupplierPortalClient на 401/403
 *
 * Защита от concurrent refresh — Cache::lock('supplier:session:refresh').
 */
class RefreshSupplierSessionJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $tries = 3;

    /**
     * @return array<int, int>
     */
    public function backoff(): array
    {
        return [120, 600, 1800];  // 2m / 10m / 30m exponential
    }

    public function handle(PlaywrightBridge $bridge): void
    {
        // Lock TTL must exceed PlaywrightBridge::TIMEOUT_SECONDS (75s) to prevent
        // auto-expiry while real chromium boot+login still в процессе → concurrent
        // refresh race. Block timeout slightly higher. Final review I-2 fix.
        /** @var LockProvider $lockStore */
        $lockStore = Cache::store('redis');
        $lockStore->lock('supplier:session:refresh', 90)
            ->block(95, function () use ($bridge) {
                $session = $bridge->refreshSession(
                    login: (string) config('services.supplier.login'),
                    password: (string) config('services.supplier.password'),
                    url: (string) config('services.supplier.portal_url'),
                );

                Cache::store('redis')->put(
                    key: 'supplier:session',
                    value: $session,
                    ttl: now()->addHours(6),
                );

                Log::info('supplier.session.refreshed', ['ttl_hours' => 6]);
            });
    }
}
