<?php
if ( ! function_exists( 'wpj_insert_subscription_purchase_order' ) ) {
	function wpj_insert_subscription_purchase_order( $args = [] ) {
		// User info
		$user_id = ! empty( $args['user_id'] ) ? $args['user_id'] : WPJ_Form::get( 'user_id', get_current_user_id() );

		// Payment info
		$payment_status      = ! empty( $args['payment_status'] ) ? $args['payment_status'] : 'pending';
		$subscription_status = ! empty( $args['subscription_status'] ) ? $args['subscription_status'] : 'inactive';
		$payment_gateway     = ! empty( $args['payment_gateway'] ) ? $args['payment_gateway'] : WPJ_Form::get( 'pay_for_item' );

		// Date info
		$addon_date = ! empty( $args['addon_date'] ) ? $args['addon_date'] : current_time( 'timestamp', 1 );

		// Currency
		$currency = ! empty( $args['currency'] ) ? $args['currency'] : apply_filters( 'wpjobster_take_allowed_currency_' . $payment_gateway, '' );

		if ( empty( $currency ) ) $currency = wpj_get_site_currency();

		// Subscription info
		$plan  = ! empty( $args['plan'] ) ? $args['plan'] : WPJ_Form::get( 'sub_type' );
		$level = ! empty( $args['level'] ) ? $args['level'] : WPJ_Form::get( 'sub_level' );

		// Subscription amount
		$subscription_amount = ! empty( $args['amount'] ) ? $args['amount'] : WPJ_Form::request( 'sub_amount' );
		$subscription_amount_exchanged = wpj_number_format_special_exchange( $subscription_amount, 2, $currency );

		// Buyer Fee
		$processing_fees = ! empty( $args['processing_fees'] ) ? $args['processing_fees'] : 0;

		if ( ! is_numeric( $processing_fees ) )
			$processing_fees = wpj_get_site_processing_fee_by_amount( $subscription_amount, 0, 0 );

		$processing_fees_exchanged = wpj_number_format_special_exchange( $processing_fees, '1', $currency );

		// Tax
		$tax = ! empty( $args['tax'] ) ? $args['tax'] : 0;

		if ( ! is_numeric( $tax ) )
			$tax = wpj_get_site_tax_by_amount( $subscription_amount, 0, 0, $processing_fees );

		$tax_exchanged = wpj_number_format_special_exchange( $tax, '1', $currency );

		// Final order price
		$payable_amount = ! empty( $args['payable_amount'] ) ? $args['payable_amount'] : '';

		if ( ! $payable_amount )
			$payable_amount = $subscription_amount + $tax + $processing_fees;

		$payable_amount_exchanged = $subscription_amount_exchanged + $processing_fees_exchanged + $tax_exchanged;

		// Insert order to database
		$orderid = wpj_insert_subscription_order(
			[
				'user_id'              => $user_id,
				'amount'               => $subscription_amount,
				'payment_status'       => $payment_status,
				'subscription_status'  => $subscription_status,
				'addon_date'           => $addon_date,
				'mc_currency'          => $currency,
				'plan'                 => $plan,
				'level'                => $level,
				'payment_gateway_name' => $payment_gateway,
				'payable_amount'       => $payable_amount_exchanged,
				'tax'                  => $tax
			],
			['%d', '%f', '%s', '%s', '%d', '%s', '%s', '%s', '%s', '%f', '%f']
		);

		do_action( 'wpj_after_insert_subscription_order', $orderid );

		// Insert payment to database
		wpj_insert_payment(
			[
				'payment_status'         => $payment_status == 'completed' ? 1 : 0,
				'payment_gateway'        => $payment_gateway,
				'payment_type'           => 'subscription',
				'payment_type_id'        => $orderid,
				'fees'                   => $processing_fees,
				'amount'                 => $payable_amount,
				'datemade'               => current_time( 'timestamp', 1 ),
				'tax'                    => $tax,
				'currency'               => wpj_get_site_default_currency(),
				'final_amount'           => $payable_amount,
				'final_amount_exchanged' => $payable_amount_exchanged,
				'final_amount_currency'  => $currency,
			],
			['%d', '%s', '%s', '%d', '%f', '%f', '%d', '%f', '%s', '%f', '%f', '%s']
		);

		return $orderid;
	}
}

