<?php
/**
 * Safe page URL + sensitive-context helpers for AI Summarize.
 *
 * @package AISummarize
 */

namespace AISummarize;

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

final class UrlHelper {

	/**
	 * Query keys stripped when “Remove query parameters” is enabled.
	 * Identity args (p, page_id, …) are preserved for plain permalinks.
	 */
	private const STRIP_QUERY_KEYS = [
		'preview',
		'preview_id',
		'preview_nonce',
		'_wpnonce',
		'nonce',
		'token',
		'access_token',
		'refresh_token',
		'key',
		'password',
		'pwd',
		'pass',
		'auth',
		'authorization',
		'session',
		'sid',
		'order',
		'order-pay',
		'order_id',
		'pay_for_order',
		'download_file',
		'customer',
		'user',
		'login',
		'redirect_to',
		'reauth',
		'action',
		'_wp_http_referer',
		'elementor-preview',
		'ver',
		'utm_source',
		'utm_medium',
		'utm_campaign',
		'utm_term',
		'utm_content',
		'fbclid',
		'gclid',
		'msclkid',
		'mc_cid',
		'mc_eid',
		'_ga',
		'_gl',
	];

	/** Kept even when stripping query params (plain permalink / archive identity). */
	private const KEEP_QUERY_KEYS = [
		'p',
		'page_id',
		'attachment_id',
		'name',
		'pagename',
		'page',
		'paged',
		'cat',
		'tag',
		'author',
		'author_name',
		'm',
		'year',
		'monthnum',
		'day',
		'w',
		'post_type',
		's',
	];

	/**
	 * Whether the current request should hide the AI Summarize UI.
	 */
	public static function isSensitiveContext(): bool {
		if ( is_admin() && ! wp_doing_ajax() ) {
			return true;
		}

		$blocked = false;

		global $pagenow;
		if ( is_string( $pagenow ) && in_array( $pagenow, [ 'wp-login.php', 'wp-signup.php', 'wp-activate.php' ], true ) ) {
			$blocked = true;
		}

		if ( function_exists( 'is_account_page' ) && is_account_page() ) {
			$blocked = true;
		}
		if ( function_exists( 'is_cart' ) && is_cart() ) {
			$blocked = true;
		}
		if ( function_exists( 'is_checkout' ) && is_checkout() ) {
			$blocked = true;
		}
		if ( function_exists( 'is_wc_endpoint_url' ) ) {
			foreach ( [ 'order-pay', 'order-received', 'view-order', 'edit-account', 'lost-password', 'customer-logout' ] as $endpoint ) {
				if ( is_wc_endpoint_url( $endpoint ) ) {
					$blocked = true;
					break;
				}
			}
		}

		if ( is_preview() || is_trackback() ) {
			$blocked = true;
		}

		$post = get_post();
		if ( $post instanceof \WP_Post ) {
			$status = get_post_status( $post );
			if ( in_array( $status, [ 'draft', 'pending', 'private', 'future', 'trash', 'auto-draft' ], true ) ) {
				$blocked = true;
			}
			if ( post_password_required( $post ) ) {
				$blocked = true;
			}
		}

		/**
		 * @param bool $blocked Whether AI Summarize should not render.
		 */
		return (bool) apply_filters( 'wpps_ai_summarize_is_sensitive_context', $blocked );
	}

	/**
	 * Resolve a shareable public URL for the current view.
	 *
	 * @param array<string, mixed> $settings
	 */
	public static function getShareableUrl( array $settings ): string {
		$url = '';

		if ( is_singular() ) {
			$post = get_post();
			if ( $post instanceof \WP_Post ) {
				$canonical = self::getCanonicalUrl( $post );
				$url       = $canonical !== '' ? $canonical : (string) get_permalink( $post );
			}
		}

		if ( $url === '' && ! is_admin() ) {
			$url = home_url( add_query_arg( [] ) );
		}

		$remove_query = ! empty( $settings['remove_query_params'] );
		$url          = self::sanitizeShareUrl( $url, $remove_query );

		/**
		 * @param string               $url      Sanitized URL.
		 * @param array<string, mixed> $settings Module settings.
		 */
		$filtered = apply_filters( 'wpps_ai_summarize_share_url', $url, $settings );

		return is_string( $filtered ) ? self::sanitizeShareUrl( $filtered, $remove_query ) : $url;
	}

