<?php

namespace wpbuddy\rich_snippets\pro;

use wpbuddy\rich_snippets\Schema_Property;
use wpbuddy\rich_snippets\Schemas_Model;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
} // Exit if accessed directly


/**
 * Class Fields.
 *
 * Prepares HTML fields to use.
 *
 * @package wpbuddy\rich_snippets
 *
 * @since   2.19.0
 */
class Fields_Model extends \wpbuddy\rich_snippets\Fields_Model {

	/**
	 * Fields_Model constructor.
	 * @since 2.19.0
	 */
	public function __construct() {
		parent::__construct();

		add_filter( 'wpbuddy/rich_snippets/fields/link_to_subselect/values', [ $this, 'more_references' ] );
		add_filter( 'wpbuddy/rich_snippets/fields/internal_subselect/values', [ $this, 'more_internal_values' ] );
		remove_filter( 'wpbuddy/rich_snippets/fields/internal_subselect/values', [
			'\wpbuddy\rich_snippets\Fields_Model',
			'more_internal_values_from_pro_preview'
		] );
	}


	/**
	 * More internal values.
	 *
	 * @param array $values
	 *
	 * @return array
	 * @since 2.19.5
	 */
	public function more_internal_values( $values ) {

		$textfield_meta = [
			'id'          => 'textfield_meta',
			'label'       => esc_html_x( 'Post meta field', 'subselect field', 'rich-snippets-schema' ),
			'description' => __( 'Enter the name of the meta field.', 'rich-snippets-schema' ),
		];

		$textfield_usermeta = [
			'id'          => 'textfield_usermeta',
			'label'       => esc_html_x( 'User meta field', 'subselect field', 'rich-snippets-schema' ),
			'description' => __( 'Enter the name of the meta field.', 'rich-snippets-schema' ),
		];

		$textfield_user = [
			'id'          => 'textfield_user',
			'label'       => esc_html_x( 'User field', 'subselect field', 'rich-snippets-schema' ),
			'description' => __( 'Enter the name of the field from the database that you want to load.', 'rich-snippets-schema' ),
		];

		$textfield_block_content = [
			'id'          => 'textfield_block_content',
			'label'       => esc_html_x( 'Block content', 'subselect field', 'rich-snippets-schema' ),
			'description' => __( 'Enter the CSS class name of the block.', 'rich-snippets-schema' ),
		];

		$textfield_termmeta = [
			'id'          => 'textfield_termmeta',
			'label'       => esc_html_x( 'Term meta field', 'subselect field', 'rich-snippets-schema' ),
			'description' => __( 'Enter the name of the term meta field.', 'rich-snippets-schema' ),
		];

		$textfield_option_string = [
			'id'          => 'textfield_option_string',
			'label'       => esc_html_x( 'Option', 'subselect field', 'rich-snippets-schema' ),
			'description' => __( 'Enter the name of the option from the WordPress options database table.', 'rich-snippets-schema' )
		];

		$textfield_option_date = [
			'id'          => 'textfield_option_date',
			'label'       => $textfield_option_string['label'],
			'description' => $textfield_option_string['description']
		];

		$textfield_option_integer = [
			'id'          => 'textfield_option_integer',
			'label'       => $textfield_option_string['label'],
			'description' => $textfield_option_string['description']
		];

		$textfield_option_time = [
			'id'          => 'textfield_option_time',
			'label'       => $textfield_option_string['label'],
			'description' => $textfield_option_string['description']
		];

		$textfield_option_url = [
			'id'          => 'textfield_option_url',
			'label'       => $textfield_option_string['label'],
			'description' => $textfield_option_string['description']
		];

		$textfield_sequential_number = [
			'id'          => 'textfield_sequential_number',
			'label'       => esc_html_x( 'Sequential Number', 'subselect field', 'rich-snippets-schema' ),
			'description' => __( 'Enter a name for the counter.', 'rich-snippets-schema' )
		];

		$values['http://schema.org/Text'][] = $textfield_meta;
		$values['http://schema.org/Text'][] = $textfield_usermeta;
		$values['http://schema.org/Text'][] = $textfield_user;
		$values['http://schema.org/Text'][] = $textfield_termmeta;
		$values['http://schema.org/Text'][] = $textfield_option_string;
		$values['http://schema.org/Text'][] = $textfield_block_content;
		$values['http://schema.org/Text'][] = array(
			'id'    => 'term_title',
			'label' => esc_html_x( 'Term title (loop and archive pages only)', 'subselect field', 'rich-snippets-schema' ),
		);
		$values['http://schema.org/Text'][] = array(
			'id'    => 'current_post_content',
			'label' => esc_html_x( 'Post content', 'subselect field', 'rich-snippets-schema' ),
		);
		$values['http://schema.org/Text'][] = array(
			'id'    => 'term_description',
			'label' => esc_html_x( 'Term description (archive pages only)', 'subselect field', 'rich-snippets-schema' ),
		);
		$values['http://schema.org/Text'][] = array(
			'id'    => 'textfield_userdata',
			'label' => esc_html_x( 'Userdata', 'subselect field', 'rich-snippets-schema' ),
		);

		$values['http://schema.org/XPathType'][] = $textfield_meta;
		$values['http://schema.org/XPathType'][] = $textfield_usermeta;
		$values['http://schema.org/XPathType'][] = $textfield_user;
		$values['http://schema.org/XPathType'][] = $textfield_termmeta;
		$values['http://schema.org/XPathType'][] = $textfield_option_string;

		$values['http://schema.org/Integer'][] = $textfield_meta;
		$values['http://schema.org/Integer'][] = $textfield_usermeta;
		$values['http://schema.org/Integer'][] = $textfield_user;
		$values['http://schema.org/Integer'][] = $textfield_block_content;
		$values['http://schema.org/Integer'][] = $textfield_termmeta;
		$values['http://schema.org/Integer'][] = $textfield_option_integer;
		$values['http://schema.org/Integer'][] = $textfield_sequential_number;
		$values['http://schema.org/Integer'][] = array(
			'id'    => 'term_description',
			'label' => esc_html_x( 'Term description (archive pages only)', 'subselect field', 'rich-snippets-schema' ),
		);

		$values['http://schema.org/Time'][] = $textfield_meta;
		$values['http://schema.org/Time'][] = $textfield_usermeta;
		$values['http://schema.org/Time'][] = $textfield_user;
		$values['http://schema.org/Time'][] = $textfield_block_content;
		$values['http://schema.org/Time'][] = $textfield_termmeta;
		$values['http://schema.org/Time'][] = $textfield_option_time;

		$values['http://schema.org/DayOfWeek'][] = $textfield_meta;
		$values['http://schema.org/DayOfWeek'][] = $textfield_usermeta;
		$values['http://schema.org/DayOfWeek'][] = $textfield_user;
		$values['http://schema.org/DayOfWeek'][] = $textfield_block_content;
		$values['http://schema.org/DayOfWeek'][] = $textfield_termmeta;

		$values['http://schema.org/Date'][] = $textfield_meta;
		$values['http://schema.org/Date'][] = $textfield_usermeta;
		$values['http://schema.org/Date'][] = $textfield_user;
		$values['http://schema.org/Date'][] = $textfield_block_content;
		$values['http://schema.org/Date'][] = $textfield_termmeta;
		$values['http://schema.org/Date'][] = $textfield_option_date;
		$values['http://schema.org/Date'][] = array(
			'id'    => 'term_description',
			'label' => esc_html_x( 'Term description (archive pages only)', 'subselect field', 'rich-snippets-schema' ),
		);

		$values['http://schema.org/URL'][] = $textfield_meta;
		$values['http://schema.org/URL'][] = $textfield_usermeta;
		$values['http://schema.org/URL'][] = $textfield_user;
		$values['http://schema.org/URL'][] = $textfield_block_content;
		$values['http://schema.org/URL'][] = $textfield_termmeta;
		$values['http://schema.org/URL'][] = $textfield_option_url;
		$values['http://schema.org/URL'][] = array(
			'id'    => 'search_url_search_term',
			'label' => esc_html_x( 'Search URL (with {search_term_string} placeholder)', 'subselect field', 'rich-snippets-schema' ),
		);
		$values['http://schema.org/URL'][] = array(
			'id'    => 'search_url',
			'label' => esc_html_x( 'Search URL', 'subselect field', 'rich-snippets-schema' ),
		);
		$values['http://schema.org/URL'][] = array(
			'id'    => 'term_url',
			'label' => esc_html_x( 'Term URL (loop and archive pages only)', 'subselect field', 'rich-snippets-schema' ),
		);
		$values['http://schema.org/URL'][] = array(
			'id'    => 'term_description',
			'label' => esc_html_x( 'Term description (archive pages only)', 'subselect field', 'rich-snippets-schema' ),
		);

		$values['http://schema.org/Duration'][] = $textfield_meta;
		$values['http://schema.org/Duration'][] = $textfield_usermeta;
		$values['http://schema.org/Duration'][] = $textfield_user;
		$values['http://schema.org/Duration'][] = $textfield_block_content;
		$values['http://schema.org/Duration'][] = $textfield_termmeta;

		$values['http://schema.org/Intangible'][] = $textfield_meta;
		$values['http://schema.org/Intangible'][] = $textfield_usermeta;
		$values['http://schema.org/Intangible'][] = $textfield_user;
		$values['http://schema.org/Intangible'][] = $textfield_block_content;
		$values['http://schema.org/Intangible'][] = $textfield_termmeta;

		$values['http://schema.org/Quantity'][] = $textfield_meta;
		$values['http://schema.org/Quantity'][] = $textfield_usermeta;
		$values['http://schema.org/Quantity'][] = $textfield_user;
		$values['http://schema.org/Quantity'][] = $textfield_block_content;
		$values['http://schema.org/Quantity'][] = $textfield_termmeta;
		$values['http://schema.org/Quantity'][] = $textfield_option_integer;

		$values['http://schema.org/Energy'][] = $textfield_meta;
		$values['http://schema.org/Energy'][] = $textfield_usermeta;
		$values['http://schema.org/Energy'][] = $textfield_user;
		$values['http://schema.org/Energy'][] = $textfield_block_content;
		$values['http://schema.org/Energy'][] = $textfield_termmeta;

		$values['http://schema.org/Mass'][] = $textfield_meta;
		$values['http://schema.org/Mass'][] = $textfield_usermeta;
		$values['http://schema.org/Mass'][] = $textfield_user;
		$values['http://schema.org/Mass'][] = $textfield_block_content;
		$values['http://schema.org/Mass'][] = $textfield_termmeta;

		$values['http://schema.org/CssSelectorType'][] = $textfield_meta;
		$values['http://schema.org/CssSelectorType'][] = $textfield_usermeta;
		$values['http://schema.org/CssSelectorType'][] = $textfield_user;
		$values['http://schema.org/CssSelectorType'][] = $textfield_termmeta;

		$values['http://schema.org/DeliveryMethod'][] = $textfield_meta;
		$values['http://schema.org/DeliveryMethod'][] = $textfield_usermeta;
		$values['http://schema.org/DeliveryMethod'][] = $textfield_user;
		$values['http://schema.org/DeliveryMethod'][] = $textfield_block_content;
		$values['http://schema.org/DeliveryMethod'][] = $textfield_termmeta;

		$taxonomies = get_taxonomies( [ 'show_ui' => true ], 'objects' );

		foreach ( $taxonomies as $taxonomy ) {
			$values['http://schema.org/Text'][] = [
				'id'    => 'taxonomy_' . $taxonomy->name,
				'label' => sprintf(
					__( 'Comma separated list of %s', 'rich-snippets-schema' ),
					esc_html( $taxonomy->label )
				),
			];
		}

		return $values;
	}

