<?php

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

/**
 * Pro utility functions.
 *
 * @since 2.5.0
 */

/**
 * Return variant name from id.
 *
 * @since 2.5.0
 *
 * @param int $variant_id Variant ID.
 * @return int
 */
function masteriyo_pro_get_variant_name_from_id( $variant_id ) {
	$variant_id = strval( $variant_id );

	$map = array(
		'121211' => 'Basic',
		'8795'   => 'Pro',
		'8796'   => 'Elite',
		'8797'   => 'Scale',
	);

	return isset( $map[ $variant_id ] ) ? $map[ $variant_id ] : 'Unknown';
}



/**
 * Return variant ID from name.
 *
 * @since 2.5.0
 *
 * @param string $variant_name Variant name.
 * @return int|null
 */
function masteriyo_pro_get_variant_id_from_name( $variant_name ) {
	$variant_name = masteriyo_strtolower( $variant_name );

	$map = array(
		'basic'   => 121211,
		'starter' => 8795,
		'pro'     => 8795,
		'growth'  => 8796,
		'elite'   => 8796,
		'scale'   => 8797,
	);

	return isset( $map[ $variant_name ] ) ? $map[ $variant_name ] : null;
}

/**
 * Determines if a user's subscription plan grants access to a feature requiring a specific plan.
 *
 * Supports backward compatibility by mapping old and new plan names to variant IDs.
 * Compares plans based on a defined hierarchy order to correctly handle feature access,
 * regardless of the numeric variant ID values.
 *
 * @since 2.20.0
 *
 * @param string $required_plan_name The plan name required to access the feature (e.g., 'basic-1', 'essentials').
 * @param int    $user_plan_id       The user's current subscription plan variant ID.
 *
 * @return bool True if the user's plan is equal or higher in the hierarchy than the required plan; false otherwise.
 */

function masteriyo_pro_is_feature_allowed_for_plan( $required_plan_name, $user_plan_id ) {
	$required_plan_name = masteriyo_normalize_plan_key( $required_plan_name );

	$plan_map = array(
		'basic'   => 121211,
		'starter' => 8795,
		'pro'     => 8795, // maps to normalized ID
		'elite'   => 8796,
		'growth'  => 8796,
		'scale'   => 8797,
	);

	$required_plan_id = $plan_map[ $required_plan_name ] ?? null;
	if ( empty( $required_plan_id ) ) {
		return false;
	}

	$user_plan_id = masteriyo_normalize_plan_id( $user_plan_id );

	$plan_order = array( 121211, 8795, 8796, 8797 );

	$required_index = array_search( $required_plan_id, $plan_order );
	$user_index     = array_search( $user_plan_id, $plan_order );

	return $required_index !== false && $user_index !== false && $user_index >= $required_index;
}


/**
 * Normalize the plan key by converting it to lowercase, trimming whitespace,
 * and removing specific substrings related to lifetime plans.
 *
 * @since 2.20.0
 * @param string $plan_name The original plan name to be normalized.
 * @return string The normalized plan name.
 */
function masteriyo_normalize_plan_key( $plan_name ) {
	$plan_name = masteriyo_strtolower( trim( $plan_name ) );
	$plan_name = preg_replace( '/[\s_-]*lifetime[\s_-]*/i', '', $plan_name );
	$parts     = preg_split( '/\s+/', $plan_name );
	return $parts[0];
}


/**
 * Normalize the user plan ID to its base plan ID.
 *
 * This function maps specific lifetime plan IDs to their corresponding base plan IDs.
 * If the provided plan ID does not exist in the mapping, it returns the original plan ID.
 * @since 2.20.0
 * @param int $user_plan_id The user plan ID to be normalized.
 * @return int The normalized plan ID (base plan ID) or the original plan ID if no mapping exists.
 */
function masteriyo_normalize_plan_id( $user_plan_id ) {
	$map = array(
		146559 => 8795,
		146567 => 8796,
		825082 => 8796,
		877800 => 8795,
		877802 => 8796,
	);

	return $map[ $user_plan_id ] ?? $user_plan_id;
}


/**
 * Return instance name.
 *
 * @since 2.5.0
 *
 * @return string
 */
