<?php

namespace Domain\CronJob;

class CronJobType
{
    // Job types
    const APILO_TOKEN_KEEPALIVE = 'apilo_token_keepalive';
    const APILO_SEND_ORDER = 'apilo_send_order';
    const APILO_SYNC_PAYMENT = 'apilo_sync_payment';
    const APILO_SYNC_STATUS = 'apilo_sync_status';
    const APILO_PRODUCT_SYNC = 'apilo_product_sync';
    const APILO_PRICELIST_SYNC = 'apilo_pricelist_sync';
    const APILO_STATUS_POLL = 'apilo_status_poll';
    const PRICE_HISTORY = 'price_history';
    const ORDER_ANALYSIS = 'order_analysis';
    const TRUSTMATE_INVITATION = 'trustmate_invitation';
    const GOOGLE_XML_FEED = 'google_xml_feed';

    // Priorities (lower = more important)
    const PRIORITY_CRITICAL = 10;
    const PRIORITY_SEND_ORDER = 40;  // apilo_send_order musi być PRZED sync payment/status
    const PRIORITY_HIGH = 50;
    const PRIORITY_NORMAL = 100;
    const PRIORITY_LOW = 200;

    // Statuses
    const STATUS_PENDING = 'pending';
    const STATUS_PROCESSING = 'processing';
    const STATUS_COMPLETED = 'completed';
    const STATUS_FAILED = 'failed';
    const STATUS_CANCELLED = 'cancelled';

    // Backoff
    const BASE_BACKOFF_SECONDS = 60;
    const MAX_BACKOFF_SECONDS = 3600;

    /**
     * @return string[]
     */
    public static function allTypes()
    {
        return [
            self::APILO_TOKEN_KEEPALIVE,
            self::APILO_SEND_ORDER,
            self::APILO_SYNC_PAYMENT,
            self::APILO_SYNC_STATUS,
            self::APILO_PRODUCT_SYNC,
            self::APILO_PRICELIST_SYNC,
            self::APILO_STATUS_POLL,
            self::PRICE_HISTORY,
            self::ORDER_ANALYSIS,
            self::TRUSTMATE_INVITATION,
            self::GOOGLE_XML_FEED,
        ];
    }

    /**
     * @return string[]
     */
    public static function allStatuses()
    {
        return [
            self::STATUS_PENDING,
            self::STATUS_PROCESSING,
            self::STATUS_COMPLETED,
            self::STATUS_FAILED,
            self::STATUS_CANCELLED,
        ];
    }

    /**
     * @param int $attempt
     * @return int
     */
    public static function calculateBackoff($attempt)
    {
        $backoff = self::BASE_BACKOFF_SECONDS * pow(2, $attempt - 1);
        return min($backoff, self::MAX_BACKOFF_SECONDS);
    }
}
