<?php
/**
 * URL manipulation helper functions.
 *
 * @package Awesomemotive\Rewardswp\Helpers
 * @since 1.0.0
 */

namespace Awesomemotive\Rewardswp\Helpers;

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

use Awesomemotive\Rewardswp\Settings\Options\General\LicenseOption;
use Awesomemotive\Rewardswp\Settings\Options\Referrals\ReferralVariableOption;

use function Awesomemotive\Rewardswp\Helpers\is_rewardswp_pro_build;


/**
 * Ensure a given URL always ends with a trailing slash before any query parameters.
 *
 * This function parses the URL, adds a trailing slash to the path component if missing,
 * and preserves query parameters and fragments.
 *
 * @param string $url The URL to process.
 *
 * @return string The sanitized URL with a trailing slash.
 * @since 1.0.0
 */
function ensure_trailing_slash( string $url ): string {
	// Sanitize the input URL.
	$url = esc_url_raw( $url );

	if ( empty( $url ) ) {
		return $url; // Return the URL as-is if it's empty.
	}

	// Parse the URL into its components.
	$parsed_url = wp_parse_url( $url );

	// Add a trailing slash to the path component, if it exists.
	$path = isset( $parsed_url['path'] ) ? rtrim( $parsed_url['path'], '/' ) . '/' : '';

	// Rebuild the URL with its components.
	$rebuilt_url = ( isset( $parsed_url['scheme'] ) ? $parsed_url['scheme'] . '://' : '' ) .
		( $parsed_url['host'] ?? '' ) .
		$path .
		( isset( $parsed_url['query'] ) ? '?' . $parsed_url['query'] : '' ) .
		( isset( $parsed_url['fragment'] ) ? '#' . $parsed_url['fragment'] : '' );

	// Return the rebuilt and sanitized URL.
	return esc_url_raw( $rebuilt_url );
}

/**
 * Checks if a given string is a valid URL.
 *
 * @since 1.0.0
 *
 * @param string $url The URL to validate.
 *
 * @return bool True if the URL is valid, false otherwise.
 */
function is_url( string $url ): bool {
	return (bool) filter_var( $url, FILTER_VALIDATE_URL );
}

/**
 * Remove all query parameters from a given URL.
 *
 * @since 1.0.0
 *
 * @param string $url The URL to clean.
 *
 * @return string|null The cleaned URL without query parameters. Will return null in case it is not a valid URL.
 */
function clean_url_params( string $url ): ?string {
	if ( ! is_url( $url ) ) {
		return '';
	}

	$parts = wp_parse_url( $url );

	if ( ! $parts || ! isset( $parts['scheme'], $parts['host'] ) ) {
		return '';
	}

	// Build the URL without query parameters.
	return sprintf(
		'%s://%s%s%s',
		$parts['scheme'],
		$parts['host'],
		isset( $parts['port'] ) ? sprintf( ':%d', $parts['port'] ) : '',
		$parts['path'] ?? ''
	);
}

/**
 * Removes specific query parameters from a given URL.
 *
 * @since 1.0.0
 *
 * @param string   $url    The URL to process.
 * @param string[] $params Array of query parameter names to remove.
 *
 * @return string The URL with the specified query parameters removed.
 */
function remove_url_params( string $url, array $params ): string {
	if ( empty( $params ) ) {
		return $url;
	}

	// Validate and parse the URL.
	if ( ! is_url( $url ) ) {
		return '';
	}

	$parts = wp_parse_url( $url );

	if ( ! $parts ) {
		return $url;
	}

	// Parse query string into an associative array.
	$query_params = [];
	if ( isset( $parts['query'] ) ) {
		parse_str( $parts['query'], $query_params );

		// Remove the specified parameters.
		foreach ( $params as $param ) {
			unset( $query_params[ $param ] );
		}
	}

	// Rebuild the query string.
	$new_query = http_build_query( $query_params );

	// Reconstruct the URL.
	return sprintf(
		'%s://%s%s%s%s',
		$parts['scheme'],
		$parts['host'],
		isset( $parts['port'] ) ? sprintf( ':%d', $parts['port'] ) : '',
		$parts['path'] ?? '',
		$new_query ? '?' . $new_query : ''
	);
}

/**
 * Retrieve the current URL.
 *
 * @since 1.0.0
 *
 * @return string
 */
function get_current_url(): string {
	return esc_url_raw(
		home_url(
			sanitize_text_field(
				wp_unslash( $_SERVER['REQUEST_URI'] ?? '' )
			)
		)
	);
}

/**
 * Retrieve the referrer URL.
 *
 * @since 1.0.0
 *
 * @return string
 */
function get_referrer_url(): string {
	return sanitize_text_field(
		wp_unslash( $_SERVER['HTTP_REFERER'] ?? '' )
	);
}

/**
 * Retrieve a URL that opens the rewards panel to a specific view.
 *
 * @since 1.0.0
 *
 * @param string $panel The panel to open. Defaults to 'home'.
 *
 * @return string
 */
