<?php
/**
 * WooCommerce Memberships addon Integration
 *
 * @link https://personalizewp.com/
 * @since 3.2.0 Merged into PWP
 * @since 3.1.0
 *
 * @package PersonalizeWP
 * @subpackage PersonalizeWP/Integrations\WooCommerce
 */

namespace PersonalizeWP\Integrations\WooCommerce;

use PersonalizeWP\Block_Renderer;
use PersonalizeWP\Integrations\Editor_Plugins_Integration_Base;

/**
 * PersonalizeWP - WooCommerceMemberships class
 */
final class WooCommerce_Subscriptions extends Editor_Plugins_Integration_Base {

	/**
	 * Class constructor
	 *
	 * @since 3.1.0
	 */
	public function __construct() {
		parent::__construct( 'woocommerce-subscriptions', __( 'WooCommerce Subscriptions', 'personalizewp' ) );
	}

	/**
	 * Add information on WooCommerce Subscriptions plans to Schema.
	 *
	 * @param array $schema Schema
	 * @return array
	 */
	public function add_integrations_rest_settings_schema( $schema ) {
		$schema['integrations']['plugins']['woocommerce_subscriptions_plans'] = array(
			'description' => __( 'An array of WooCommerce Subscriptions Plans. As plan ID and plan name pairs.', 'personalizewp' ),
			'type'        => 'array',
			'readonly'    => true,
		);
		return $schema;
	}

	/**
	 * Add WooCommerce Subscriptions Plans to editor settings.
	 *
	 * @since 3.1.0
	 *
	 * @param array $settings Existing editor settings
	 * @return array
	 */
	public function add_integrations_rest_settings( $settings ) {

		$settings['integrations']['plugins'][] = [
			'value' => $this->plugin_slug,
			'label' => $this->plugin_title,
		];

		$settings['integrations']['woocommerce_subscriptions_plans'] = $this->get_plans();

		return $settings;
	}

	/**
	 * Get WooCommerce Subscriptions Plans.
	 *
	 * @since 3.1.0
	 *
	 * @return array
	 */
	private function get_plans() {

		$cache_key           = 'pwp_woocommerce_subscriptions_plans';
		$subscriptions_plans = wp_cache_get( $cache_key );
		if ( false !== $subscriptions_plans ) {
			return $subscriptions_plans;
		}

		$subscriptions_plans    = [];
		$subscriptions_products = wc_get_products(
			[
				'limit'  => -1,
				'type'   => 'subscription',
				'status' => 'publish',
			]
		);

		if ( ! empty( $subscriptions_products ) ) {
			// Each product is an instance of \WC_Product()
			foreach ( $subscriptions_products as $subscription_product ) {
				$subscriptions_plans[] = [
					'value' => $subscription_product->get_id(), // Cannot directly get ID.
					'label' => $subscription_product->get_name(), // Cannot directly get name.
				];
			}
		}
		wp_cache_set( $cache_key, $subscriptions_plans, '', 5 * MINUTE_IN_SECONDS );

		return $subscriptions_plans;
	}

	/**
	 * Wrapper for checking if the block should render or not. Fires of specific logic check when required.
	 *
	 * @since 3.2.0 Switched from deprecated `personalizewp_should_render_block` filter
	 * @since 3.1.0
	 *
	 * @param bool  $display_block The current status of block display.
	 * @param array $block_params  The set of Personalize display condition attributes.
	 * @param array $params        Array of user params passed via REST
	 * @param array $parsed_block  The full block, including name and attributes.
	 *
	 * @return bool $display_block
	 */
	public function check_render_block_logic( $display_block, $block_params, $params, $parsed_block ) {

		// Nothing to do.
		if ( empty( $block_params['integrations'] ) ) {
			return $display_block;
		}

		// Bail if the integration plugin is not WooCommerce Subscriptions.
		if ( ! $this->uses_this_plugin( $block_params['integrations'] ) ) {
			return $display_block;
		}

		// Bail if WooCommerce Subscriptions plans are empty.
		if ( ! $this->has_plans_set( $block_params['integrations'] ) ) {
			return $display_block;
		}

		// The block should not be displayed if the user is not logged in.
		if ( ! is_user_logged_in() ) {
			return false;
		}

		$plan_params   = [
			'plans'  => $block_params['integrations']['woocommerce_subscriptions_plans'],
			'action' => $block_params['action'],
		];
		$display_block = $this->check_woocommerce_subscriptions_plans_logic( $display_block, $plan_params, $params );

		return $display_block;
	}

	/**
	 * Checks the block for WooCommerce Subscriptions Plans specific logic.
	 *
	 * @since 3.1.0
	 *
	 * @param bool  $display_block  The current status of block display.
	 * @param array $plan_params    Subset of the block params.
	 * @param array $params         Array of user params passed via REST.
	 *
	 * @return bool $display_block
	 */
	private function check_woocommerce_subscriptions_plans_logic( $display_block, $plan_params, $params ) {

		$woocommerce_subscriptions_plans = array_unique( array_filter( $plan_params['plans'] ) );

		if ( empty( $woocommerce_subscriptions_plans ) ) {
			return false;
		}

		$user_id = get_current_user_id();

		// Get all the active subscriptions for the user
		$user_active_subscriptions = wcs_get_users_subscriptions( $user_id );

		if ( empty( $user_active_subscriptions ) ) {
			return false;
		}

		$active_subscriptions_products_ids = [];
		foreach ( $user_active_subscriptions as $user_active_subscription ) {
			if ( $user_active_subscription->has_status( 'active' ) ) {
				$items = $user_active_subscription->get_items();
				foreach ( $items as $item ) {
					$active_subscriptions_products_ids[] = $item->get_product_id();
				}
			}
		}

		$array_intersect        = array_intersect( $woocommerce_subscriptions_plans, $active_subscriptions_products_ids );
		$has_matched_conditions = ! empty( $array_intersect );

		// Display block (or not) based on action and conditions validation.
		$display_block = Block_Renderer::instance()->validate_with_block_action( $display_block, $plan_params['action'], $has_matched_conditions );

		return $display_block;
	}

	/**
	 * Checks if a <pwp-block> placeholder should be displayed.
	 *
	 * @since 3.1.0
	 *
	 * @param bool  $display_placeholder Whether PersonalizeWP should show the block or not
	 * @param array $block_params        The set of Personalize display condition attributes.
	 * @param array $parsed_block        The full block, including name and attributes.
	 *
	 * @return bool $display_placeholder
	 */
	public function check_render_placeholder_logic( $display_placeholder, $block_params, $parsed_block ) {

		// Nothing to do.
		if ( empty( $block_params['integrations'] ) ) {
			return $display_placeholder;
		}

		$integrations = $block_params['integrations'];
		if ( $this->uses_this_plugin( $integrations ) && $this->has_plans_set( $integrations ) ) {
			$display_placeholder = true;
		}

		return $display_placeholder;
	}

	/**
	 * Check whether there are plans set in the integrations attribute.
	 *
	 * @since 3.2.0 Simplified param for easier reuse
	 * @since 3.1.0
	 *
	 * @param array $integrations The integrations attribute
	 *
	 * @return bool true if the plans set in the integrations attribute, otherwise false.
	 */
	private function has_plans_set( $integrations ) {
		return ! empty( $integrations['woocommerce_subscriptions_plans'] ) && is_array( $integrations['woocommerce_subscriptions_plans'] );
	}
}