	/**
	 * @param \WP_Post $post
	 */
	private static function getCanonicalUrl( \WP_Post $post ): string {
		if ( function_exists( 'wp_get_canonical_url' ) ) {
			$maybe = wp_get_canonical_url( $post );
			if ( is_string( $maybe ) && $maybe !== '' ) {
				return $maybe;
			}
		}
		return '';
	}

	/**
	 * Strip fragments and (optionally) tracking/sensitive query args.
	 *
	 * @param bool $strip_tracking When true, remove tracking/sensitive args; keep identity args.
	 *                             When false, only remove high-risk secrets (nonce, token, password, preview).
	 */
	public static function sanitizeShareUrl( string $url, bool $strip_tracking = true ): string {
		$url = trim( $url );
		if ( $url === '' ) {
			return '';
		}

		$url = esc_url_raw( $url );
		if ( ! is_string( $url ) || $url === '' ) {
			return '';
		}

		$parts = wp_parse_url( $url );
		if ( ! is_array( $parts ) || empty( $parts['host'] ) ) {
			return '';
		}

		$scheme = isset( $parts['scheme'] ) ? strtolower( (string) $parts['scheme'] ) : 'https';
		if ( ! in_array( $scheme, [ 'http', 'https' ], true ) ) {
			return '';
		}

		$path    = isset( $parts['path'] ) ? (string) $parts['path'] : '';
		$rebuild = $scheme . '://' . $parts['host'];
		if ( ! empty( $parts['port'] ) ) {
			$rebuild .= ':' . (int) $parts['port'];
		}
		$rebuild .= $path;

		$query = '';
		if ( ! empty( $parts['query'] ) ) {
			parse_str( (string) $parts['query'], $args );
			if ( is_array( $args ) ) {
				$strip = $strip_tracking
					? self::STRIP_QUERY_KEYS
					: [ 'preview', 'preview_id', 'preview_nonce', '_wpnonce', 'nonce', 'token', 'access_token', 'password', 'pwd', 'pass' ];

				foreach ( array_keys( $args ) as $key ) {
					$lk = strtolower( (string) $key );
					if ( in_array( $lk, self::KEEP_QUERY_KEYS, true ) ) {
						continue;
					}
					if ( in_array( $lk, $strip, true ) || ( $strip_tracking && str_starts_with( $lk, 'utm_' ) ) ) {
						unset( $args[ $key ] );
					}
				}

				if ( $args !== [] ) {
					$query = build_query( $args );
				}
			}
		}

		if ( $query !== '' ) {
			$rebuild .= '?' . $query;
		}

		return esc_url_raw( $rebuild ) ?: '';
	}

	/**
	 * @param array<string, mixed> $settings
	 */
	public static function buildPrompt( array $settings, string $url ): string {
		$prompt = str_replace( '{url}', $url, self::defaultPromptTemplate() );
		$prompt = trim( $prompt );

		/**
		 * @param string               $prompt   Prompt body.
		 * @param string               $url      Shared URL.
		 * @param array<string, mixed> $settings Module settings.
		 */
		$filtered = apply_filters( 'wpps_ai_summarize_prompt', $prompt, $url, $settings );

		return is_string( $filtered ) ? trim( $filtered ) : $prompt;
	}

	public static function defaultPromptTemplate(): string {
		return "Read the following page and answer questions about its content:\n\n{url} \n\nFirst provide a concise summary, then identify the key points. Base your response on the page content and allow me to ask follow-up questions.";
	}
}