if ( ! function_exists( 'wpj_activate_subscription_order' ) ) {
	function wpj_activate_subscription_order( $order_id ) {
		// Get subscription order
		$subscription_order = wpj_get_subscription_order( '*', ['id' => $order_id], 'row' );

		// Get user info
		$uid = $subscription_order->user_id;
		if ( ! $uid ) $uid = get_current_user_id();

		// Get active subscription
		$active_subscription = wpj_get_subscription_by_uid( $uid );

		// Currency
		$currency = $subscription_order->mc_currency;

		// Subscription details
		$subscription_name = WPJ_Form::get( 'sub_id', $subscription_order->plan . '-' . $subscription_order->level );
		$subscription_arr  = explode( '-', $subscription_name );

		// Subscription type
		$sub_type  = $subscription_arr[0];

		// Subscription level
		$sub_level = $subscription_arr[1];

		if ( WPJ_Form::request( 'schedule_only' ) == '1' ) { // Subscription schedule
			$last_sub_amount = wpj_get_option( 'wpjobster_subscription_' . $active_subscription->subscription_type . '_amount_' . $active_subscription->subscription_level );
			$sub_amount      = wpj_get_option( 'wpjobster_subscription_' . $sub_type . '_amount_' . $sub_level );

			$payable_amount  = $sub_amount - $last_sub_amount;
			if ( $last_sub_amount > $sub_amount ) $payable_amount = 0;

			// Update subscription info
			wpj_update_active_subscription(
				[
					'next_subscription_level'  => $sub_level,
					'next_subscription_type'   => $sub_type,
					'next_subscription_amount' => wpj_get_option( 'wpjobster_subscription_' . $sub_type . '_amount_' . $sub_level )
				],
				['user_id' => $uid]
			);

			// Update subscription order
			wpj_update_subscription_order(
				['amount' => $payable_amount, 'payable_amount' => $payable_amount],
				['id' => $order_id]
			);

			// Update old subscription
			wpj_update_subscription_order(
				['payment_status' => 'cancelled', 'subscription_status' => 'inactive'],
				['id' => wpj_get_subscription_order( 'id', ['user_id' => $uid, 'subscription_status' => 'active'], 'var' )]
			);

			// Update payment
			wpj_update_payment(
				[
					'amount'                 => $payable_amount,
					'final_amount'           => $payable_amount,
					'final_amount_exchanged' => wpj_number_format_special_exchange( $payable_amount, 1, $currency ),
					'final_amount_currency'  => $currency
				],
				[
					'payment_type_id' => $order_id,
					'payment_type'    => 'subscription'
				]
			);

			$email_reason = 'subscription_schedule';

		} elseif ( is_object( $active_subscription ) ) { // Subscription upgrade
			do_action( 'wpj_before_subscription_activation', 'upgrade', $order_id, $sub_type, $sub_level );

			$last_sub_amount = wpj_get_option( 'wpjobster_subscription_' . $active_subscription->subscription_type . '_amount_' . $active_subscription->subscription_level );
			$payable_amount  = wpj_get_option( 'wpjobster_subscription_' . $sub_type . '_amount_' . $sub_level ) - $last_sub_amount;

			// Update subscription info
			wpj_update_active_subscription(
				[
					'subscription_level'       => $sub_level,
					'subscription_type'        => $sub_type,
					'subscription_status'      => 'active',
					'subscription_amount'      => wpj_get_option( 'wpjobster_subscription_' . $sub_type . '_amount_' . $sub_level ),
					'next_subscription_level'  => $sub_level,
					'next_subscription_type'   => $sub_type,
					'next_subscription_amount' => wpj_get_option( 'wpjobster_subscription_' . $sub_type . '_amount_' . $sub_level ),
					'next_billing_date'        => wpj_get_subscription_next_billing_date( $sub_type ),
				],
				['user_id' => $uid]
			);

			// Update old subscription
			wpj_update_subscription_order(
				[
					'payment_status'      => 'cancelled',
					'subscription_status' => 'inactive',
				],
				['id' => wpj_get_subscription_order( 'id', ['user_id' => $uid, 'subscription_status' => 'active'], 'var' )]
			);

			// Save log
			wpj_add_history_log([
				'tp'        => '0',
				'reason'    => __( 'Payment for changing subscription', 'wpjobster' ),
				'amount'    => $payable_amount,
				'uid'       => $uid,
				'oid'       => $order_id,
				'rid'       => 11,
				'details'   => $sub_type . '_' . $sub_level . '_change',
				'payed_amt' => $currency . '|' . wpj_number_format_special_exchange( $payable_amount, 1, $currency )
			]);

			// Send email to admin
			wpj_notify_user_translated( 'admin_upgrade_subscription', 'admin', [
				'##username##'                    => wpj_get_user_display_type( $uid ),
				'##current_subscription_level##'  => wpj_translate_string( $sub_level ),
				'##current_subscription_period##' => wpj_translate_string( $sub_type ),
				'##current_subscription_amount##' => wpj_get_option( 'wpjobster_subscription_' . $active_subscription->subscription_type . '_amount_' . $sub_level ),
				'##next_subscription_amount##'    => wpj_get_option( 'wpjobster_subscription_' . $sub_type . '_amount_' . $sub_level ),
				'##next_subscription_level##'     => wpj_translate_string( $sub_level ),
				'##next_billing_date##'           => wpj_get_subscription_next_billing_date( $sub_type ),
				'##amount_updated##'              => wpj_number_format_special_exchange( $payable_amount, 1, $currency )
			]);

			$email_reason = 'balance_down_subscription_change';

		} else { // New subscription
			do_action( 'wpj_before_subscription_activation', 'new', $order_id, $sub_type, $sub_level );

			$payable_amount = wpj_get_option( 'wpjobster_subscription_' . $sub_type . '_amount_' . $sub_level );

			// Insert subscription to database and activate
			if ( ! is_object( wpj_get_subscription_by_uid( get_current_user_id() ) ) ) {
				wpj_insert_active_subscription(
					[
						'subscription_level'       => $sub_level,
						'sub_start_date'           => current_time( 'timestamp', 1 ),
						'subscription_type'        => $sub_type,
						'subscription_amount'      => $payable_amount,
						'user_id'                  => $uid,
						'subscription_status'      => 'active',
						'next_billing_date'        => wpj_get_subscription_next_billing_date( $sub_type ),
						'next_subscription_level'  => $sub_level,
						'next_subscription_type'   => $sub_type,
						'next_subscription_amount' => wpj_get_option( 'wpjobster_subscription_' . $sub_type . '_amount_' . $sub_level )
					],
					['%s', '%d', '%s', '%f', '%d', '%s', '%d', '%s', '%s', '%f']
				);
			}

			// Save log
			wpj_add_history_log([
				'tp'        => '0',
				'reason'    => __( 'Payment for subscription', 'wpjobster' ),
				'amount'    => $payable_amount,
				'uid'       => $uid,
				'oid'       => $order_id,
				'rid'       => 11,
				'details'   => $sub_type . '_' . $sub_level . '_new',
				'payed_amt' => $currency . '|' . wpj_number_format_special_exchange( $payable_amount, 1, $currency )
			]);

			// Send email to admin
			wpj_notify_user_translated( 'admin_new_subscription', 'admin', [
				'##amount_updated##'              => wpj_number_format_special_exchange( $payable_amount, 1, $currency ),
				'##username##'                    => wpj_get_user_display_type( $uid ),
				'##current_subscription_level##'  => wpj_translate_string( $sub_level ),
				'##current_subscription_period##' => wpj_translate_string( $sub_type ),
				'##current_subscription_amount##' => $payable_amount,
				'##next_subscription_level##'     => wpj_translate_string( $sub_level ),
				'##next_subscription_type##'      => wpj_translate_string( $sub_type ),
				'##next_subscription_amount##'    => wpj_get_option( 'wpjobster_subscription_' . $sub_type . '_amount_' . $sub_level ),
				'##next_billing_date##'           => wpj_get_subscription_next_billing_date( $sub_type )
			]);

			$email_reason = 'balance_down_subscription';

		}

		// Decrease credits if payment method is Account Balance
		if ( $subscription_order->payment_gateway_name == 'credits' ) {
			$user_credit = wpj_get_user_credit( $uid );

			if ( $payable_amount > 0 && $payable_amount > $user_credit ) {
				wp_redirect( wpj_get_payment_link() . 'topup?no_credits=1' ); exit;
			}

			wpj_update_user_credit( $uid, $user_credit - $payable_amount );
		}

		// Send emails
		wpj_notify_user_translated( $email_reason, $uid, [
			'##amount_updated##'              => wpj_number_format_special_exchange( $payable_amount, 1, $currency ),
			'##username##'                    => wpj_get_user_display_type( $uid ),
			'##current_subscription_level##'  => wpj_translate_string( $sub_level ),
			'##current_subscription_period##' => wpj_translate_string( $sub_type ),
			'##current_subscription_amount##' => $payable_amount,
			"##next_subscription_level##"     => wpj_translate_string( $sub_level ),
			"##next_subscription_type##"      => wpj_translate_string( $sub_type ),
			"##next_subscription_amount##"    => wpj_get_option( 'wpjobster_subscription_' . $sub_type . '_amount_' . $sub_level ),
			"##next_billing_date##"           => wpj_get_subscription_next_billing_date( $sub_type )
		]);

		// Checks
		wpj_do_user_level_extras_check( $uid );
		wpj_do_user_level_extras_price_check( $uid );
		wpj_do_user_level_job_price_check( $uid );
	}
}

