<?php
namespace Prodigy\Includes\Helpers;

use Prodigy\admin\Prodigy_Admin_Setup_Wizard;
use Prodigy\Includes\Models\Prodigy_Products;
use Prodigy\Includes\Prodigy;

/**
 * Prodigy Url Helper
 *
 * @version    3.1.9
 * @package    Prodigy
 * @subpackage Prodigy/includes
 */
class Prodigy_Url_Helper {

	public const HOSTED_PATH_LOGIN            = '/customer/login';
	public const HOSTED_PATH_ACCOUNT          = '/customer/account';
	public const HOSTED_PATH_ORDERS           = '/customer/orders';
	public const HOSTED_PATH_ADDRESSES        = '/customer/addresses';
	public const HOSTED_PATH_PAYMENT_METHODS  = '/customer/payment_methods';
	public const HOSTED_PATH_PROFILE_SETTINGS = '/customer/profile_settings';
	public const HOSTED_PATH_SUBSCRIPTION     = '/customer/subscriptions';


	/**
	 * @param int $component
	 *
	 * @return array|false|mixed|null
	 */
	public static function prodigy_parse_request_uri( int $component = PHP_URL_PATH ) {
		return wp_parse_url( self::prodigy_get_request_uri(), $component );
	}

	/**
	 * @return string
	 */
	public static function prodigy_get_request_uri(): string {
		return isset( $_SERVER['REQUEST_URI'] ) ? sanitize_url( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
	}

	/**
	 * @return false|string
	 */
	public static function prodigy_get_thank_url() {
		return self::prodigy_get_page_permalink( 'thank' );
	}

	/**
	 * @param string $page
	 *
	 * @return bool|int
	 */
	public static function prodigy_get_page_id( string $page ) {
		$page = apply_filters( 'prodigy_get_' . $page . '_page_id', get_option( 'prodigy_' . $page . '_page_id' ) );

		if ( $page ) {
			return absint( $page );
		}

		return false;
	}

	/**
	 * @param string  $page
	 * @param ?string $fallback
	 *
	 * @return false|string
	 */
	public static function prodigy_get_page_permalink( string $page, ?string $fallback = null ) {
		$page_id   = self::prodigy_get_page_id( $page );
		$permalink = 0 < $page_id ? get_permalink( $page_id ) : '';

		if ( ! $permalink ) {
			$permalink = $fallback ?? get_home_url();
		}

		return $permalink;
	}


	/**
	 * @param string $taxonomy
	 *
	 * @return bool
	 */
	public static function is_archive_page_url( string $taxonomy = '' ): bool {
		$is_shop = false;

		if ( isset( $_GET['page_id'] ) && self::prodigy_get_page_id( 'shop' ) === (int) $_GET['page_id'] ) {
			return true;
		}

		$url_params = self::prodigy_parse_request_uri( -1 );
		if ( isset( $url_params['path'] ) ) {
			$path    = explode( '/', $url_params['path'] );
			$page_id = self::prodigy_get_page_id( 'shop' );
			foreach ( $path as $slug ) {
				if ( ! empty( $slug ) && Prodigy_Page::is_shop_page( $slug, $page_id ) ) {
					$is_shop = true;
					break;
				}
			}

			if ( ! empty( $taxonomy ) ) {
				$is_shop = Prodigy_Page::is_shop_page( $taxonomy, $page_id );
			}
		}

		return $is_shop;
	}

	/**
	 * @return false|string
	 */
	public static function prodigy_get_shop_url() {
		return self::prodigy_get_page_permalink( 'shop' );
	}

	/**
	 * @return mixed
	 */
	public static function prodigy_get_cart_url() {
		return self::prodigy_get_page_permalink( 'cart' );
	}

	/**
	 * @return mixed|string
	 */
	public static function get_brand_slug(): string {
		$term_slug = '';
		$taxonomy  = get_query_var( 'taxonomy' );
		$term      = get_query_var( 'term' );

		if ( ! empty( $taxonomy ) && $taxonomy === Prodigy::get_prodigy_brand_type() ) {
			$term_slug = $term;
		} elseif ( isset( $_GET['brand'] ) ) {
			$term_slug = sanitize_text_field( wp_unslash( $_GET['brand'] ) );
		} elseif ( isset( $_GET['current_url'] ) ) {
			$current_url = sanitize_url( wp_unslash( $_GET['current_url'] ) );
			$taxonomy    = self::get_taxonomy_from_url( $current_url );
			if ( ! empty( $taxonomy ) && $taxonomy === Prodigy::get_prodigy_brand_slug() ) {
				$term_slug = self::get_taxonomy_slug_from_url( $current_url );
			}
		}

		return $term_slug;
	}

	/**
	 * @param   int $id
	 *
	 * @return false|string
	 */
	public static function get_product_url_by_remote_id( int $id ): string {
		$product    = Prodigy_Products::get_product_meta_by_remote_id(
			Prodigy::PRODIGY_REMOTE_PRODUCT_ID,
			$id
		);
		$link       = get_permalink( $product->post_id ?? '' );
		$brand_slug = self::get_brand_slug();
		if ( $brand_slug ) {
			$link = add_query_arg( 'brand', $brand_slug, $link );
		}

		return $link;
	}

	/**
	 * @param   object $product
	 *
	 * @return false|string
	 */
	public static function get_product_page_url( object $product ) {
		$link       = get_permalink( $product->post_id );
		$brand_slug = self::get_brand_slug();
		if ( $brand_slug ) {
			$link = add_query_arg( 'brand', $brand_slug, $link );
		}

		return $link;
	}

	/**
	 * @param string $url
	 *
	 * @return string
	 */
	public static function get_taxonomy_from_url( string $url ): string {
		$result   = '';
		$path     = wp_parse_url( $url, PHP_URL_PATH );
		$path     = trim( $path, '/' );
		$segments = explode( '/', $path );

		if ( isset( $segments[0], $segments[1] ) ) {
			$tax_slug = $segments[0];
			$result   = $tax_slug;
		}

		return $result;
	}

	/**
	 * @param   string $url
	 *
	 * @return string
	 */
	public static function get_taxonomy_slug_from_url( string $url ): string {
		$result   = '';
		$path     = wp_parse_url( $url, PHP_URL_PATH );
		$path     = trim( $path, '/' );
		$segments = explode( '/', $path );

		if ( isset( $segments[0], $segments[1] ) ) {
			$result = $segments[1];
		}

		return $result;
	}

	/**
	 * @param string $url
	 *
	 * @return void
	 */
	public static function redirect_to( string $url ): void {
		wp_safe_redirect( $url );
		exit;
	}

	/**
	 * @return void
	 */
	public static function redirect_to_404() {
		// Do not redirect when editing in Elementor (avoids 404 when opening "Edit" on a Prodigy Product template).
		if ( is_admin() && isset( $_GET['action'] ) && sanitize_key( wp_unslash( $_GET['action'] ) ) === 'elementor' ) {
			return;
		}
		wp_safe_redirect( home_url( '404' ) );
		exit();
	}

	/**
	 * @param string $target_url
	 *
	 * @return void
	 */
	public static function login_redirect( string $target_url ): void {
		wp_redirect( $target_url );
		exit;
	}

	/**
	 * @return string
	 */
	public static function get_hs_store_subdomain(): string {
		return get_option( Prodigy_Admin_Setup_Wizard::OPTION_URL_DOMAIN_HOSTED_SYSTEM, '' );
	}

	/**
	 * @return string
	 */
	public static function get_url_customer_login(): string {
		return PRODIGY_PROTOCOL_DOMAIN . self::get_hs_store_subdomain() . '.' . PRODIGY_CHECKOUT_DOMAIN . self::HOSTED_PATH_LOGIN;
	}


	/**
	 * @return string
	 */
	public static function get_url_customer_account(): string {
		return PRODIGY_PROTOCOL_DOMAIN . self::get_hs_store_subdomain() . '.' . PRODIGY_CHECKOUT_DOMAIN . self::HOSTED_PATH_ACCOUNT;
	}

	/**
	 * @return string
	 */
	public static function get_url_customer_orders(): string {
		return PRODIGY_PROTOCOL_DOMAIN . self::get_hs_store_subdomain() . '.' . PRODIGY_CHECKOUT_DOMAIN . self::HOSTED_PATH_ORDERS;
	}


	/**
	 * @return string
	 */
	public static function get_url_customer_addresses(): string {
		return PRODIGY_PROTOCOL_DOMAIN . self::get_hs_store_subdomain() . '.' . PRODIGY_CHECKOUT_DOMAIN . self::HOSTED_PATH_ADDRESSES;
	}


	/**
	 * @return string
	 */
	public static function get_url_customer_payments(): string {
		return PRODIGY_PROTOCOL_DOMAIN . self::get_hs_store_subdomain() . '.' . PRODIGY_CHECKOUT_DOMAIN . self::HOSTED_PATH_PAYMENT_METHODS;
	}

	/**
	 * @return string
	 */
	public static function get_url_customer_subscription_settings(): string {
		return PRODIGY_PROTOCOL_DOMAIN . self::get_hs_store_subdomain() . '.' . PRODIGY_CHECKOUT_DOMAIN . self::HOSTED_PATH_SUBSCRIPTION;
	}

	/**
	 * @return string
	 */
	public static function get_url_customer_balance(): string {
		return PRODIGY_PROTOCOL_DOMAIN . self::get_hs_store_subdomain() . '.' . PRODIGY_CHECKOUT_DOMAIN . self::HOSTED_PATH_ACCOUNT;
	}

	/**
	 * @return string
	 */
	public static function get_url_customer_profile_settings(): string {
		return PRODIGY_PROTOCOL_DOMAIN . self::get_hs_store_subdomain() . '.' . PRODIGY_CHECKOUT_DOMAIN . self::HOSTED_PATH_PROFILE_SETTINGS;
	}

	/**
	 * @return string
	 */
	public static function get_url_home(): string {
		return PRODIGY_PROTOCOL_DOMAIN . self::get_hs_store_subdomain() . '.' . PRODIGY_CHECKOUT_DOMAIN;
	}

	/**
	 * Validate if a taxonomy term exists and redirect to 404 if not
	 *
	 * @param string $taxonomy_slug
	 * @param string $term_slug
	 * @return bool
	 */
	public static function validate_taxonomy_term_exists( string $taxonomy_slug, string $term_slug ): bool {
		if ( ! taxonomy_exists( $taxonomy_slug ) ) {
			self::redirect_to_404();
		}

		$term = get_term_by( 'slug', $term_slug, $taxonomy_slug );
		if ( ! $term || is_wp_error( $term ) ) {
			self::redirect_to_404();
		}

		return true;
	}

	/**
	 * Validate Prodigy taxonomy terms from URL and redirect to 404 if not found
	 *
	 * @return bool
	 */
	public static function validate_prodigy_taxonomy_url(): bool {
		$path     = trim( self::prodigy_parse_request_uri(), '/' );
		$segments = explode( '/', $path );

		if ( count( $segments ) < 2 ) {
			return true;
		}

		$taxonomy_slug = $segments[0];
		$term_slug     = $segments[1];

		$taxonomy_mapping = array(
			Prodigy::get_prodigy_category_slug() => Prodigy::get_prodigy_category_type(),
			Prodigy::get_prodigy_tag_slug()      => Prodigy::get_prodigy_tag_type(),
			Prodigy::get_prodigy_brand_slug()    => Prodigy::get_prodigy_brand_type(),
		);

		if ( ! isset( $taxonomy_mapping[ $taxonomy_slug ] ) ) {
			return true;
		}

		$taxonomy_name = $taxonomy_mapping[ $taxonomy_slug ];

		return self::validate_taxonomy_term_exists( $taxonomy_name, $term_slug );
	}
}
