<?php

namespace App\Console\Commands;

use App\ScheduledTasks\ScheduledTaskClock;
use Illuminate\Console\Command;
use Illuminate\Support\Carbon;
use Mtc\MercuryDataModels\ScheduledTask;
use Mtc\MercuryDataModels\ScheduledTaskRun;

class MaterialiseScheduledTasks extends Command
{
    /**
     * @var string
     */
    protected $signature = 'scheduled-tasks:materialise {--date= : Materialise for a specific date (Y-m-d), defaults to today}';

    /**
     * @var string
     */
    protected $description = 'Create the pending run rows for every enabled scheduled task due on the day';

    public function handle(ScheduledTaskClock $clock): int
    {
        $date = $this->option('date')
            ? Carbon::createFromFormat('Y-m-d', $this->option('date'))->startOfDay()
            : Carbon::today();

        $created = 0;

        ScheduledTask::query()
            ->enabled()
            ->scheduleTriggered()
            ->each(function (ScheduledTask $task) use ($clock, $date, &$created) {
                $rows = $clock->occurrencesForDate($task, $date)
                    ->map(fn (Carbon $occurrence) => [
                        'scheduled_task_id' => $task->id,
                        'status' => ScheduledTaskRun::STATUS_PENDING,
                        'scheduled_for' => $occurrence,
                        'trigger' => ScheduledTaskRun::TRIGGER_SCHEDULE,
                        'created_at' => Carbon::now(),
                        'updated_at' => Carbon::now(),
                    ])
                    ->toArray();

                if (!empty($rows)) {
                    // The unique key on (task, scheduled_for) makes re-runs no-ops
                    $created += ScheduledTaskRun::query()->insertOrIgnore($rows);
                }

                $task->update(['next_due_at' => $clock->nextDueAt($task, Carbon::now())]);
            });

        $this->info("Materialised {$created} scheduled task runs for {$date->toDateString()}");

        return self::SUCCESS;
    }
}