if ( ! function_exists( 'wpj_get_subscription_by_uid' ) ) {
	function wpj_get_subscription_by_uid( $uid = '' ) {
		if ( ! $uid ) $uid = get_current_user_id();

		$current_subscription = wpj_get_active_subscription( '*', ['user_id' => $uid], 'row' );

		if ( is_object( $current_subscription ) ) {
			$current_subscription->next_billing_date = wpj_date( wpj_get_option( 'date_format' ), $current_subscription->next_billing_date );
			$current_subscription->sub_start_date    = wpj_date( wpj_get_option( 'date_format' ), $current_subscription->sub_start_date );
		}

		return $current_subscription ? $current_subscription : false;
	}
}

if ( ! function_exists( 'wpj_get_subscription_info' ) ) {
	function wpj_get_subscription_info( $uid = '', $return = '' ) {
		if ( ! $uid ) $uid = get_current_user_id();

		$info = [];

		$info['wpjobster_subscription_enabled'] = wpj_get_option( 'wpjobster_subscription_enabled' );

		if ( $info['wpjobster_subscription_enabled'] == 'yes' ) {
			$current_subscription = wpj_get_subscription_by_uid( $uid );

			$info['wpjobster_subscription_eligibility_enabled'] = wpj_get_option( 'wpjobster_subscription_eligibility_enabled' );

			if ( $current_subscription ) {
				if ( $current_subscription->subscription_status == 'cancelled' ) {
					$info['wpjobster_subscription_type']        = '';
					$info['wpjobster_subscription_level']       = 'level0';
					$info['wpjobster_subscription_amount']      = '0';
					$info['wpjobster_subscription_eligibility'] = false;
					$info['wpjobster_subscription_status']      = 'cancelled';
					$info['wpjobster_subscription_type_old']    = $current_subscription->subscription_type;
					$info['wpjobster_subscription_level_old']   = $current_subscription->subscription_level;
					$info['wpjobster_subscription_old']         = $current_subscription;

				} else {
					$info['wpjobster_subscription_status'] = 'active';
					$info['wpjobster_subscription_type']   = $current_subscription->subscription_type;
					$info['wpjobster_subscription_level']  = $current_subscription->subscription_level;
					$info['wpjobster_subscription_amount'] = wpj_get_option( 'wpjobster_subscription_' . $info['wpjobster_subscription_type'] . '_amount_' . $info['wpjobster_subscription_level'] );

					if ( $info['wpjobster_subscription_eligibility_enabled'] == 'yes' ) {
						$info['wpjobster_subscription_eligibility'] = wpj_get_option( 'wpjobster_subscription_eligibility_amount_' . $info['wpjobster_subscription_level'] );

					} else {
						$info['wpjobster_subscription_eligibility'] = false;

					}

				}

			} else {
				$info['wpjobster_subscription_status']      = 'new';
				$info['wpjobster_subscription_type']        = '';
				$info['wpjobster_subscription_level']       = 'level0';
				$info['wpjobster_subscription_amount']      = '0';
				$info['wpjobster_subscription_eligibility'] = false;

			}

			$info['wpjobster_subscription_profile_label_enabled'] = wpj_get_option( 'wpjobster_subscription_profile_label_enabled' );

			if ( $info['wpjobster_subscription_profile_label_enabled'] == 'yes' ) {
				$info['wpjobster_subscription_profile_label'] = wpj_get_option( 'wpjobster_subscription_profile_label_' . $info['wpjobster_subscription_level'] );

			} else {
				$info['wpjobster_subscription_profile_label'] = false;

			}

			$info['wpjobster_subscription_icon_url_enabled'] = wpj_get_option( 'wpjobster_subscription_icon_url_enabled' );

			if ( $info['wpjobster_subscription_icon_url_enabled'] == 'yes' ) {
				$info['wpjobster_subscription_icon_url'] = wpj_get_option( 'wpjobster_subscription_icon_url_' . $info['wpjobster_subscription_level'] );

			} else {
				$info['wpjobster_subscription_icon_url'] = false;

			}

			$info['wpjobster_subscription_min_extra_price_enabled'] = wpj_get_option( 'wpjobster_subscription_min_extra_price_enabled' );

			if ( $info['wpjobster_subscription_min_extra_price_enabled'] == 'yes' ) {
				$info['wpjobster_subscription_min_extra_price'] = wpj_get_option( 'wpj_job_extra_price_limits_subscription_' . $info['wpjobster_subscription_level'] )[1];

			} else {
				$info['wpjobster_subscription_min_extra_price'] = false;

			}

			$info['wpjobster_subscription_max_extra_price_enabled'] = wpj_get_option( 'wpjobster_subscription_max_extra_price_enabled' );

			if ( $info['wpjobster_subscription_max_extra_price_enabled'] == 'yes' ) {
				$info['wpjobster_subscription_max_extra_price'] = wpj_get_option( 'wpj_job_extra_price_limits_subscription_' . $info['wpjobster_subscription_level'] )[2];

			} else {
				$info['wpjobster_subscription_max_extra_price'] = false;

			}

			$info['wpjobster_subscription_min_job_price_enabled'] = wpj_get_option( 'wpjobster_subscription_min_job_price_enabled' );

			if ( $info['wpjobster_subscription_min_job_price_enabled'] == 'yes' ) {
				$info['wpjobster_subscription_min_job_price'] = wpj_get_option( 'wpj_job_price_limits_subscription_' . $info['wpjobster_subscription_level'] )[1];

			} else {
				$info['wpjobster_subscription_min_job_price'] = false;

			}

			$info['wpjobster_subscription_max_job_price_enabled'] = wpj_get_option( 'wpjobster_subscription_max_job_price_enabled' );

			if ( $info['wpjobster_subscription_max_job_price_enabled'] == 'yes' ) {
				$info['wpjobster_subscription_max_job_price'] = wpj_get_option( 'wpj_job_price_limits_subscription_' . $info['wpjobster_subscription_level'] )[2];

			} else {
				$info['wpjobster_subscription_max_job_price'] = false;

			}

			$info['wpjobster_subscription_min_custom_extras_enabled'] = wpj_get_option( 'wpjobster_subscription_min_custom_extras_enabled' );

			if ( $info['wpjobster_subscription_min_custom_extras_enabled'] == 'yes' ) {
				$info['wpjobster_subscription_min_custom_extras'] = wpj_get_option( 'wpj_custom_extra_price_limits_subscription_' . $info['wpjobster_subscription_level'] )[1];
			} else {
				$info['wpjobster_subscription_min_custom_extras'] = false;
			}

			$info['wpjobster_subscription_custom_extras_enabled'] = wpj_get_option( 'wpjobster_subscription_custom_extras_enabled' );

			if ( $info['wpjobster_subscription_custom_extras_enabled'] == 'yes' ) {
				$info['wpjobster_subscription_max_custom_extras'] = wpj_get_option( 'wpj_custom_extra_price_limits_subscription_' . $info['wpjobster_subscription_level'] )[2];

			} else {
				$info['wpjobster_subscription_max_custom_extras'] = false;

			}

			$info['wpjobster_fees_for_subscriber_enabled'] = wpj_get_option( 'wpjobster_fees_for_subscriber_enabled' );

			if ( $info['wpjobster_fees_for_subscriber_enabled'] == 'yes' ) {
				$info['wpjobster_subscription_fees'] = wpj_get_option( 'wpjobster_subscription_fees_' . $info['wpjobster_subscription_level'] );

			} else {
				$info['wpjobster_subscription_fees'] = false;

			}

			$info['wpjobster_subscription_noof_extras_enabled'] = wpj_get_option( 'wpjobster_subscription_noof_extras_enabled' );

			if ( $info['wpjobster_subscription_noof_extras_enabled'] == 'yes' ) {
				$info['wpjobster_subscription_noof_extras'] = wpj_get_option( 'wpjobster_subscription_noof_extras_' . $info['wpjobster_subscription_level'] );

			} else {
				$info['wpjobster_subscription_noof_extras'] = false;

			}

			$info['wpjobster_subscription_ex_fast_delivery_enabled'] = wpj_get_option( 'wpjobster_subscription_ex_fast_delivery_enabled' );

			if ( $info['wpjobster_subscription_ex_fast_delivery_enabled'] == 'yes' ) {
				$info['wpjobster_subscription_ex_fast_delivery'] = 'yes';

			} else {
				$info['wpjobster_subscription_ex_fast_delivery'] = false;

			}

			$info['wpjobster_subscription_additional_revision_enabled'] = wpj_get_option( 'wpjobster_subscription_additional_revision_enabled' );

			if ( $info['wpjobster_subscription_additional_revision_enabled'] == 'yes' ) {
				$info['wpjobster_subscription_additional_revision'] = 'yes';

			} else {
				$info['wpjobster_subscription_additional_revision'] = false;

			}

			$info['wpjobster_subscription_job_multiples_enabled'] = wpj_get_option( 'wpjobster_subscription_job_multiples_enabled' );

			if ( $info['wpjobster_subscription_job_multiples_enabled'] == 'yes' ) {
				$info['wpjobster_subscription_job_multiples'] = wpj_get_option( 'wpjobster_subscription_job_multiples_' . $info['wpjobster_subscription_level'] );

			} else {
				$info['wpjobster_subscription_job_multiples'] = false;

			}

			$info['wpjobster_subscription_extra_multiples_enabled'] = wpj_get_option( 'wpjobster_subscription_extra_multiples_enabled' );

			if ( $info['wpjobster_subscription_extra_multiples_enabled'] == 'yes' ) {
				$info['wpjobster_subscription_extra_multiples'] = wpj_get_option( 'wpjobster_subscription_extra_multiples_' . $info['wpjobster_subscription_level'] );

			} else {
				$info['wpjobster_subscription_extra_multiples'] = false;

			}

			$info['wpjobster_subscription_video_multiples_enabled'] = wpj_get_option( 'wpjobster_subscription_video_multiples_enabled' );

			if ( $info['wpjobster_subscription_video_multiples_enabled'] == 'yes' ) {
				$info['wpjobster_subscription_video_multiples'] = wpj_get_option( 'wpjobster_subscription_video_multiples_' . $info['wpjobster_subscription_level'] );

			} else {
				$info['wpjobster_subscription_video_multiples'] = false;

			}

		} else {
			$info['wpjobster_subscription_type']                = false;
			$info['wpjobster_subscription_level']               = false;
			$info['wpjobster_subscription_amount']              = false;
			$info['wpjobster_subscription_eligibility']         = false;
			$info['wpjobster_subscription_noof_extras']         = false;
			$info['wpjobster_subscription_ex_fast_delivery']    = false;
			$info['wpjobster_subscription_additional_revision'] = false;
			$info['wpjobster_subscription_job_multiples']       = false;
			$info['wpjobster_subscription_extra_multiples']     = false;
			$info['wpjobster_subscription_max_extra_price']     = false;
			$info['wpjobster_subscription_fees']                = false;
			$info['wpjobster_subscription_profile_label']       = false;
			$info['wpjobster_subscription_icon_url']            = false;
			$info['wpjobster_subscription_max_job_price']       = false;
			$info['wpjobster_subscription_max_custom_extras']   = false;

		}

		if ( $return && isset( $info[$return] ) ) {
			return $info[$return];
		}

		return $info;
	}
}

