package space.nstart.pcp_tgu_service.config

import org.springframework.boot.context.properties.ConfigurationProperties

/**
 * Настройки планирования и автозапуска процессов по планам.
 */
@ConfigurationProperties(prefix = "planning")
data class PlanningProperties(

    /** За сколько минут до начала плана автоматически запускать Camunda-процесс. */
    val notificationBeforeStartMinutes: Long,

    /** Минимальный разрыв в минутах между стартами соседних планов при расчете цепочки. */
    val targetPlanDurationMinutes: Long,

    /** Допустимое отклонение от целевой длительности плана в минутах. */
    val targetPlanDurationDeltaMinutes: Long,

    /** Включает периодическое обновление пунктов из внешнего API. */
    val externalUpdateEnabled: Boolean,

    /** Горизонт запроса данных по пунктам из внешнего API в днях, начиная от текущего момента. */
    val externalPointsLookaheadDays: Long,

    /** Сколько дней подтвержденной истории планов держать в in-memory выдаче. */
    val inMemoryHistoryDays: Long,

    /** Интервал в миллисекундах между запросами во внешнее API. */
    val externalUpdateFixedDelayMs: Long,

    /** Интервал в миллисекундах между проверками, пора ли автозапускать Camunda-процесс по плану. */
    val notificationCheckFixedDelayMs: Long,

    /** Минимальный запас времени для повторной выдачи после REJECTED. */
    val minReissueLeadMinutes: Long,

    /** Минимальное время на подготовку срочно перевыдаваемого плана (после негатива), в минутах. */
    val reissuePrepMinutes: Long,

    /** TTL lease'а worker job claim в секундах. */
    val workerLockTtlSeconds: Long,

    /**
     * Сколько минут после начала плана ждать решения оператора, прежде чем продолжить цепочку
     * без подтверждения. По истечении план НЕ помечается ACCEPTED — он остаётся WAITING_DECISION,
     * но перестаёт блокировать выдачу следующего плана и становится новым якорем цепочки.
     */
    val waitingDecisionGraceMinutes: Long,

    /**
     * Порог заморозки перед стартом плана для ручной перевыдачи в свой слот (replace).
     * Если до начала плана осталось меньше этого числа минут (now >= startTime - layinFreezeMinutes),
     * план считается невозвратным: заменить его в своём слоте уже нельзя (доступен только fork-forward).
     * Вместе со статусом LAID_IN образует «точку невозврата».
     */
    val layinFreezeMinutes: Long
)