function masteriyo_pro_get_instance_name() {
	$instance_name = wp_parse_url( get_bloginfo( 'url' ), PHP_URL_HOST );
	$instance_name = $instance_name ? $instance_name : wp_generate_uuid4();

	return $instance_name;
}

/**
 * Activate license key.
 *
 * @since 2.5.0
 *
 * @param string $license_key License key.
 * @param string $instance_name Instance name.
 * @return array|WP_Error
 */
function masteriyo_pro_activate_license( $license_key, $instance_name ) {
	$response = wp_remote_get(
		MASTERIYO_PRO_API_URL . '/activate',
		array(
			'headers' => array(
				'Accept' => 'application/json',
			),
			'timeout' => 30,
			'body'    => array(
				'license_key'   => $license_key,
				'instance_name' => $instance_name,
			),
		)
	);

	if ( is_wp_error( $response ) ) {
		return $response;
	}

	// Throw error when firewall flags license activation process as malicious activity.
	if ( 403 === wp_remote_retrieve_response_code( $response ) ) {
		return new \WP_Error(
			'masteriyo_pro_rest_license_authorized',
			wp_remote_retrieve_body( $response ),
			array( 'status' => 403 )
		);
	}

	$data = json_decode( wp_remote_retrieve_body( $response ), true );

	if ( is_null( $data ) ) {
		return new \WP_Error(
			'masteriyo_pro_rest_invalid_json',
			esc_html__( 'Invalid JSON received from the validation server.', 'learning-management-system' ),
			array( 'status' => 500 )
		);
	}

	$activated = masteriyo_array_get( $data, 'data.activated', false );

	if ( false === $activated ) {
		return new \WP_Error(
			'masteriyo_pro_rest_license_activation_fail',
			$data['error'],
			array(
				'status' => 400,
			)
		);
	}

	return masteriyo_array_get( $data, 'data' );
}

/**
 * Deactivate license key.
 *
 * @since 2.5.0
 *
 * @param string $license_key
 * @param string $instance_id
 * @return boolean|WP_Error
 */
function masteriyo_pro_deactivate_license( $license_key, $instance_id ) {
	$deactivate_url = add_query_arg(
		array(
			'license_key' => $license_key,
			'instance_id' => $instance_id,
		),
		MASTERIYO_PRO_API_URL . '/deactivate'
	);

	$response = wp_remote_get(
		$deactivate_url,
		array(
			'headers' => array(
				'Accept' => 'application/json',
			),
			'timeout' => 30,
		)
	);

	if ( is_wp_error( $response ) ) {
		return $response;
	}

	// Throw error when firewall flags license deactivation process as malicious activity.
	if ( 403 === wp_remote_retrieve_response_code( $response ) ) {
		return new \WP_Error(
			'masteriyo_pro_rest_license_authorized',
			wp_remote_retrieve_body( $response ),
			array( 'status' => 403 )
		);
	}

	$data = json_decode( wp_remote_retrieve_body( $response ), true );

	if ( is_null( $data ) ) {
		return new \WP_Error(
			'masteriyo_pro_rest_invalid_json',
			esc_html__( 'Invalid JSON received from the validation server.', 'learning-management-system' ),
			array( 'status' => 500 )
		);
	}

	return isset( $data['success'] );
}

/**
 * Validate the license key.
 *
 * @since 2.6.7
 *
 * @param string $license_key The key of the license.
 *
 * @return boolean Returns false if only the license key is invalid or expired and return true otherwise.
 */
function masteriyo_pro_validate_license( $license_key ) {
	$validate_url = add_query_arg(
		array(
			'license_key' => $license_key,
		),
		MASTERIYO_PRO_API_URL . '/update'
	);

	$response = wp_remote_get(
		$validate_url,
		array(
			'headers' => array(
				'Accept' => 'application/json',
			),
			'timeout' => 10,
		)
	);

	if ( is_wp_error( $response ) ) {
		return true;
	}

	$data = json_decode( wp_remote_retrieve_body( $response ), true );

	if ( is_array( $data ) && isset( $data['error_code'] ) && 'invalid_license_key' === $data['error_code'] ) {
		return false;
	}

	return true;
}