if ( ! function_exists( 'wpj_get_subscription_levels_info' ) ) {
	function wpj_get_subscription_levels_info() {
		$subscription_arr = [];

		$subscription_levels = [
			'level0' => sprintf( __( 'Level %d', 'wpjobster' ), 0 ),
			'level1' => sprintf( __( 'Level %d', 'wpjobster' ), 1 ),
			'level2' => sprintf( __( 'Level %d', 'wpjobster' ), 2 ),
			'level3' => sprintf( __( 'Level %d', 'wpjobster' ), 3 )
		];

		foreach ( $subscription_levels as $key => $value ) {
			$subscription_arr[$key]['weekly']           = wpj_get_option( 'wpjobster_subscription_weekly_amount_' . $key );
			$subscription_arr[$key]['monthly']          = wpj_get_option( 'wpjobster_subscription_monthly_amount_' . $key );
			$subscription_arr[$key]['quarterly']        = wpj_get_option( 'wpjobster_subscription_quarterly_amount_' . $key );
			$subscription_arr[$key]['yearly']           = wpj_get_option( 'wpjobster_subscription_yearly_amount_' . $key );
			$subscription_arr[$key]['lifetime']         = wpj_get_option( 'wpjobster_subscription_lifetime_amount_' . $key );
			$subscription_arr[$key]['eligility']        = wpj_get_option( 'wpjobster_subscription_eligibility_amount_' . $key );
			$subscription_arr[$key]['fees']             = wpj_get_option( 'wpjobster_subscription_fees_' . $key );
			$subscription_arr[$key]['profile_label']    = wpj_get_option( 'wpjobster_subscription_profile_label_' . $key );
			$subscription_arr[$key]['icon_url']         = wpj_get_option( 'wpjobster_subscription_icon_url_' . $key );
			$subscription_arr[$key]['noof_extras']      = wpj_get_option( 'wpjobster_subscription_noof_extras_' . $key );
			$subscription_arr[$key]['noof_efd']         = wpj_get_option( 'wpjobster_subscription_fast_del_multiples_' . $key );
			$subscription_arr[$key]['noof_ar']          = wpj_get_option( 'wpjobster_subscription_add_rev_multiples_' . $key );
			$subscription_arr[$key]['noof_active_jobs'] = wpj_get_option( 'wpjobster_subscription_active_jobs_' . $key );
			$subscription_arr[$key]['noof_job_m']       = wpj_get_option( 'wpjobster_subscription_job_multiples_' . $key );
			$subscription_arr[$key]['noof_extra_m']     = wpj_get_option( 'wpjobster_subscription_extra_multiples_' . $key );
			$subscription_arr[$key]['noof_video_m']     = wpj_get_option( 'wpjobster_subscription_video_multiples_' . $key );
			$subscription_arr[$key]['min_ce_price']     = wpj_get_option( 'wpj_custom_extra_price_limits_subscription_' . $key )[1];
			$subscription_arr[$key]['max_ce_price']     = wpj_get_option( 'wpj_custom_extra_price_limits_subscription_' . $key )[2];
			$subscription_arr[$key]['min_extra_price']  = wpj_get_option( 'wpj_job_extra_price_limits_subscription_' . $key )[1];
			$subscription_arr[$key]['max_extra_price']  = wpj_get_option( 'wpj_job_extra_price_limits_subscription_' . $key )[2];
			$subscription_arr[$key]['min_job_price']    = wpj_get_option( 'wpj_job_price_limits_subscription_' . $key )[1];
			$subscription_arr[$key]['max_job_price']    = wpj_get_option( 'wpj_job_price_limits_subscription_' . $key )[2];
			$subscription_arr[$key]['job_packages']     = wpj_get_option( 'wpjobster_subscription_packages_' . $key );
			$subscription_arr[$key]['tips']             = wpj_get_option( 'wpjobster_subscription_tips_' . $key );

			$subscription_arr = apply_filters( 'wpj_subscription_levels_info_filter', $subscription_arr, $key );
		}

		return $subscription_arr;
	}
}

