<?php

declare(strict_types=1);

namespace apexl\Io\modules\jobs\Service;

use apexl\entityCore\helpers\Condition;
use apexl\Vault\enums\SortDirection;
use apexl\Io\modules\jobs\Entity\QueueJob;
use apexl\Io\modules\jobs\Helper\QueueJobTask;
use apexl\Io\modules\jobs\Interface\QueuedTaskFinderInterface;
use Generator;

class QueuedTaskFinderDb implements QueuedTaskFinderInterface
{
    private const BATCH = 1000;

    public function tasks(?int $limit = 10): Generator
    {
        $job = new QueueJob();

        $i = 0;

        $batch = min($limit, self::BATCH);
        while (true) {

            $offset = $i * $batch;

            if ($offset >= $limit) {
                break;
            }

            $jobs = $job->loadMultiple([
                Condition::isNull('processed'),
                Condition::isNull('failed'),
                Condition::equals('locked', 0),
                // Deferred / scheduled-retry jobs (run_after in the future)
                // are skipped until due. Legacy rows default to 0 = due now.
                Condition::lessThanOrEqual('run_after', time()),
            ], ['sequence', SortDirection::ASC], $batch, $offset);

            if (!count($jobs)) {
                break;
            }

            $i++;

            yield array_map(fn(QueueJob $queueJob): QueueJobTask => new QueueJobTask($queueJob), $jobs);
        }
    }
}
