<?php
/**
 * @package ACF
 * @author  WP Engine
 *
 * © 2026 Advanced Custom Fields (ACF®). All rights reserved.
 * "ACF" is a trademark of WP Engine.
 * Licensed under the GNU General Public License v2 or later.
 * https://www.gnu.org/licenses/gpl-2.0.html
 */

namespace ACF\AI\GEO;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;

/**
 * ACF GEO Field Settings
 *
 * Adds JSON-LD field role settings to ACF fields.
 */
class FieldSettings {

	/**
	 * Constructs the FieldSettings class.
	 *
	 * @since 6.8.0
	 *
	 * @return void
	 */
	public function __construct() {
		$this->init();
	}

	/**
	 * Initialize the field settings
	 *
	 * @since 6.8.0
	 *
	 * @return void
	 */
	public function init() {
		// Add field role setting to the General tab.
		add_action( 'acf/field_group/render_field_settings_tab/general', array( $this, 'render_field_role_setting' ) );
	}

	/**
	 * Render the field role setting
	 *
	 * @since 6.8.0
	 *
	 * @param array $field The field being edited.
	 * @return void
	 */
	public function render_field_role_setting( $field ) {
		// Get available Schema.org properties based on common types.
		acf_render_field_setting(
			$field,
			array(
				'label'        => __( 'Schema.org Property', 'acf' ),
				'instructions' => __( 'Map this field to a Schema.org property instead of using additionalProperty.', 'acf' ),
				'type'         => 'select',
				'name'         => 'schema_property',
				'wrapper'      => array(
					'class' => 'acf-field-meta-box',
				),
				'choices'      => $this->get_schema_properties(),
				'allow_null'   => 1,
				'ui'           => 1,
				'experimental' => 1,
			)
		);
	}

	/**
	 * Get available Schema.org roles
	 *
	 * Returns a hierarchical array of Schema.org properties organized by type.
	 * Uses the complete schema.org vocabulary from SchemaData.
	 *
	 * @since 6.8.0
	 *
	 * @return array Array of properties grouped by Schema.org type.
	 */
	public function get_schema_properties() {
		// Start with default option.
		$roles = array(
			'' => __( 'Use additionalProperty (default)', 'acf' ),
		);

		// Get all properties grouped by type from schema.org vocabulary.
		$properties_by_type = Schema::get_properties_by_type();

		// Get priority types from Schema class.
		$priority_types = Schema::get_priority_types();

		// Add priority types first.
		foreach ( $priority_types as $type ) {
			if ( isset( $properties_by_type[ $type ] ) ) {
				$type_label           = sprintf( '%s Properties', $type );
				$roles[ $type_label ] = array();

				foreach ( $properties_by_type[ $type ] as $property ) {
					$roles[ $type_label ][ $property ] = $property;
				}

				// Remove from main array so we don't duplicate.
				unset( $properties_by_type[ $type ] );
			}
		}

		// Add remaining types alphabetically.
		foreach ( $properties_by_type as $type => $properties ) {
			// Skip types with no properties.
			if ( empty( $properties ) ) {
				continue;
			}

			$type_label           = sprintf( '%s Properties', $type );
			$roles[ $type_label ] = array();

			foreach ( $properties as $property ) {
				$roles[ $type_label ][ $property ] = $property;
			}
		}

		/**
		 * Filter the available Schema.org properties.
		 *
		 * Allows developers to add custom Schema.org properties or modify existing ones.
		 *
		 * @param array $properties The Schema.org role mappings grouped by type.
		 */
		return apply_filters( 'acf/schema/schema_properties', $roles );
	}
}
