<?php

namespace PortalPeople\virtualstock\jobs;

use Yii;
use yii\base\BaseObject;
use yii\queue\JobInterface;
use PortalPeople\virtualstock\exceptions\ApiException;
use PortalPeople\virtualstock\exceptions\RateLimitException;
use PortalPeople\virtualstock\events\StockUpdatedEvent;
use PortalPeople\virtualstock\Module;
use PortalPeople\virtualstock\services\WebhookService;

/**
 * Queue job that fetches current stock levels for a batch of supplier SKUs.
 *
 * Push via:
 *   Yii::$app->get($module->queueComponent)->push(new UpdateStockLevelJob([
 *       'supplierSkus' => ['SKU-001', 'SKU-002'],
 *   ]));
 *
 * Results are emitted as Yii events on the module so application code
 * can persist or further process them without coupling to a specific ORM.
 *
 * On API failure (rate-limit or transient error) the job re-throws so the
 * queue worker can retry according to its configured retry policy.
 */
class UpdateStockLevelJob extends BaseObject implements JobInterface
{
    /**
     * Supplier product SKUs to check.
     *
     * @var string[]
     */
    public array $supplierSkus = [];

    /**
     * When true the fetched stock data is only logged; nothing else is executed.
     */
    public bool $dryRun = false;

    /**
     * @inheritdoc
     */
    public function execute($queue): void
    {
        if ($this->supplierSkus === []) {
            Yii::info('UpdateStockLevelJob: no SKUs supplied — skipping.', 'virtualstock');
            return;
        }

        /** @var Module|null $module */
        $module = Yii::$app->getModule('virtualstock');

        if ($module === null || !$module->isConfigured()) {
            Yii::warning('UpdateStockLevelJob: module not configured — skipping.', 'virtualstock');
            return;
        }

        $client = $module->createClient();
        $results = [];
        $failed = 0;

        foreach ($this->supplierSkus as $sku) {
            try {
                $stockData = $client->getProductStock($sku);
                $results[$sku] = $stockData;

                Yii::info(sprintf(
                    'UpdateStockLevelJob: %s → qty=%s status=%s%s',
                    $sku,
                    $stockData['quantity'] ?? $stockData['stock_quantity'] ?? '?',
                    $stockData['availability_status'] ?? $stockData['status'] ?? '?',
                    $this->dryRun ? ' [dry-run]' : ''
                ), 'virtualstock');
            } catch (RateLimitException $e) {
                Yii::warning(
                    'UpdateStockLevelJob: rate limit hit on SKU ' . $sku . ' — will retry.',
                    'virtualstock'
                );
                throw $e;
            } catch (ApiException $e) {
                $failed++;
                Yii::error(
                    'UpdateStockLevelJob: API error for SKU ' . $sku . ': ' . $e->getMessage(),
                    'virtualstock'
                );
                $results[$sku] = ['error' => $e->getMessage()];
            }
        }

        if (!$this->dryRun) {
            $event = new StockUpdatedEvent();
            $event->stockResults = $results;
            $event->failedCount = $failed;
            Yii::$app->trigger(WebhookService::EVENT_STOCK_UPDATED, $event);
        }

        Yii::info(sprintf(
            'UpdateStockLevelJob complete: checked=%d failed=%d dryRun=%s',
            count($this->supplierSkus),
            $failed,
            $this->dryRun ? 'yes' : 'no'
        ), 'virtualstock');
    }
}
