<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * Define the application's command schedule.
     */
    protected function schedule(Schedule $schedule): void
    {
        // Shared hosting can't keep `queue:work` running forever as a daemon
        // (the host kills long-lived processes), so a single cron entry runs
        // `schedule:run` every minute, which in turn fires this: process
        // whatever's due, then exit. --max-time keeps it under the next
        // minute's tick. Three workers run in parallel (runInBackground) so
        // a busy queue drains faster than one worker could manage alone;
        // each has its own withoutOverlapping lock so a slow tick just skips
        // that one worker's slot instead of blocking the others.
        for ($worker = 1; $worker <= 3; $worker++) {
            $schedule->command('queue:work --stop-when-empty --tries=3 --max-time=50')
                ->everyMinute()
                ->runInBackground()
                ->withoutOverlapping()
                ->name("queue-worker-{$worker}")
                // withoutOverlapping()'s default mutex is keyed off the raw
                // command string, so identical commands in this loop would
                // all share one lock and only one worker would ever run;
                // override it per-iteration to give each worker its own.
                ->createMutexNameUsing(fn () => "framework/schedule-queue-worker-{$worker}");
        }

        // Fires due recurring email campaigns and advances their schedule.
        // Runs before the queue drain above so newly-dispatched send jobs
        // go out within the same minute rather than waiting for the next tick.
        $schedule->command('campaigns:dispatch-recurring')
            ->everyMinute()
            ->withoutOverlapping();
    }

    /**
     * Register the commands for the application.
     */
    protected function commands(): void
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}