if ( ! function_exists( 'wpj_subscription_package_enabled' ) ) {
	function wpj_subscription_package_enabled( $key = '' ) {
		if ( $key ) {
			$level2 = wpj_get_option( 'wpjobster_subscription_level_2_enabled' ) != 'yes' ? 'level2' : '';
			$level3 = wpj_get_option( 'wpjobster_subscription_level_3_enabled' ) != 'yes' ? 'level3' : '';

			if ( $key != $level2 && $key != $level3 ) return true;
			else return false;

		} else return true;
	}
}

if ( ! function_exists( 'wpj_get_user_feature_status' ) ) {
	function wpj_get_user_feature_status( $level_option = '', $subscription_option = '' ) {
		$allowed = wpj_get_option( $level_option );

		if ( wpj_get_option( 'wpjobster_subscription_enabled' ) == 'yes' )
			$allowed = wpj_get_option( $subscription_option );

		return $allowed;
	}
}

if ( ! function_exists( 'wpj_get_user_feature_value' ) ) {
	function wpj_get_user_feature_value( $level_option = '', $subscription_option = '', $default_value = '', $uid = '' ) {
		if ( ! $uid ) $uid = get_current_user_id();

		$user_level = wpj_get_user_level( $uid );

		$feature_value = wpj_get_option( 'wpjobster_get_level' . $user_level . '_' . $level_option );

		if ( $level_option == 'min_amount' ) $feature_value = wpj_get_option( 'wpj_job_price_limits_level' . $user_level )[1];
		if ( $level_option == 'max_amount' ) $feature_value = wpj_get_option( 'wpj_job_price_limits_level' . $user_level )[2];
		if ( $level_option == 'min_extra_amount' ) $feature_value = wpj_get_option( 'wpj_job_extra_price_limits_level' . $user_level )[1];
		if ( $level_option == 'max_extra_amount' ) $feature_value = wpj_get_option( 'wpj_job_extra_price_limits_level' . $user_level )[2];
		if ( $level_option == 'min_customextrasamount' ) $feature_value = wpj_get_option( 'wpj_custom_extra_price_limits_level' . $user_level )[1];
		if ( $level_option == 'max_customextrasamount' ) $feature_value = wpj_get_option( 'wpj_custom_extra_price_limits_level' . $user_level )[2];

		if ( wpj_get_option( 'wpjobster_subscription_enabled' ) == 'yes' ) {
			$current_subscription    = wpj_get_subscription_info( $uid );
			$user_subscription_level = $current_subscription['wpjobster_subscription_level'];

			$subscription_value = wpj_get_option( 'wpjobster_subscription_' . $subscription_option . '_' . $user_subscription_level );

			if ( $subscription_option == 'min_job_price' ) $subscription_value = wpj_get_option( 'wpj_job_price_limits_subscription_level' . $user_level )[1];
			if ( $subscription_option == 'max_job_price' ) $subscription_value = wpj_get_option( 'wpj_job_price_limits_subscription_level' . $user_level )[2];
			if ( $subscription_option == 'min_extra_price' ) $subscription_value = wpj_get_option( 'wpj_job_extra_price_limits_subscription_level' . $user_level )[1];
			if ( $subscription_option == 'max_extra_price' ) $subscription_value = wpj_get_option( 'wpj_job_extra_price_limits_subscription_level' . $user_level )[2];
			if ( $subscription_option == 'min_customextrasamount' ) $subscription_value = wpj_get_option( 'wpj_custom_extra_price_limits_subscription_level' . $user_level )[1];
			if ( $subscription_option == 'max_customextrasamount' ) $subscription_value = wpj_get_option( 'wpj_custom_extra_price_limits_subscription_level' . $user_level )[2];

			if ( is_numeric( $subscription_value ) && $subscription_value > $feature_value ) {
				$feature_value = $subscription_value;

			} elseif ( ! is_numeric( $feature_value ) ) {
				$feature_value = $subscription_value;

			}
		}

		if ( ! is_numeric( $feature_value ) && $feature_value != 'yes' && $feature_value != 'no' ) {
			if ( ! is_numeric( $default_value ) && $default_value != 'yes' && $default_value != 'no' )
				$default_value = 3;

			$feature_value = $default_value;
		}

		return $feature_value;
	}
}

