<?php

/**
 * Skip/Pause Helper Functions
 *
 * Global helper functions for skip renewal and pause subscription features.
 *
 * @package ArraySubs\Functions
 * @since 1.0.0
 */

defined('ABSPATH') || exit;

/**
 * Get SkipManager instance when available.
 *
 * @return object|null
 */
function arraysubs_get_skip_manager()
{
    $class = '\\ArraySubs\\Features\\SkipRenewal\\Services\\SkipManager';

    if (!class_exists($class)) {
        return null;
    }

    return new $class();
}

/**
 * Get PauseManager instance when available.
 *
 * @return object|null
 */
function arraysubs_get_pause_manager()
{
    $class = '\\ArraySubs\\Features\\SkipRenewal\\Services\\PauseManager';

    if (!class_exists($class)) {
        return null;
    }

    return new $class();
}

// =============================================================================
// SKIP RENEWAL FUNCTIONS
// =============================================================================

/**
 * Check if a subscription can skip renewal cycles
 *
 * @param int $subscription_id Subscription post ID
 * @return bool Whether skip is allowed
 */
function arraysubs_can_skip_subscription(int $subscription_id): bool
{
    $manager = arraysubs_get_skip_manager();

    if (!$manager) {
        return false;
    }

    $result = $manager->canSkip($subscription_id);
    return !empty($result['can_skip']);
}

/**
 * Skip renewal cycles for a subscription
 *
 * @param int $subscription_id Subscription post ID
 * @param int $cycles         Number of cycles to skip (default: 1)
 * @param int $user_id        User ID who requested the skip (default: current user or 0)
 * @return bool Whether skip was successful
 */
function arraysubs_skip_subscription(int $subscription_id, int $cycles = 1, int $user_id = null): bool
{
    if ($user_id === null) {
        $user_id = get_current_user_id();
    }

    $manager = arraysubs_get_skip_manager();

    if (!$manager) {
        return false;
    }

    return $manager->skip($subscription_id, $cycles, $user_id);
}

/**
 * Undo skip for a subscription
 *
 * Restores the original next payment date.
 *
 * @param int $subscription_id Subscription post ID
 * @param int $user_id        User ID who is undoing (default: current user or 0)
 * @return bool Whether undo was successful
 */
function arraysubs_undo_skip(int $subscription_id, int $user_id = null): bool
{
    if ($user_id === null) {
        $user_id = get_current_user_id();
    }

    $manager = arraysubs_get_skip_manager();

    if (!$manager) {
        return false;
    }

    return $manager->undoSkip($subscription_id, $user_id);
}

/**
 * Modify an existing skip (change cycle count)
 *
 * @param int $subscription_id Subscription post ID
 * @param int $new_cycles     New number of cycles to skip
 * @param int $user_id        User ID who is modifying (default: current user or 0)
 * @return bool Whether modification was successful
 */
function arraysubs_modify_skip(int $subscription_id, int $new_cycles, int $user_id = null): bool
{
    if ($user_id === null) {
        $user_id = get_current_user_id();
    }

    $manager = arraysubs_get_skip_manager();

    if (!$manager) {
        return false;
    }

    return $manager->modifySkip($subscription_id, $new_cycles, $user_id);
}

/**
 * Get skip status for a subscription
 *
 * @param int $subscription_id Subscription post ID
 * @return array {
 *     @type bool   $is_skipping       Whether currently skipping
 *     @type int    $cycles_total      Total cycles being skipped
 *     @type int    $cycles_remaining  Remaining cycles to skip
 *     @type int    $cycles_completed  Cycles already skipped
 *     @type string $original_date     Original next payment date
 *     @type string $new_date          New next payment date
 *     @type string $requested_at      When skip was requested
 *     @type int    $requested_by      User ID who requested
 * }
 */
function arraysubs_get_skip_status(int $subscription_id): array
{
    $manager = arraysubs_get_skip_manager();

    if (!$manager) {
        return [
            'is_skipping' => false,
            'cycles_total' => 0,
            'cycles_remaining' => 0,
            'cycles_completed' => 0,
            'original_date' => '',
            'new_date' => '',
            'requested_at' => '',
            'requested_by' => 0,
        ];
    }

    return $manager->getSkipStatus($subscription_id);
}

/**
 * Check if a subscription is currently skipping cycles
 *
 * @param int $subscription_id Subscription post ID
 * @return bool Whether subscription is skipping
 */
function arraysubs_is_subscription_skipping(int $subscription_id): bool
{
    $status = arraysubs_get_skip_status($subscription_id);
    return $status['is_skipping'];
}

/**
 * Get remaining skip allowance for a subscription
 *
 * @param int $subscription_id Subscription post ID
 * @return int Number of cycles that can still be skipped
 */
function arraysubs_get_remaining_skip_allowance(int $subscription_id): int
{
    $manager = arraysubs_get_skip_manager();

    if (!$manager) {
        return 0;
    }

    return $manager->getRemainingSkipAllowance($subscription_id);
}

