<?php

//As this files autoload from composer.
if ( ! defined( 'ABSPATH' ) ) {
	return;
}

/**
 * Subscription functions.
 *
 * @since 2.6.10
 * @package Masteriyo\Helper
 */

use Masteriyo\Enums\OrderType;
use Masteriyo\Enums\CourseAccessMode;
use Masteriyo\Enums\OrderStatus;
use Masteriyo\PostType\PostType;
use Masteriyo\Pro\Models\Subscription;
use Masteriyo\Models\Order\OrderItemCourse;

/**
 * Get payment retry.
 *
 * @since 2.6.10
 *
 * @param \Masteriyo\Models\PaymentRetry|int $payment_retry
 *
 * @return \Masteriyo\Models\PaymentRetry|null
 */
function masteriyo_get_payment_retry( $payment_retry ) {
	if ( is_a( $payment_retry, Model::class ) ) {
		$id = $payment_retry->get_id();
	} else {
		$id = absint( $payment_retry );
	}

	try {
		$payment_retry_store = masteriyo( 'payment-retry.store' );
		$payment_retry_obj   = masteriyo( 'payment-retry' );
		$payment_retry->set_id( $id );
		$payment_retry_store->read( $payment_retry_obj );
	} catch ( \Exception $e ) {
		$payment_retry_obj = null;
	}

	/**
	 * Filters payment retry object.
	 *
	 * @since 2.6.10
	 *
	 * @param \Masteriyo\Models\PaymentRetry $payment_retry_obj Payment retry object.
	 * @param int|\Masteriyo\Models\PaymentRetry $payment_retry Passed payment retry data.
	 */
	return apply_filters( 'masteriyo_get_payment_retry', $payment_retry_obj, $payment_retry );
}

/**
 * Get subscription.
 *
 * @since 2.6.10
 *
 * @param int|\Masteriyo\Models\Subscription|\WP_Post $subscription Subscription id or Subscription Model or Post.
 *
 * @return \Masteriyo\Models\Subscription|null
 */
function masteriyo_get_subscription( $subscription ) {
	if ( $subscription instanceof Subscription ) {
		$id = $subscription->get_id();
	} elseif ( $subscription instanceof WP_Post ) {
		$id = $subscription->ID;
	} else {
		$id = absint( $subscription );
	}

	try {
		$subscription_store = masteriyo( 'subscription.store' );
		$subscription_obj   = masteriyo( 'subscription' );

		$id = absint( $id );
		$subscription_obj->set_id( $id );
		$subscription_store->read( $subscription_obj );
	} catch ( \Exception $e ) {
		return null;
	}

	/**
	 * Filters subscription object.
	 *
	 * @since 2.6.10
	 *
	 * @param \Masteriyo\Models\Subscription $subscription_obj Subscription object.
	 * @param int|\Masteriyo\Models\Subscription|WP_Post $subscription Subscription id or Subscription Model or Post.
	 */
	return apply_filters( 'masteriyo_get_subscription', $subscription_obj, $subscription );
}

/**
 * Return true if the order contains subscription.
 *
 * @since 2.6.10
 *
 * @param \Masteriyo\Models\Order\Order|\WP_Post|int $order
 * @param array $order_type
 * @return boolean
 */
function masteriyo_order_contains_subscription( $order, $order_type = array( OrderType::PARENT, OrderType::RESUBSCRIBE, OrderType::SWITCH ) ) {
	$order                 = masteriyo_get_order( $order );
	$contains_subscription = false;

	if ( $order ) {
		$type                  = $order->get_type();
		$contains_subscription = $type && in_array( $type, $order_type, true );
	}

	/**
	 * Filters masteriyo order contains subscription.
	 *
	 * @since 2.6.10
	 *
	 * @param boolean $contains_subscription
	 * @param \Masteriyo\Models\Order\Order|null $order
	 * @param array $order_type
	 */
	return apply_filters( 'masteriyo_order_contains_subscription', $contains_subscription, $order, $order_type );
}

/**
 * Return true if it is subscription.
 *
 * @since 2.6.10
 *
 * @param \Masteriyo\Pro\Models\Subscription|\WP_Post|int $subscription
 */
