<?php
/**
 * AJAX navigation for WooCommerce My Account.
 *
 * Keeps the canonical WooCommerce endpoint URLs intact while replacing only
 * the account content region during in-account navigation.
 *
 * @package Shabnam_MuchWOW
 */

defined( 'ABSPATH' ) || exit;

/**
 * Return endpoint keys that are safe to render through the account SPA.
 *
 * @return array<int,string>
 */
function shabnam_muchwow_account_spa_allowed_endpoints() {
	$allowed = array( 'dashboard' );

	if ( function_exists( 'WC' ) && WC() && isset( WC()->query ) ) {
		$allowed = array_merge( $allowed, array_keys( (array) WC()->query->get_query_vars() ) );
	}

	// Logout must always remain a normal navigation so WordPress can complete
	// its nonce-protected logout flow and redirect correctly.
	$allowed = array_values( array_diff( array_unique( array_map( 'sanitize_key', $allowed ) ), array( 'customer-logout' ) ) );

	return $allowed;
}

/**
 * Build a front-end URL map used by JavaScript to resolve Woo endpoints,
 * including sites that customized endpoint slugs in WooCommerce settings.
 *
 * @return array<string,string>
 */
function shabnam_muchwow_account_spa_endpoint_urls() {
	if ( ! function_exists( 'wc_get_page_permalink' ) || ! function_exists( 'wc_get_account_endpoint_url' ) ) {
		return array();
	}

	$map = array(
		'dashboard' => wc_get_page_permalink( 'myaccount' ),
	);

	foreach ( shabnam_muchwow_account_spa_allowed_endpoints() as $endpoint ) {
		if ( 'dashboard' === $endpoint ) {
			continue;
		}
		$map[ $endpoint ] = wc_get_account_endpoint_url( $endpoint );
	}

	return array_filter( $map );
}

/**
 * Sanitize an endpoint value according to WooCommerce endpoint semantics.
 *
 * @param string $endpoint Endpoint key.
 * @param mixed  $value    Raw endpoint value.
 * @return string|int
 */
function shabnam_muchwow_account_spa_clean_value( $endpoint, $value ) {
	$value = is_scalar( $value ) ? wp_unslash( (string) $value ) : '';

	if ( in_array( $endpoint, array( 'orders', 'view-order' ), true ) ) {
		return absint( $value );
	}

	if ( 'edit-address' === $endpoint ) {
		return in_array( $value, array( 'billing', 'shipping' ), true ) ? $value : '';
	}

	return sanitize_text_field( $value );
}

/**
 * Render one account endpoint exactly through WooCommerce's public hooks.
 *
 * @param string     $endpoint Endpoint key.
 * @param string|int $value    Endpoint value.
 * @return string
 */
function shabnam_muchwow_account_spa_render( $endpoint, $value = '' ) {
	ob_start();

	if ( 'dashboard' === $endpoint ) {
		do_action( 'woocommerce_account_dashboard' );
	} else {
		/**
		 * WooCommerce itself dispatches account endpoints using this hook form.
		 * The endpoint is strictly allow-listed before this function is called.
		 */
		do_action( 'woocommerce_account_' . $endpoint . '_endpoint', $value );
	}

	return (string) ob_get_clean();
}

/**
 * AJAX handler for internal My Account navigation.
 */
function shabnam_muchwow_account_spa_ajax() {
	if ( ! class_exists( 'WooCommerce' ) || ! is_user_logged_in() ) {
		wp_send_json_error( array( 'message' => __( 'برای مشاهده حساب کاربری باید وارد سایت شوید.', 'shabnam-muchwow' ) ), 401 );
	}

	check_ajax_referer( 'shabnam_muchwow_account_spa', 'nonce' );

	$endpoint = isset( $_POST['endpoint'] ) ? sanitize_key( wp_unslash( $_POST['endpoint'] ) ) : 'dashboard';
	$allowed  = shabnam_muchwow_account_spa_allowed_endpoints();

	if ( ! in_array( $endpoint, $allowed, true ) ) {
		wp_send_json_error( array( 'message' => __( 'بخش درخواستی حساب کاربری معتبر نیست.', 'shabnam-muchwow' ) ), 400 );
	}

	$value = isset( $_POST['value'] ) ? shabnam_muchwow_account_spa_clean_value( $endpoint, $_POST['value'] ) : '';

	// Preserve WooCommerce notices generated for this request, if any.
	$html = shabnam_muchwow_account_spa_render( $endpoint, $value );

	wp_send_json_success(
		array(
			'html'     => $html,
			'endpoint' => $endpoint,
			'value'    => $value,
		)
	);
}
add_action( 'wp_ajax_shabnam_muchwow_account_spa', 'shabnam_muchwow_account_spa_ajax' );
