<?php
/**
 * Custom pricing/upgrade page for Craft Addons Pro.
 *
 * Replaces the Freemius default pricing page with a branded page while
 * keeping Freemius checkout intact.
 *
 * @package CraftAddonsForWPBakery
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Class CAFW_Pricing
 *
 * Intercepts the Freemius pricing page hook and renders a custom branded
 * upgrade page. Freemius checkout JS is loaded and triggered from the
 * custom page so payments still go through Freemius.
 */
class CAFW_Pricing {

	/**
	 * Transient key for cached pricing data.
	 *
	 * @var string
	 */
	const CACHE_KEY = 'cafw_pricing';

	/**
	 * Freemius pricing page hook (resolved once, stored here).
	 *
	 * @var string
	 */
	private static $hook = '';

	/**
	 * Register hooks.
	 *
	 * @return void
	 */
	public static function init() {
		add_action( 'admin_menu', array( __CLASS__, 'override_pricing_page' ), PHP_INT_MAX );
		add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue' ) );
	}

	/**
	 * Remove the Freemius pricing page render and inject our own.
	 *
	 * @return void
	 */
	public static function override_pricing_page() {
		if ( ! function_exists( 'cafw_fs' ) ) {
			return;
		}

		$hook = get_plugin_page_hookname( 'craft-addons-for-wpbakery-pricing', 'craft-addons-for-wpbakery' );

		$fs = cafw_fs();
		if (
			is_object( $fs ) &&
			method_exists( $fs, 'is_premium' ) &&
			$fs->is_premium()
		) {
			remove_submenu_page( 'craft-addons-for-wpbakery', 'craft-addons-for-wpbakery-pricing' );
			if ( ! empty( $hook ) ) {
				remove_all_actions( $hook );
			}
			return;
		}

		if ( empty( $hook ) ) {
			return;
		}

		self::$hook = $hook;
		remove_all_actions( $hook );
		add_action( $hook, array( __CLASS__, 'render_page' ) );
	}

	/**
	 * Enqueue assets only on the pricing hook.
	 *
	 * @param string $hook Current admin page hook suffix.
	 * @return void
	 */
	public static function enqueue( $hook ) {
		if ( empty( self::$hook ) || $hook !== self::$hook ) {
			return;
		}

		wp_enqueue_script(
			'freemius-checkout',
			'https://checkout.freemius.com/js/v1/',
			array(),
			null, // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion
			true
		);

		wp_enqueue_style(
			'cafw-pricing',
			CAFW_URL . 'admin/css/cafw-pricing.css',
			array(),
			CAFW_Plugin::asset_ver( 'admin/css/cafw-pricing.css' )
		);

		wp_enqueue_script(
			'cafw-pricing',
			CAFW_URL . 'admin/js/cafw-pricing.js',
			array( 'freemius-checkout' ),
			CAFW_Plugin::asset_ver( 'admin/js/cafw-pricing.js' ),
			true
		);

		$pricing_data = self::get_pricing();
		$fs           = function_exists( 'cafw_fs' ) ? cafw_fs() : null;

		$plan_id    = isset( $pricing_data['plan_id'] ) ? (string) $pricing_data['plan_id'] : '';
		$tiers      = isset( $pricing_data['tiers'] ) ? $pricing_data['tiers'] : array();
		$plugin_id  = ( is_object( $fs ) && method_exists( $fs, 'get_id' ) ) ? (string) $fs->get_id() : '';
		$public_key = ( is_object( $fs ) && method_exists( $fs, 'get_public_key' ) ) ? $fs->get_public_key() : '';
		$account_url = ( is_object( $fs ) && method_exists( $fs, 'get_account_url' ) ) ? $fs->get_account_url() : admin_url();

		wp_localize_script(
			'cafw-pricing',
			'CAFWPricing',
			array(
				'pluginId'   => $plugin_id,
				'publicKey'  => $public_key,
				'planId'     => $plan_id,
				'tiers'      => $tiers,
				'accountUrl' => esc_url( $account_url ),
				'nextUrl'    => esc_url( $account_url ),
			)
		);
	}

