<?php

namespace Leantime\Domain\Queue\Services;

use Leantime\Core\Language as LanguageCore;
use Leantime\Core\Mailer as MailerCore;
use Leantime\Domain\Queue\Repositories\Queue as QueueRepository;
use Leantime\Domain\Queue\Workers\DefaultWorker;
use Leantime\Domain\Queue\Workers\EmailWorker;
use Leantime\Domain\Queue\Workers\HttpRequestWorker;
use Leantime\Domain\Queue\Workers\Workers;
use Leantime\Domain\Setting\Repositories\Setting as SettingRepository;
use Leantime\Domain\Users\Repositories\Users as UserRepository;

/**
 * @api
 */
class Queue
{
    private QueueRepository $queue;

    private UserRepository $userRepo;

    private SettingRepository $settingsRepo;

    private MailerCore $mailer;

    private LanguageCore $language;

    public $availableWorkers = ['email', 'httprequest'];

    /**
     * Class constructor.
     *
     * @param  QueueRepository  $queue  The queue repository.
     * @param  UserRepository  $userRepo  The user repository.
     * @param  SettingRepository  $settingsRepo  The settings repository.
     * @param  MailerCore  $mailer  The mailer core.
     * @param  LanguageCore  $language  The language core.
     */
    public function __construct(
        QueueRepository $queue,
        UserRepository $userRepo,
        SettingRepository $settingsRepo,
        MailerCore $mailer,
        LanguageCore $language
    ) {
        // NEW Queuing messaging system
        $this->queue = $queue;

        // We need users and settings and a mailer
        $this->userRepo = $userRepo;
        $this->settingsRepo = $settingsRepo;
        $this->mailer = $mailer;
        $this->language = $language;
    }

    /**
     * Process the queue for a specific worker.
     *
     * @param  Workers  $worker  The worker for which to process the queue.
     * @return bool Returns true if the queue was processed successfully, false otherwise.
     *
     * @api
     */
    public function processQueue(Workers $worker): bool
    {

        $messages = $this->queue->listMessageInQueue($worker);

        if ($worker == Workers::EMAILS) {
            $worker = app()->make(EmailWorker::class);
            $worker->handleQueue($messages);
        }

        if ($worker == Workers::HTTPREQUESTS) {
            $worker = app()->make(HttpRequestWorker::class);
            $worker->handleQueue($messages);
        }

        if ($worker == Workers::DEFAULT) {
            $worker = app()->make(DefaultWorker::class);
            $worker->handleQueue($messages);
        }

        return true;
    }

    public function addToQueue(Workers $channel, string $subject, string $message, $projectId)
    {

        return $this->queue->addMessageToQueue(
            channel: $channel,
            subject: $subject,
            message: $message,
            projectId: $projectId,
            userId: session('userdata.id'));

    }

    public static function addJob(Workers $channel, string $subject, mixed $message, ?int $userId = null, ?int $projectId = null)
    {

        $queue = app()->make(QueueRepository::class);

        return $queue->addMessageToQueue(
            channel: $channel,
            subject: $subject,
            message: serialize($message),
            projectId: $projectId ?? session('currentProject'),
            userId: $userId ?? session('userdata.id')
        );

    }
}