if ( ! function_exists( 'wpj_get_subscription_features' ) ) {
	function wpj_get_subscription_features() {
		$arr = [];

		if ( wpj_get_option( 'wpjobster_fees_for_subscriber_enabled' ) != 'no' ) {
			$arr['fees'] = [
				'label' => __( 'Commission charged', 'wpjobster' ),
				'slug'  => 'fees'
			];
		}

		if ( wpj_get_option( 'wpjobster_packages_enabled' ) != 'no' ) {
			$arr['job_packages'] = [
				'label' => __( 'Job packages', 'wpjobster' ),
				'slug'  => 'job_packages'
			];
		}

		if ( wpj_get_option( 'wpjobster_tips_enabled' ) != 'no' ) {
			$arr['tips'] = [
				'label' => __( 'Tips', 'wpjobster' ),
				'slug'  => 'tips'
			];
		}

		if ( wpj_get_option( 'wpjobster_subscription_noof_extras_enabled' ) != 'no' ) {
			$arr['nr_extras_allowed'] = [
				'label' => __( 'Number of extras allowed', 'wpjobster' ),
				'slug'  => 'noof_extras'
			];
		}

		if ( wpj_get_option( 'wpjobster_subscription_ex_fast_delivery_enabled' ) != 'no' ) {
			$arr['nr_efd_allowed'] = [
				'label' => __( 'Number of extra fast delivery allowed', 'wpjobster' ),
				'slug'  => 'noof_efd'
			];
		}

		if ( wpj_get_option( 'wpjobster_subscription_additional_revision_enabled' ) != 'no' ) {
			$arr['nr_ar_allowed'] = [
				'label' => __( 'Number of additional revision allowed', 'wpjobster' ),
				'slug'  => 'noof_ar'
			];
		}

		if ( wpj_get_option( 'wpjobster_subscription_job_multiples_enabled' ) != 'no' ) {
			$arr['nr_job_m_allowed'] = [
				'label' => __( 'Number of multiple jobs allowed', 'wpjobster' ),
				'slug'  => 'noof_job_m'
			];
		}

		if ( get_option( 'wpjobster_subscription_active_jobs_enabled' ) != 'no' ) {
			$arr['nr_active_jobs_allowed'] = [
				'label' => __( 'Number of active jobs allowed', 'wpjobster' ),
				'slug'  => 'noof_active_jobs'
			];
		}

		if ( wpj_get_option( 'wpjobster_subscription_extra_multiples_enabled' ) != 'no' ) {
			$arr['nr_extra_m_allowed'] = [
				'label' => __( 'Number of multiple extras allowed', 'wpjobster' ),
				'slug'  => 'noof_extra_m'
			];
		}

		if ( wpj_get_option( 'wpjobster_subscription_video_multiples_enabled' ) != 'no' ) {
			$arr['nr_video_m_allowed'] = [
				'label' => __( 'Number of multiple videos allowed', 'wpjobster' ),
				'slug'  => 'noof_video_m'
			];
		}

		if ( wpj_get_option( 'wpjobster_subscription_min_job_price_enabled' ) != 'no' ) {
			$arr['price_min_job_allowed'] = [
				'label' => __( 'Minimum price for job allowed', 'wpjobster' ),
				'slug'  => 'min_job_price'
			];
		}

		if ( wpj_get_option( 'wpjobster_subscription_max_job_price_enabled' ) != 'no' ) {
			$arr['price_job_allowed'] = [
				'label' => __( 'Maximum price for job allowed', 'wpjobster' ),
				'slug'  => 'max_job_price'
			];
		}

		if ( wpj_get_option( 'wpjobster_subscription_min_extra_price_enabled' ) != 'no' ) {
			$arr['price_min_extra_allowed'] = [
				'label' => __( 'Minimum price for extra allowed', 'wpjobster' ),
				'slug'  => 'min_extra_price'
			];
		}

		if ( wpj_get_option( 'wpjobster_subscription_max_extra_price_enabled' ) != 'no' ) {
			$arr['price_extra_allowed'] = [
				'label' => __( 'Maximum price for extra allowed', 'wpjobster' ),
				'slug'  => 'max_extra_price'
			];
		}

		if ( wpj_get_option( 'wpjobster_subscription_min_custom_extras_enabled' ) != 'no' ) {
			$arr['price_min_ce_allowed'] = [
				'label' => __( 'Minimum price for custom extra allowed', 'wpjobster' ),
				'slug'  => 'min_ce_price'
			];
		}

		if ( wpj_get_option( 'wpjobster_subscription_custom_extras_enabled' ) != 'no' ) {
			$arr['price_ce_allowed'] = [
				'label' => __( 'Maximum price for custom extra allowed', 'wpjobster' ),
				'slug'  => 'max_ce_price'
			];
		}

		if ( wpj_get_option( 'wpjobster_subscription_profile_label_enabled' ) != 'no' ) {
			$arr['profile_label'] = [
				'label' => __( 'Profile label', 'wpjobster' ),
				'slug'  => 'profile_label',
			];
		}

		if ( wpj_get_option( 'wpjobster_subscription_icon_url_enabled' ) != 'no' ) {
			$arr['profile_icon'] = [
				'label' => __( 'Profile icon', 'wpjobster' ),
				'slug'  => 'icon_url'
			];
		}

		return $arr;
	}
}

