<?php

declare(strict_types=1);

namespace KupShop\SynchronizationBundle\Scheduler\Handler;

use KupShop\KupShopBundle\Util\Logging\SentryLogger;
use KupShop\SynchronizationBundle\Scheduler\Message\SynchronizationJobMessage;
use KupShop\SynchronizationBundle\Util\SynchronizationJobProvider;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;

#[AsMessageHandler]
readonly class SynchronizationHandler
{
    public function __construct(
        private SynchronizationJobProvider $provider,
        private SentryLogger $sentryLogger,
    ) {
    }

    public function __invoke(SynchronizationJobMessage $message): void
    {
        $output = new ConsoleOutput();

        if (!($job = $this->provider->getJob($message->jobId))) {
            return;
        }

        if ($job->truthTest && !($job->truthTest)()) {
            return;
        }

        $output->writeln(sprintf('[INFO] Processing job: "%s"...', $job->name));

        $memory_usage_start = memory_get_usage();
        $st = getScriptTime();
        $output->writeln(sprintf('[MEMORY_INFO] Total memory usage: "%s" MB', round($memory_usage_start / (1024 * 1024), 2)));

        try {
            call_user_func($job->fn, $output);

            $output->writeln(sprintf('[INFO] Completed job: "%s"', $job->name));
            $output->writeln(sprintf('[MEMORY_INFO] Memory usage by job: "%s" MB', round((memory_get_usage() - $memory_usage_start) / (1024 * 1024), 2)));
            $output->writeln(sprintf('[SCRIPT_TIME_INFO] Job duration : "%s" s', round(getScriptTime() - $st, 1)));
        } catch (\Throwable $e) {
            if (isDevelopment()) {
                throw $e;
            }

            $this->sentryLogger->captureException($e);

            $output->writeln(sprintf('[INFO] Job "%s" failed: %s', $job->name, $e->getMessage()));
        }
    }
}
