<?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_Memberships extends Editor_Plugins_Integration_Base {

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

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

	/**
	 * Add WooCommerce Memberships 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_memberships_plans'] = $this->get_plans();

		return $settings;
	}

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

		$cache_key         = 'pwp_woocommerce_memberships_plans';
		$memberships_plans = wp_cache_get( $cache_key );
		if ( false !== $memberships_plans ) {
			return $memberships_plans;
		}

		$memberships_plans  = array();
		$_memberships_plans = wc_memberships_get_membership_plans();

		if ( ! empty( $_memberships_plans ) ) {
			foreach ( $_memberships_plans as $membership_plan ) {
				$memberships_plans[] = array(
					'value' => $membership_plan->id,
					'label' => $membership_plan->name,
				);
			}
		}
		wp_cache_set( $cache_key, $memberships_plans, '', 5 * MINUTE_IN_SECONDS );

		return $memberships_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 Memberships.
		if ( ! $this->uses_this_plugin( $block_params['integrations'] ) ) {
			return $display_block;
		}

		// Bail if WooCommerce Memberships 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_memberships_plans'],
			'action' => $block_params['action'],
		];
		$display_block = $this->check_woocommerce_memberships_plans_logic( $display_block, $plan_params, $params );

		return $display_block;
	}

	/**
	 * Checks the block for WooCommerce Memberships 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_memberships_plans_logic( $display_block, $plan_params, $params ) {

		$woocommerce_memberships_plans = array_unique( array_filter( $plan_params['plans'] ) );
		if ( empty( $woocommerce_memberships_plans ) ) {
			return false;
		}

		$user_id = get_current_user_id();

		$has_matched_conditions = false;
		foreach ( $woocommerce_memberships_plans as $woocommerce_memberships_plan ) {
			if ( wc_memberships_is_user_member( $user_id, $woocommerce_memberships_plan, false ) ) {
				$has_matched_conditions = true;
				break;
			}
		}

		// 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
	 *
	 * @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_memberships_plans'] ) && is_array( $integrations['woocommerce_memberships_plans'] );
	}
}