if ( ! function_exists( 'wpj_get_subscription_min_price_by_level' ) ) {
	function wpj_get_subscription_min_price_by_level( $level = 1 ) {
		$interval_arr = ['weekly', 'monthly', 'quarterly', 'yearly', 'lifetime'];

		$subscription_levels = wpj_get_subscription_levels_info();

		$prices = [];

		foreach ( $interval_arr as $key => $period ) {
			$prices[] = floatval( $subscription_levels['level' . $level][$period] );
		}

		return $prices && array_filter( $prices ) && $level != 0 ? min( array_filter( $prices ) ) : 0;
	}
}

if ( ! function_exists( 'wpj_get_subscription_cycle_and_period' ) ) {
	function wpj_get_subscription_cycle_and_period( $sub_type = '', $return = '' ) {
		$sub_type = WPJ_Form::get( 'sub_type', $sub_type );

		if ( $sub_type == 'daily' ) {
			$cycle = 'D';
			$period = 1;

		} else if ( $sub_type == 'weekly' ) {
			$cycle = 'W';
			$period = 1;

		} else if ( $sub_type == 'monthly' ) {
			$cycle = 'M';
			$period = 1;

		}else if ( $sub_type == 'quarterly' ) {
			$cycle = 'M';
			$period = 3;

		} else if ( $sub_type == 'yearly' ) {
			$cycle = 'Y';
			$period = 1;

		} else {
			$cycle = 'lifetime';
			$period = 'unlimited';

		}

		if ( $return == 'cycle' )
			return $cycle;

		if ( $return == 'period' )
			return $period;

		return [ 'cycle' => $cycle, 'period' => $period ];
	}
}