function get_panel_url( string $panel = 'home' ): string {
	return esc_url_raw( sprintf( '%s?rewardswp=%s', home_url( '/' ), $panel ) );
}

/**
 * Retrieves the base URL for referrals with the referral slug appended as a query argument but without the member code.
 *
 * @return string The referral base URL.
 */
function get_referral_link_base_url(): string {
	return sprintf(
		'%s=',
		add_query_arg(
			get_option_value( ReferralVariableOption::class ),
			'',
			home_url( '/' )
		)
	);
}

/**
 * Add UTM parameters to a URL for tracking.
 *
 * @since 1.1.0
 *
 * @param string $url      The base URL to add UTM parameters to.
 * @param string $source   UTM source (e.g., 'rewardswp', 'liteplugin').
 * @param string $medium   UTM medium (e.g., 'drawer', 'modal', 'banner').
 * @param string $campaign UTM campaign (e.g., 'addon', 'upgrade', 'integration').
 * @param string $content  Optional UTM content for additional tracking.
 * @param string $term     Optional UTM term for additional tracking (e.g., feature slug).
 *
 * @return string The URL with UTM parameters added.
 */
function add_utm_params( string $url, string $source, string $medium = 'plugin', string $campaign = '', string $content = '', string $term = '' ): string {
	$utm_params = [
		'utm_source' => sanitize_key( $source ),
		'utm_medium' => sanitize_key( $medium ),
	];

	if ( ! empty( $campaign ) ) {
		$utm_params['utm_campaign'] = sanitize_key( $campaign );
	}

	if ( ! empty( $content ) ) {
		$utm_params['utm_content'] = sanitize_key( $content );
	}

	if ( ! empty( $term ) ) {
		$utm_params['utm_term'] = sanitize_key( $term );
	}

	// Note: Don't escape here - callers should use esc_url() at output time.
	return add_query_arg( $utm_params, $url );
}

/**
 * Retrieve the admin-ajax.php URL for storefront (front-end) requests.
 *
 * The returned URL carries the `rewardswp_locale=site` marker, which
 * AwesomeMotiveRewardsWP::use_site_locale_for_frontend_ajax() reads to serve
 * the response in the site language instead of the logged-in visitor's
 * profile language (admin-ajax.php makes is_admin() true, so WordPress would
 * otherwise pick the profile language and the storefront UI would end up
 * partially translated).
 *
 * All storefront code must source its AJAX URL from this helper. Admin
 * screens should keep using admin_url( 'admin-ajax.php' ) directly so they
 * keep honoring each admin's own profile language; a CI guard enforces the
 * split.
 *
 * @since 1.4.4
 *
 * @return string The admin-ajax.php URL with the site-locale marker.
 */
function frontend_ajax_url(): string {
	return add_query_arg( 'rewardswp_locale', 'site', admin_url( 'admin-ajax.php' ) );
}

/**
 * Get the upgrade URL with UTM parameters for tracking.
 *
 * Returns different URLs based on build type:
 * - Lite build: https://rewardswp.com/lite-upgrade/
 * - Pro build: https://rewardswp.com/pro-upgrade/
 *
 * UTM structure:
 * - utm_source: WordPress
 * - utm_campaign: liteplugin (Lite build) or proplugin (Pro build)
 * - utm_medium: location/context (e.g., 'settings', 'drawer', 'dashboard-help-widget')
 * - utm_content: content identifier (e.g., 'upgrade_to_plus', 'compare_plans')
 * - utm_term: feature slug (e.g., 'redeem_free_shipping', 'points_expiry')
 *
 * @since 1.1.0
 *
 * @param string $content UTM content identifier (e.g., 'upgrade_to_plus', 'compare_plans').
 * @param string $medium  UTM medium for tracking (e.g., 'settings', 'drawer', 'modal').
 * @param string $plan    Optional minimum required plan name (e.g., 'Plus', 'Pro').
 * @param string $term    Optional UTM term for feature tracking (e.g., 'redeem_free_shipping').
 *
 * @return string The upgrade URL with UTM parameters.
 */
function get_upgrade_url( string $content = '', string $medium = 'plugin', string $plan = '', string $term = '' ): string {
	$is_pro   = is_rewardswp_pro_context();
	$base_url = $is_pro ? 'https://rewardswp.com/pro-upgrade/' : 'https://rewardswp.com/lite-upgrade/';
	$campaign = $is_pro ? 'proplugin' : 'liteplugin';

	$url = add_utm_params( $base_url, 'WordPress', $medium, $campaign, $content, $term );

	if ( ! empty( $plan ) ) {
		$url = add_query_arg( 'plan', strtolower( $plan ), $url );
	}

	// Append license key for Pro builds.
	if ( $is_pro ) {
		$license_data = get_option_value( LicenseOption::class );

		if ( ! empty( $license_data['key'] ) ) {
			$url = add_query_arg( 'license_key', $license_data['key'], $url );
		}
	}

	return $url;
}
