<?php

namespace App;

use App\Appointment\Message\ExpireAppointmentsMessage;
use App\Blog\Message\PublishScheduledBlogsMessage;
use App\Shared\Event\Message\PublishDomainEventsMessage;
use App\Shared\Logging\Message\PruneLogsMessage;
use App\Waitlist\Message\ExpireWaitlistMessage;
use Symfony\Component\Scheduler\Attribute\AsSchedule;
use Symfony\Component\Scheduler\RecurringMessage;
use Symfony\Component\Scheduler\Schedule as SymfonySchedule;
use Symfony\Component\Scheduler\ScheduleProviderInterface;
use Symfony\Contracts\Cache\CacheInterface;

#[AsSchedule]
class Schedule implements ScheduleProviderInterface
{
    public function __construct(
        private CacheInterface $cache,
    ) {
    }

    public function getSchedule(): SymfonySchedule
    {
        return (new SymfonySchedule())
            ->stateful($this->cache) // ensure missed tasks are executed
            ->processOnlyLastMissedRun(true) // ensure only last missed task is run
            ->add(
                RecurringMessage::every('1 minute', new ExpireAppointmentsMessage())
            )
            ->add(
                RecurringMessage::every('1 day', new PruneLogsMessage())
            )
            ->add(
                RecurringMessage::every('1 minute', new PublishScheduledBlogsMessage())
            )
            // صندوق خروجی رویدادها. `stateful` بالا یعنی تیکِ ازدست‌رفته بعد از ری‌استارت
            // جبران می‌شود، و چون خودِ publisher از جدول می‌خواند، یک اجرا کافی است تا
            // هرچه در فاصله جمع شده برود.
            ->add(
                RecurringMessage::every('1 minute', new PublishDomainEventsMessage())
            )
            // انتظارهای مرده — پاکسازیِ نمایش، نه اصلاح رفتار (تطبیق از قبل ردشان می‌کرد).
            ->add(
                RecurringMessage::every('1 day', new ExpireWaitlistMessage())
            );
    }
}