	/**
	 * Adds Global Snippets to the list of references.
	 *
	 * @param array $values
	 *
	 * @return array
	 *
	 * @since 2.19.0
	 */
	public static function more_references( $values ) {
		$global_posts = call_user_func( function () {

			$cache = wp_cache_get( 'post_reference_values', 'wpb_rs' );

			if ( is_array( $cache ) ) {
				return $cache;
			}

			global $wpdb, $post;

			$sql = "SELECT pm.meta_value as global_schemas, p.post_title, p.ID "
			       . " FROM {$wpdb->posts} p "
			       . " LEFT JOIN {$wpdb->postmeta} as pm ON (p.ID = pm.post_id AND pm.meta_key = '_wpb_rs_schema') "
			       . " WHERE p.post_status = 'publish' AND p.post_type = 'wpb-rs-global' ";

			if ( isset( $post ) && $post instanceof \WP_Post ) {
				# do not include Post ID
				$sql .= sprintf( ' AND p.ID != "%d" ', $post->ID );
			}

			$results = $wpdb->get_results( $sql );

			if ( ! is_array( $results ) ) {
				wp_cache_set( 'post_reference_values', array(), 'wpb_rs', MINUTE_IN_SECONDS );

				return array();
			}

			$values = array();

			foreach ( $results as $result ) {
				$global_schemas = maybe_unserialize( $result->global_schemas );
				if ( ! is_array( $global_schemas ) ) {
					continue;
				}

				/**
				 * @var \wpbuddy\rich_snippets\Rich_Snippet $global_schema
				 */
				foreach ( $global_schemas as $snippet_uid => $global_schema ) {
					$values[ 'global_snippet_' . $snippet_uid ] = sprintf(
						_x( 'Global snippet: %2$s/%1$s (%3$d)', '%1$s is the title of the global schema. %2$s is the schema class name. %3$d is the post ID', 'rich-snippets-schema' ),
						$result->post_title,
						$global_schema->type,
						$result->ID
					);
				}
			}

			wp_cache_set( 'post_reference_values', $values, 'wpb_rs', MINUTE_IN_SECONDS );

			return $values;

		} );

		$values = array_merge( $values, $global_posts );

		return $values;
	}


