<?php

namespace classes;

use InvalidArgumentException;

class cron_schedule
{
    public static function normalize(array $schedule): array
    {
        $type = strtolower(trim((string)($schedule['type'] ?? 'interval')));
        if ($type !== 'interval') {
            throw new InvalidArgumentException('Unsupported cron schedule type: ' . $type);
        }

        $seconds = (int)($schedule['seconds'] ?? $schedule['interval'] ?? 0);
        if ($seconds < 30 || $seconds > 2678400) {
            throw new InvalidArgumentException('Cron interval must be between 30 seconds and 31 days.');
        }

        return [
            'type' => 'interval',
            'seconds' => $seconds,
        ];
    }

    public static function nextRunAt(array $schedule, ?string $anchorDateTime, int $now): string
    {
        $normalized = self::normalize($schedule);
        $anchor = $anchorDateTime !== null && trim($anchorDateTime) !== ''
            ? strtotime($anchorDateTime)
            : false;
        $base = $anchor !== false ? (int)$anchor : $now;
        $next = $base + (int)$normalized['seconds'];

        if ($next <= $now) {
            $missed = (int)floor(($now - $next) / (int)$normalized['seconds']) + 1;
            $next += $missed * (int)$normalized['seconds'];
        }

        return date('Y-m-d H:i:s', $next);
    }

    public static function dueAt(array $schedule, ?string $lastRunAt, int $now, ?int $legacyLastRun = null): string
    {
        $normalized = self::normalize($schedule);

        if ($lastRunAt !== null && trim($lastRunAt) !== '') {
            return self::nextRunAt($normalized, $lastRunAt, $now);
        }

        if ($legacyLastRun !== null && $legacyLastRun > 0) {
            return date('Y-m-d H:i:s', $legacyLastRun + (int)$normalized['seconds']);
        }

        return date('Y-m-d H:i:s', $now);
    }
}
