<?php
/**
 * Safe documentation-key resolver for Schema Health issues.
 *
 * @package SEOvaultSEO\Schema\Validation
 */

namespace SEOvaultSEO\Schema\Validation;

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

/**
 * Maps internal issue documentation keys to trusted public URLs.
 */
class ValidationDocumentationRegistry {

	/**
	 * Resolve an internal documentation key to an allowed HTTPS URL.
	 *
	 * @param string $key   Internal documentation key.
	 * @param array  $issue Exported issue data.
	 * @return string
	 */
	public static function resolve( $key, $issue = array() ) {
		$key  = sanitize_key( $key );
		$urls = self::get_urls();
		$url  = isset( $urls[ $key ] ) ? $urls[ $key ] : '';

		$url = apply_filters( 'seovaultseo_schema_validation_documentation_url', $url, $key, $issue );
		if ( ! is_string( $url ) || '' === $url ) {
			return '';
		}

		return self::resolve_raw_url( $url );
	}

	/**
	 * Allowlist an absolute HTTPS documentation URL.
	 *
	 * @param string $url Candidate URL.
	 * @return string
	 */
	public static function resolve_raw_url( $url ) {
		if ( ! is_string( $url ) || '' === $url ) {
			return '';
		}

		$parts         = wp_parse_url( $url );
		$hosts         = apply_filters(
			'seovaultseo_schema_validation_documentation_hosts',
			array(
				'developers.google.com',
				'seovaultai.com',
				'www.seovaultai.com',
				'schema.org',
				'www.schema.org',
			)
		);
		$allowed_hosts = array();
		if ( is_array( $hosts ) ) {
			foreach ( $hosts as $host ) {
				if ( is_string( $host ) && '' !== $host ) {
					$allowed_hosts[] = strtolower( $host );
				}
			}
		}
		if (
			! is_array( $parts )
			|| 'https' !== ( $parts['scheme'] ?? '' )
			|| empty( $parts['host'] )
			|| ! in_array( strtolower( $parts['host'] ), $allowed_hosts, true )
		) {
			return '';
		}

		return esc_url_raw( $url, array( 'https' ) );
	}

	/**
	 * Build the bundled key => source URL map.
	 *
	 * @return array
	 */
	private static function get_urls() {
		$data = require __DIR__ . '/Data/GoogleRichResultRules.php';
		$urls = array();
		foreach ( $data['rules'] ?? array() as $type => $rule ) {
			if ( empty( $rule['source_url'] ) || ! is_string( $rule['source_url'] ) ) {
				continue;
			}
			$url = (string) $rule['source_url'];
			$key = strtolower( preg_replace( '/(?<!^)[A-Z]/', '_$0', (string) $type ) );
			$urls[ $key ] = $url;

			// Prefer the registry documentation_key alias when present (e.g. FAQPage → faq_page).
			if ( class_exists( '\SEOvaultSEO\Schema\SchemaTypePolicyRegistry' ) ) {
				$policy = \SEOvaultSEO\Schema\SchemaTypePolicyRegistry::get_entry( (string) $type );
				if ( is_array( $policy ) && ! empty( $policy['documentation_key'] ) ) {
					$urls[ sanitize_key( (string) $policy['documentation_key'] ) ] = $url;
				}
			}
		}
		return $urls;
	}
}