	/**
	 * Fetch, normalise, and cache Freemius plan + pricing data.
	 *
	 * Mirrors affiliatex's fetch_pricing() method.
	 *
	 * @return array{plan_id:int,currency:string,tiers:array}|array
	 */
	public static function get_pricing() {
		$cached = get_transient( self::CACHE_KEY );
		if ( false !== $cached && is_array( $cached ) ) {
			return $cached;
		}

		if ( ! function_exists( 'cafw_fs' ) ) {
			return array();
		}

		try {
			$fs = cafw_fs();
			if ( ! is_object( $fs ) || ! method_exists( $fs, 'get_api_plugin_scope' ) ) {
				return array();
			}

			$result = $fs->get_api_plugin_scope()->get( 'pricing.json?is_enriched=true', true );

			$plans = ( is_object( $result ) && isset( $result->plans ) && is_array( $result->plans ) )
				? $result->plans
				: array();

			$paid_plan = self::find_paid_plan( $plans );
			if ( null === $paid_plan ) {
				return array();
			}

			$currency = 'usd';
			$tiers    = array();

			foreach ( (array) $paid_plan->pricing as $pricing ) {
				$annual   = self::extract_price( $pricing, 'annual_price' );
				$monthly  = self::extract_price( $pricing, 'monthly_price' );
				$lifetime = self::extract_price( $pricing, 'lifetime_price' );

				if ( null === $annual && null === $monthly && null === $lifetime ) {
					continue;
				}

				if ( ! empty( $pricing->currency ) ) {
					$currency = $pricing->currency;
				}

				$licenses = isset( $pricing->licenses ) && is_numeric( $pricing->licenses )
					? (int) $pricing->licenses
					: 0;

				$tiers[] = array(
					'pricing_id' => isset( $pricing->id ) ? (int) $pricing->id : 0,
					'licenses'   => $licenses,
					'annual'     => $annual,
					'monthly'    => $monthly,
					'lifetime'   => $lifetime,
				);
			}

			usort(
				$tiers,
				function ( $a, $b ) {
					if ( 0 === $a['licenses'] ) {
						return 1;
					}
					if ( 0 === $b['licenses'] ) {
						return -1;
					}
					return $a['licenses'] - $b['licenses'];
				}
			);

			$data = array(
				'plan_id'  => (int) $paid_plan->id,
				'currency' => $currency,
				'tiers'    => $tiers,
			);

			set_transient( self::CACHE_KEY, $data, HOUR_IN_SECONDS );

			return $data;

		} catch ( Exception $e ) {
			return array();
		}
	}

	/**
	 * Pick the paid plan carrying the most priced tiers.
	 *
	 * @param array $plans Plans from the Freemius API response.
	 * @return object|null
	 */
	private static function find_paid_plan( array $plans ) {
		$best       = null;
		$best_count = 0;

		foreach ( $plans as $plan ) {
			if ( empty( $plan->pricing ) || ! is_array( $plan->pricing ) ) {
				continue;
			}

			$count = 0;
			foreach ( $plan->pricing as $pricing ) {
				if (
					null !== self::extract_price( $pricing, 'annual_price' ) ||
					null !== self::extract_price( $pricing, 'monthly_price' ) ||
					null !== self::extract_price( $pricing, 'lifetime_price' )
				) {
					++$count;
				}
			}

			if ( $count > $best_count ) {
				$best_count = $count;
				$best       = $plan;
			}
		}

		return $best;
	}

	/**
	 * Read a positive numeric price from a pricing object, or null.
	 *
	 * @param object $pricing Pricing object from Freemius.
	 * @param string $key     Property name to read.
	 * @return float|null
	 */
	private static function extract_price( $pricing, $key ) {
		if (
			isset( $pricing->{$key} ) &&
			is_numeric( $pricing->{$key} ) &&
			$pricing->{$key} > 0
		) {
			return (float) $pricing->{$key};
		}
		return null;
	}

	/**
	 * Render the custom pricing page.
	 *
	 * @return void
	 */
	public static function render_page() {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		$cafw_pricing_data = self::get_pricing();

		$cafw_upgrade_url = '';
		$cafw_support_url = '';

		if ( function_exists( 'cafw_fs' ) ) {
			$fs = cafw_fs();
			if ( is_object( $fs ) ) {
				if ( method_exists( $fs, 'get_upgrade_url' ) ) {
					$cafw_upgrade_url = $fs->get_upgrade_url();
				}
				if ( method_exists( $fs, 'contact_url' ) ) {
					$cafw_support_url = $fs->contact_url();
				}
			}
		}

		require CAFW_PATH . 'admin/views/pricing.php';
	}
}