if ( ! function_exists( 'wpj_get_subscription_plan_name_by_level' ) ) {
	function wpj_get_subscription_plan_name_by_level( $sub_level = '' ) {
		$sub_level = WPJ_Form::get( 'sub_level', $sub_level );

		if ( $sub_level == 'level1' ) {
			$plan = wpj_get_option( 'wpjobster_subscription_name_level1' ) ? wpj_get_option( 'wpjobster_subscription_name_level1' ) : __( 'Starter', 'wpjobster' );

		} else if ( $sub_level == 'level2' ) {
			$plan = wpj_get_option( 'wpjobster_subscription_name_level2' ) ? wpj_get_option( 'wpjobster_subscription_name_level2' ) : __( 'Business', 'wpjobster' );

		} else if ( $sub_level == 'level3' ) {
			$plan = wpj_get_option( 'wpjobster_subscription_name_level3' ) ? wpj_get_option( 'wpjobster_subscription_name_level3' ) : __( 'Professional', 'wpjobster' );

		} else {
			$plan = wpj_get_option( 'wpjobster_subscription_name_level0' ) ? wpj_get_option( 'wpjobster_subscription_name_level0' ) : __( 'Free', 'wpjobster' );

		}

		return $plan;
	}
}

if ( ! function_exists( 'wpj_get_subscription_next_billing_date' ) ) {
	function wpj_get_subscription_next_billing_date( $sub_type = '' ) {
		$sub_type = WPJ_Form::get( 'sub_type', $sub_type );

		$start_date = date( 'Y-m-d' );

		$start_date_obj = new DateTime( $start_date );

		if ( $sub_type == 'weekly' )
			$interval = new DateInterval( 'P7D' );

		if ( $sub_type == 'monthly' )
			$interval = new DateInterval( 'P1M' );

		if ( $sub_type == 'quarterly' )
			$interval = new DateInterval( 'P3M' );

		if ( $sub_type == 'yearly' )
			$interval = new DateInterval( 'P12M' );

		if ( $sub_type == 'lifetime' ) {
			$next_billing_date = 0;

		} else {
			$start_date_obj->add( $interval );
			$next_billing_date = strtotime( $start_date_obj->format( 'Y-m-d' ) );

		}

		return $next_billing_date;
	}
}

if ( ! function_exists( 'wpj_get_subscription_messages' ) ) {
	function wpj_get_subscription_messages( $type = 'all' ) {
		$errors = [
			'not_enough_balance'     => __( 'You do not have enough balance to purchase this subscription.', 'wpjobster' ),
			'no_subscription_levels' => __( 'Suscription levels not defined', 'wpjobster' ),
			'not_eligible'           => __( 'You are not eligible for this level', 'wpjobster' ),
			'cancelled'              => __( 'You cancelled this subscription.', 'wpjobster' ),
			'no_plan_selected'       => __( 'Please select a plan.', 'wpjobster' )
		];

		if ( $type == 'errors' )
			return $errors;

		$messages = [
			'balance_down_subscription'        => __( 'Thank you for subscribing with us! We have sent you a confirmation email.', 'wpjobster' ),
			'balance_down_subscription_change' => __( 'You have successfully changed your subscription! We have sent you a confirmation email.', 'wpjobster' ),
			'subscription_schedule'            => __( 'You have successfully scheduled your subscription. We have sent you a confirmation email.', 'wpjobster' ),
			'success'                          => __( 'Thank you for subscribing with us! If the subscription is not active, please refresh the page in a few minutes.', 'wpjobster' )
		];

		if ( $type == 'messages' )
			return $messages;

		return [ 'errors' => $errors, 'messages' => $messages ];
	}
}

if ( ! function_exists( 'wpj_remove_subscription' ) ) {
	function wpj_remove_subscription( $order_id = '', $payment_gateway = '' ) {
		$order_id        = WPJ_Form::post( 'order_id', $order_id );
		$payment_gateway = WPJ_Form::post( 'payment_gateway', $payment_gateway );

		do_action( 'wpj_before_subscription_removal', $order_id );

		$order = wpj_get_subscription_order(
			'user_id, payment_gateway_name, payment_gateway_transaction_id, payment_response',
			['id' => $order_id],
			'row'
		);

		if ( $order ) {
			$active_subscription_id = wpj_get_active_subscription( 'id', ['user_id' => $order->user_id], 'var' );

			if ( $active_subscription_id ) {
				wpj_delete_active_subscription( wpj_get_active_subscription( 'id', ['user_id' => $order->user_id], 'var' ) );
			}

			if ( ! class_exists( 'WPJ_Subscription' ) ) {
				include_once get_template_directory() . '/lib/gateways/class-subscription.php';
			}

			$subscription_class = new WPJ_Subscription( $payment_gateway ?? 'free' );

			do_action( 'wpjobster_subscription_payment_failed', $order_id, $order->payment_gateway_name, $order->payment_gateway_transaction_id, $order->payment_response, 'no' );
		}

		if ( wpj_is_ajax_call() ) wp_die();
	}
}

if ( ! function_exists( 'wpj_subscription_has_levels_defined' ) ) {
	function wpj_subscription_has_levels_defined( $level = '' ) {
		$billing_period_valid = $billing_period_valid1 = $billing_period_valid2 = $billing_period_valid3 = false;

		foreach ( ['weekly', 'monthly', 'quarterly', 'yearly', 'lifetime'] as $key => $value ) {
			if ( wpj_get_subscription_levels_info()['level1'][$value] > 0 )
				$billing_period_valid = $billing_period_valid1 = true;

			if ( wpj_get_option( 'wpjobster_subscription_level_2_enabled' ) == 'yes' && wpj_get_subscription_levels_info()['level2'][$value] > 0 )
				$billing_period_valid = $billing_period_valid2 = true;

			if ( wpj_get_option( 'wpjobster_subscription_level_3_enabled' ) == 'yes' && wpj_get_subscription_levels_info()['level3'][$value] > 0 )
				$billing_period_valid = $billing_period_valid3 = true;
		}

		if ( $level == 'level2' )
			return $billing_period_valid2;

		if ( $level == 'level3' )
			return $billing_period_valid3;

		return $billing_period_valid;
	}
}