	/**
	 * Returns a list of values available for loops.
	 *
	 * @return array
	 * @since 2.8.0
	 *
	 */
	public static function get_loop_values() {
		$values = [
			''             => __( 'No loop', 'rich-snippets-schema' ),
			'main_query'   => __( 'Main query items (ie. for archive pages)', 'rich-snippets-schema' ),
			'page_parents' => __( 'Page parents', 'rich-snippets-schema' ),
		];

		$menus = call_user_func( function () {
			$values = [];

			$menus = wp_get_nav_menus();

			foreach ( $menus as $menu ) {
				if ( ! is_object( $menu ) ) {
					continue;
				}

				if ( ! isset( $menu->term_id ) ) {
					continue;
				}

				if ( ! isset( $menu->name ) ) {
					continue;
				}

				$values[ 'menu_' . $menu->term_id ] = sprintf(
					_x( 'Menu: %s', 'Menu label', 'rich-snippets-schema' ),
					esc_html( $menu->name )
				);
			}

			return $values;
		} );

		$values = array_merge( $values, $menus );

		$taxonomies = call_user_func( function () {
			$values = [];

			/**
			 * @var \WP_Taxonomy[]
			 */
			$taxonomies = get_taxonomies(
				[ 'public' => true ],
				'objects'
			);

			foreach ( $taxonomies as $tax_key => $tax ) {
				$values[ 'taxonomy_' . $tax_key ] = sprintf(
					_x( 'Taxonomy: %s', 'Taxonomy label', 'rich-snippets-schema' ),
					esc_html( $tax->label )
				);
			}

			return $values;
		} );

		$values = array_merge( $values, $taxonomies );

		/**
		 * 'loop' subselect values filter.
		 *
		 * This filter can be used to add additional options to the 'link to' subfield select.
		 *
		 * @hook  wpbuddy/rich_snippets/fields/loop_subselect/values
		 *
		 * @param {array} $values The return parameter: an array of values.
		 * @returns {array} An array of values.
		 *
		 * @since 2.8.0
		 */
		$values = apply_filters(
			'wpbuddy/rich_snippets/fields/loop_subselect/values',
			$values
		);

		return $values;
	}