function masteriyo_is_subscription( $subscription ) {
	if ( is_object( $subscription ) && $subscription instanceof Subscription ) {
		$is_subscription = true;
	} else {
		$is_subscription = null !== masteriyo_get_subscription( $subscription );
	}

	/**
	 * Filters subscription is true or not.
	 *
	 * @since 2.6.10
	*/
	return apply_filters( 'masteriyo_is_subscription', $is_subscription, $subscription );
}

/**
 * Return true if the order is a subscription renewal order.
 *
 * @since 2.6.10
 *
 * @param \Masteriyo\Models\Order\Order|\WP_Post|int $order
 * @param array $order_type
 * @return boolean
 */
function masteriyo_order_contains_renewal( $order ) {
	$order      = masteriyo_get_order( $order );
	$is_renewal = false;

	if ( $order ) {
		$type       = $order->get_type();
		$is_renewal = $type && OrderType::RENEWAL === $type;
	}

	/**
	 * Filters masteriyo order contains renewal.
	 *
	 * @since 2.6.10
	 *
	 * @param boolean $is_renewal
	 * @param \Masteriyo\Models\Order\Order|null $order
	 */
	return apply_filters( 'masteriyo_order_contains_renewal', $is_renewal, $order );
}

/**
 * Return true if the $order_id is subscription or subscription related order types.
 *
 * @since 2.6.10
 *
 * @param \Masteriyo\Models\Order\Order|\WP_Post|int $order
 *
 * @return boolean
 */
function masteriyo_has_subscription( $order ) {
	return masteriyo_order_contains_subscription( $order ) || masteriyo_is_subscription( $order ) || masteriyo_order_contains_renewal( $order );
}

/**
 * Return true if the order contains recurring courses.
 *
 * @since 2.6.10
 *
 * @param \Masteriyo\Models\Order\Order|\WP_Post|int $order
 *
 * @return boolean
 */
function masteriyo_order_contains_recurring_courses( $order ) {
	$order                      = masteriyo_get_order( $order );
	$contains_recurring_courses = false;

	foreach ( $order->get_items( 'course' ) as $order_item ) {
		if ( $order_item instanceof OrderItemCourse ) {
			$course                     = masteriyo_get_course( $order_item->get_course_id() );
			$contains_recurring_courses = $course && CourseAccessMode::RECURRING === $course->get_access_mode();
			break;
		}
	}

	/**
	 * Filters order contains recurring course.
	 *
	 * @since 2.6.10
	 *
	 * @param boolean $contains_recurring_courses
	 * @param \Masteriyo\Models\Order\Order|null $order
	 */
	return apply_filters( 'masteriyo_order_contains_recurring_courses', $contains_recurring_courses, $order );
}

/**
 * Get subscription from order.
 *
 * @since 2.6.10
 *
 * @param \Masteriyo\Models\Order\Order|\WP_Post|int $order
 *
 * @return null|\Masteriyo\Pro\Models\Subscription
 */
function masteriyo_get_subscription_from_order( $order ) {
	$order = masteriyo_get_order( $order );
	if ( ! $order ) {
		return null;
	}

	return masteriyo_get_subscription(
		current(
			get_children(
				array(
					'post_type'      => PostType::SUBSCRIPTION,
					'post_parent'    => $order->get_id(),
					'posts_per_page' => 1,
					'fields'         => 'ids',
				)
			)
		)
	);
}

if ( ! function_exists( 'masteriyo_get_pending_and_on_hold_subscriptions_count' ) ) {
	/**
	 * Get the total count of subscriptions with status 'pending' and 'on hold'.
	 *
	 * @since 2.16.0
	 *
	 * @return int The total number of subscriptions with 'pending' and 'on hold' status.
	 */
	function masteriyo_get_pending_and_on_hold_subscriptions_count() {
		$orders_count = (array) wp_count_posts( PostType::SUBSCRIPTION );

		$pending = absint( masteriyo_array_get( $orders_count, OrderStatus::PENDING, 0 ) );
		$on_hold = absint( masteriyo_array_get( $orders_count, OrderStatus::ON_HOLD, 0 ) );

		return $pending + $on_hold;
	}
}
