<?php

declare(strict_types=1);

namespace Autogedal\FeedMonitor\Model\Firebear;

use Autogedal\FeedMonitor\Model\JobProviderInterface;
use Firebear\ImportExport\Api\JobRepositoryInterface;
use Magento\Framework\Api\SearchCriteriaBuilder;

/**
 * The Firebear import jobs Firebear schedules itself: active, with a cron expression. Monitored as
 * "firebear_job_<id>"; the interval after which a job counts as not running comes from its cron expression.
 */
class FirebearJobs implements JobProviderInterface
{
    public const SOURCE = 'firebear';

    private const CODE_PREFIX = 'firebear_job_';
    /** Margin over the scheduled interval before "not running" (as the daily custom jobs: 24 h + 2 h). */
    private const MARGIN_MINUTES = 120;

    /** @var array<string, array<string, mixed>>|null */
    private ?array $jobs = null;

    public function __construct(
        private readonly JobRepositoryInterface $jobRepository,
        private readonly SearchCriteriaBuilder $searchCriteriaBuilder,
        private readonly CronInterval $cronInterval
    ) {
    }

    public function getJobs(): array
    {
        if ($this->jobs !== null) {
            return $this->jobs;
        }

        $this->jobs = [];
        $criteria = $this->searchCriteriaBuilder->addFilter('is_active', 1)->create();
        foreach ($this->jobRepository->getList($criteria)->getItems() as $job) {
            $cron = trim((string)$job->getCron());
            if ($cron === '') {
                continue; // not scheduled: only run by hand
            }
            $interval = $this->cronInterval->getMinutes($cron);
            $this->jobs[self::jobCode((int)$job->getId())] = [
                'label' => 'Firebear: ' . $job->getTitle(),
                'max_age_minutes' => $interval === null ? null : $interval + self::MARGIN_MINUTES,
                'log_file' => 'var/log/firebear/' . (int)$job->getId() . '-*.log',
                'source' => self::SOURCE,
            ];
        }

        return $this->jobs;
    }

    public static function jobCode(int $jobId): string
    {
        return self::CODE_PREFIX . $jobId;
    }

    public static function jobId(string $jobCode): ?int
    {
        return str_starts_with($jobCode, self::CODE_PREFIX) ? (int)substr($jobCode, strlen(self::CODE_PREFIX)) : null;
    }
}