	/**
	 * Fetches 'loop' subselect options.
	 *
	 * @param Schema_Property $prop
	 * @param string $schema
	 * @param string $selected The selected item.
	 *
	 * @return string[] Array of HTML <option> fields.
	 * @since 2.8.0
	 *
	 */
	public static function get_loop_subselect_options( $schema, $selected ) {
		$options = array();

		$values = self::get_loop_values();

		foreach ( $values as $value => $label ) {
			$options[] = sprintf(
				'<option data-use-textfield="%s" value="%s" %s>%s</option>',
				false !== stripos( $value, 'textfield' ) ? 1 : 0,
				$value,
				selected( $selected, $value, false ),
				esc_html( $label )
			);
		}

		/**
		 * Internal 'loop' values.
		 *
		 * This filter can be used to add additional options to the 'loop' subselect.
		 *
		 * @hook  wpbuddy/rich_snippets/fields/loop_subselect/options
		 *
		 * @param {array}  $options The return parameter: an array of options.
		 * @param {string} $schema   The current schema class.
		 * @param {string} $selected The current selected item.
		 *
		 * @returns {array} An array of options.
		 *
		 * @since 2.8.0
		 */
		return apply_filters(
			'wpbuddy/rich_snippets/fields/loop_subselect/options',
			$options,
			$schema,
			$selected
		);
	}


}