<?php

namespace KupShop\KupShopBundle\Util\System;

use KupShop\AdminBundle\Util\ActivityLog;
use KupShop\KupShopBundle\Util\Logging\CustomDataExceptionInterface;
use KupShop\KupShopBundle\Util\Logging\SentryLogger;

class AsyncQueue
{
    private array $queue = [];

    /** @var SentryLogger */
    private $sentryLogger;

    /**
     * @required
     */
    public function setSentryLogger(SentryLogger $sentryLogger): void
    {
        $this->sentryLogger = $sentryLogger;
    }

    public function addHandler(callable $callback, string $name = '', ?callable $errorHandler = null): void
    {
        $this->queue[] = [$callback, $name, $errorHandler];
    }

    public function handleAll(): void
    {
        while ($this->handle() === true) {
            // fetching queue
        }
    }

    public function handle(): bool
    {
        if ($handler = array_shift($this->queue)) {
            [$callback, $name, $errorHandler] = $handler;
            if (is_callable($callback)) {
                try {
                    $var = $callback();
                } catch (\Throwable $e) {
                    // use custom error handler instead of generic
                    if ($errorHandler) {
                        $errorHandler($name, $e);

                        return true;
                    }

                    // use generic error handler if error handler is not specified
                    $message = "Chyba při zpracování asynchronní úlohy: {$name}";
                    $data = [];
                    if ($e instanceof CustomDataExceptionInterface) {
                        $data = $e->getData();
                    }

                    addActivityLog(ActivityLog::SEVERITY_ERROR, ActivityLog::TYPE_CHANGE, $message, $data);
                    $this->sentryLogger->captureException($e, $handler);

                    return true;
                }
            }

            return true;
        }

        return false;
    }

    public function isEmpty(): bool
    {
        return count($this->queue) <= 0;
    }
}
