<?php

declare(strict_types=1);

final class ReminderRules
{
    private CooldownCalculator $cooldownCalculator;

    public function __construct()
    {
        $this->cooldownCalculator = new CooldownCalculator();
    }

    /**
     * بررسی قوانین قطعی
     */
    public function passes(
        array $row,
        ReminderDecision $decision
    ): bool {

        if ($this->isCompleted($row, $decision)) {
            return false;
        }

        if ($this->deadlinePassed($row, $decision)) {
            return false;
        }

        if ($this->maxRemindersReached($row, $decision)) {
            return false;
        }

        if (!$this->cooldownPassed($row, $decision)) {
            return false;
        }

        return true;
    }

    /**
     * ثبت نام تکمیل شده
     */
    private function isCompleted(
        array $row,
        ReminderDecision $decision
    ): bool {

        if (($row['current_step'] ?? '') !== 'completed') {
            return false;
        }

        $decision->deny('registration_completed');

        return true;
    }

    /**
     * ددلاین گذشته
     */
    private function deadlinePassed(
        array $row,
        ReminderDecision $decision
    ): bool {

        if (empty($row['deadline'])) {
            return false;
        }

        if (strtotime($row['deadline']) > time()) {
            return false;
        }

        $decision->deny('deadline_passed');

        return true;
    }

    /**
     * سقف ریمایندر
     */
    private function maxRemindersReached(
        array $row,
        ReminderDecision $decision
    ): bool {

        if ((int)$row['reminder_count'] < 5) {
            return false;
        }

        $decision->deny('max_reminders');

        return true;
    }

    /**
     * بررسی Cooldown
     */
    private function cooldownPassed(
        array $row,
        ReminderDecision $decision
    ): bool {

        $lastActivity = strtotime(
            $row['last_reminder_at']
            ?? $row['step_changed_at']
            ?? $row['created_at']
        );

        if (!$lastActivity) {
            return true;
        }

        $requiredCooldown = $this->cooldownCalculator->calculate(
            $decision,
            $row
        );

        $decision->setNextDelay($requiredCooldown);

        $elapsed = time() - $lastActivity;

        if ($elapsed >= $requiredCooldown) {
            return true;
        }

        $decision->deny('cooldown');

        return false;
    }
}