// =============================================================================
// PAUSE SUBSCRIPTION FUNCTIONS
// =============================================================================

/**
 * Check if a subscription can be paused
 *
 * @param int $subscription_id Subscription post ID
 * @return bool Whether pause is allowed
 */
function arraysubs_can_pause_subscription(int $subscription_id): bool
{
    $manager = arraysubs_get_pause_manager();

    if (!$manager) {
        return false;
    }

    $result = $manager->canPause($subscription_id);
    return !empty($result['can_pause']);
}

/**
 * Pause a subscription
 *
 * @param int    $subscription_id Subscription post ID
 * @param int    $days           Pause duration in days
 * @param int    $user_id        User ID who requested (default: current user or 0)
 * @param string $reason         Optional reason for pausing
 * @return bool Whether pause was successful
 */
function arraysubs_pause_subscription(int $subscription_id, int $days, int $user_id = null, string $reason = ''): bool
{
    if ($user_id === null) {
        $user_id = get_current_user_id();
    }

    $manager = arraysubs_get_pause_manager();

    if (!$manager) {
        return false;
    }

    return $manager->pause($subscription_id, $days, $user_id, $reason);
}

/**
 * Resume a paused subscription
 *
 * @param int $subscription_id Subscription post ID
 * @param int $user_id        User ID who is resuming (default: current user or 0)
 * @return bool Whether resume was successful
 */
function arraysubs_resume_subscription(int $subscription_id, int $user_id = null): bool
{
    if ($user_id === null) {
        $user_id = get_current_user_id();
    }

    $manager = arraysubs_get_pause_manager();

    if (!$manager) {
        return false;
    }

    return $manager->resume($subscription_id, $user_id);
}

/**
 * Get pause status for a subscription
 *
 * @param int $subscription_id Subscription post ID
 * @return array {
 *     @type bool   $is_paused        Whether currently paused
 *     @type string $start_date       Pause start date
 *     @type string $end_date         Pause end date
 *     @type int    $duration_days    Planned pause duration
 *     @type int    $days_paused      Actual days paused so far
 *     @type int    $days_remaining   Days until auto-resume
 *     @type int    $pause_count      Total times paused
 *     @type string $reason           Pause reason
 *     @type string $pre_pause_status Status before pause
 *     @type int    $requested_by     User ID who requested
 * }
 */
function arraysubs_get_pause_status(int $subscription_id): array
{
    $manager = arraysubs_get_pause_manager();

    if (!$manager) {
        return [
            'is_paused' => false,
            'start_date' => '',
            'end_date' => '',
            'duration_days' => 0,
            'days_paused' => 0,
            'days_remaining' => 0,
            'pause_count' => 0,
            'reason' => '',
            'pre_pause_status' => '',
            'requested_by' => 0,
        ];
    }

    return $manager->getPauseStatus($subscription_id);
}

/**
 * Check if a subscription is currently paused
 *
 * @param int $subscription_id Subscription post ID
 * @return bool Whether subscription is paused
 */
function arraysubs_is_subscription_paused(int $subscription_id): bool
{
    $status = arraysubs_get_pause_status($subscription_id);
    return $status['is_paused'];
}

/**
 * Get the number of times a subscription has been paused
 *
 * @param int $subscription_id Subscription post ID
 * @return int Pause count
 */
function arraysubs_get_pause_count(int $subscription_id): int
{
    $manager = arraysubs_get_pause_manager();

    if (!$manager) {
        return 0;
    }

    return $manager->getPauseCount($subscription_id);
}

/**
 * Get days since last pause for a subscription
 *
 * @param int $subscription_id Subscription post ID
 * @return int|null Days since last pause or null if never paused
 */
function arraysubs_get_days_since_last_pause(int $subscription_id): ?int
{
    $manager = arraysubs_get_pause_manager();

    if (!$manager) {
        return null;
    }

    return $manager->getTimeSinceLastPause($subscription_id);
}

/**
 * Get remaining pause allowance for a subscription
 *
 * @param int $subscription_id Subscription post ID
 * @return array {
 *     @type bool $can_pause         Whether can pause now
 *     @type int  $remaining_pauses  Number of pauses remaining
 *     @type int  $max_duration_days Maximum pause duration allowed
 * }
 */
function arraysubs_get_remaining_pause_allowance(int $subscription_id): array
{
    $manager = arraysubs_get_pause_manager();

    if (!$manager) {
        return [
            'can_pause' => false,
            'remaining_pauses' => 0,
            'max_duration_days' => 0,
            'reason' => '',
        ];
    }

    $result = $manager->canPause($subscription_id);

    return [
        'can_pause'          => !empty($result['can_pause']),
        'remaining_pauses'   => isset($result['remaining_pauses']) ? (int) $result['remaining_pauses'] : 0,
        'max_duration_days'  => isset($result['max_duration_days']) ? (int) $result['max_duration_days'] : 0,
        'reason'             => isset($result['reason']) ? (string) $result['reason'] : '',
    ];
}
