<?php
/**
 * Validates properties against the bundled vocabulary subset.
 *
 * Terms outside the subset are technical information ("not verified"), not
 * published warnings — the local list is conservative and incomplete vs Schema.org.
 *
 * @package SEOvaultSEO\Schema\Validation\Rules\SchemaOrg
 */

namespace SEOvaultSEO\Schema\Validation\Rules\SchemaOrg;

use SEOvaultSEO\Schema\Validation\Data\SchemaOrgVocabularyCatalog;
use SEOvaultSEO\Schema\Validation\RuleInterface;
use SEOvaultSEO\Schema\Validation\Severity;
use SEOvaultSEO\Schema\Validation\ValidationContext;
use SEOvaultSEO\Schema\Validation\ValidationIssue;

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

/**
 * Reports properties outside the local vocabulary as technical information.
 */
class KnownPropertyRule implements RuleInterface {

	/**
	 * Get the stable rule code.
	 *
	 * @return string
	 */
	public function get_code() {
		return 'schema.property.unknown';
	}

	/**
	 * Vocabulary property checks apply to typed entities.
	 *
	 * @param ValidationContext $context Validation context.
	 * @return bool
	 */
	public function supports( ValidationContext $context ) {
		return true;
	}

	/**
	 * Report properties outside the local vocabulary subset as technical info.
	 *
	 * @param ValidationContext $context Validation context.
	 * @return ValidationIssue[]
	 */
	public function evaluate( ValidationContext $context ) {
		$known_types      = SchemaOrgVocabularyCatalog::known_types_map();
		$known_properties = SchemaOrgVocabularyCatalog::known_properties_map();
		$issues           = array();

		foreach ( $context->get_entities() as $entity ) {
			$types = $entity['types'] ?? array();
			if ( empty( array_intersect_key( array_flip( $types ), $known_types ) ) ) {
				continue;
			}

			foreach ( $entity['data'] ?? array() as $property => $value ) {
				if ( '@' === substr( (string) $property, 0, 1 ) || isset( $known_properties[ $property ] ) ) {
					continue;
				}

				$issues[] = new ValidationIssue(
					array(
						'code'        => 'schema.property.unknown',
						'severity'    => Severity::INFO,
						'category'    => 'technical',
						'entity_type' => implode( ', ', $types ),
						'entity_id'   => $entity['id'] ?? '',
						'path'        => ( $entity['path'] ?? '' ) . '.' . $property,
						'source'      => $context->get_source(),
						'title_key'   => 'schema.property_unknown.title',
						'message_key' => 'schema.property_unknown.message',
					)
				);
			}
		}

		return $issues;
	}
}
