<?php

namespace CTXFeed\V5\Product;

use CTXFeed\V5\Utility\Cache;
use Woo_Feed_Custom_Identifier_Filter;

/**
 * The file that defines the merchants attributes
 *
 * A class definition that includes attributes and functions used across the
 * admin area.
 *
 * @link       https://webappick.com/
 * @since      1.0.0
 *
 * @package    Woo_Feed
 * @subpackage Woo_Feed/includes
 * @author     Ohidul Islam <wahid@webappick.com>
 */
class ProductAttributeFactory {
	/**
	 * Hold Product Attributes.
	 *
	 * @var $attributes
	 */
	public $attributes;

	/**
	 * Safe unserialize that prevents PHP Object Injection.
	 *
	 * @param mixed $data The data to unserialize.
	 * @return mixed The unserialized data or original if not serialized.
	 */
	private static function safe_unserialize( $data ) {
		if ( ! is_string( $data ) ) {
			return $data;
		}
		if ( ! is_serialized( $data ) ) {
			return $data;
		}
		// Use allowed_classes = false to prevent object instantiation
		return @unserialize( $data, array( 'allowed_classes' => false ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_unserialize
	}

	/**
	 * Get Product Attributes
	 *
	 * @return string|array
	 */
	public static function getAttributes() {
		return self::setAttributes();
	}

	/**
	 * @return mixed|array
	 */
	private static function setAttributes() {
		$attributes        = [];
		$primaryAttributes = [
			'optionGroup' => esc_html__( 'Primary Attributes', 'woo-feed' ),
			'options'     => [
				'id'                    => esc_html__( 'Product Id', 'woo-feed' ),
				'title'                 => esc_html__( 'Product Title', 'woo-feed' ),
				'parent_title'          => esc_html__( 'Parent Title', 'woo-feed' ),
				'description'           => esc_html__( 'Product Description', 'woo-feed' ),
				'parent_description'    => esc_html__( 'Parent Description', 'woo-feed' ),
				'description_with_html' => esc_html__( 'Product Description (with HTML)', 'woo-feed' ),
				'short_description'     => esc_html__( 'Product Short Description', 'woo-feed' ),
				'primary_category'      => esc_html__( 'Parent Category', 'woo-feed' ),
				'primary_category_id'   => esc_html__( 'Parent Category ID', 'woo-feed' ),
				'child_category'        => esc_html__( 'Child Category', 'woo-feed' ),
				'child_category_id'     => esc_html__( 'Child Category ID', 'woo-feed' ),
				'product_type'          => esc_html__( 'Product Category [Category Path]', 'woo-feed' ),
				'product_full_cat'      => esc_html__( 'Product Full Category [Category Full Path]', 'woo-feed' ),
				'link'                  => esc_html__( 'Product URL', 'woo-feed' ),
				'parent_link'           => esc_html__( 'Parent URL', 'woo-feed' ),
				'canonical_link'        => esc_html__( 'Canonical URL', 'woo-feed' ),
				'ex_link'               => esc_html__( 'External Product URL', 'woo-feed' ),
				'add_to_cart_link'      => esc_html__( 'Add to Cart URL', 'woo-feed' ),
				'item_group_id'         => esc_html__( 'Parent Id [Group Id]', 'woo-feed' ),
				'sku'                   => esc_html__( 'SKU', 'woo-feed' ),
				'sku_id'                => esc_html__( 'SKU_ID', 'woo-feed' ),
				'parent_sku'            => esc_html__( 'Parent SKU', 'woo-feed' ),
				'availability'          => esc_html__( 'Availability', 'woo-feed' ),
				'availability_date'     => esc_html__( 'Availability Date', 'woo-feed' ),
				'quantity'              => esc_html__( 'Quantity', 'woo-feed' ),
				'reviewer_name'         => esc_html__( 'Reviewer Name', 'woo-feed' ),
				'weight'                => esc_html__( 'Weight', 'woo-feed' ),
				'weight_unit'           => esc_html__( 'Weight Unit', 'woo-feed' ),
				'width'                 => esc_html__( 'Width', 'woo-feed' ),
				'height'                => esc_html__( 'Height', 'woo-feed' ),
				'length'                => esc_html__( 'Length', 'woo-feed' ),
				'type'                  => esc_html__( 'Product Type', 'woo-feed' ),
				'visibility'            => esc_html__( 'Visibility', 'woo-feed' ),
				'rating_total'          => esc_html__( 'Total Rating', 'woo-feed' ),
				'rating_average'        => esc_html__( 'Average Rating', 'woo-feed' ),
				'tags'                  => esc_html__( 'Tags', 'woo-feed' ),
				'is_bundle'             => esc_html__( 'Is Bundle', 'woo-feed' ),
				'author_name'           => esc_html__( 'Author Name', 'woo-feed' ),
				'author_email'          => esc_html__( 'Author Email', 'woo-feed' ),
				'date_created'          => esc_html__( 'Date Created', 'woo-feed' ),
				'date_updated'          => esc_html__( 'Date Updated', 'woo-feed' ),
				'product_status'        => esc_html__( 'Product Status', 'woo-feed' ),
				'featured_status'        => esc_html__( 'Featured Status', 'woo-feed' ),
				'checkout_link_template' => esc_html__( 'Checkout Link Template', 'woo-feed' ),
				'gtin_upc_ean_isbn'      => esc_html__( 'GTIN,UPC,EAN, or ISBN', 'woo-feed' ),
			]
		];

		$attributes [] = $primaryAttributes;


		$imageAttributes = [
			'optionGroup' => esc_html__( 'Images', 'woo-feed' ),
			'options'     => [
				'image'         => esc_html__( 'Main Image', 'woo-feed' ),
				'feature_image' => esc_html__( 'Featured Image', 'woo-feed' ),
				'images'        => esc_html__( 'Images [Comma Separated]', 'woo-feed' ),
				'image_1'       => esc_html__( 'Additional Image 1', 'woo-feed' ),
				'image_2'       => esc_html__( 'Additional Image 2', 'woo-feed' ),
				'image_3'       => esc_html__( 'Additional Image 3', 'woo-feed' ),
				'image_4'       => esc_html__( 'Additional Image 4', 'woo-feed' ),
				'image_5'       => esc_html__( 'Additional Image 5', 'woo-feed' ),
				'image_6'       => esc_html__( 'Additional Image 6', 'woo-feed' ),
				'image_7'       => esc_html__( 'Additional Image 7', 'woo-feed' ),
				'image_8'       => esc_html__( 'Additional Image 8', 'woo-feed' ),
				'image_9'       => esc_html__( 'Additional Image 9', 'woo-feed' ),
				'image_10'      => esc_html__( 'Additional Image 10', 'woo-feed' ),
			],
		];

		$attributes [] = $imageAttributes;

		$priceAttributes = [
			'optionGroup' => esc_html__( 'Price', 'woo-feed' ),
			'options'     => [
				'currency'                  => esc_html__( 'Currency', 'woo-feed' ),
				'price'                     => esc_html__( 'Regular Price', 'woo-feed' ),
				'current_price'             => esc_html__( 'Price', 'woo-feed' ),
				'sale_price'                => esc_html__( 'Sale Price', 'woo-feed' ),
				'price_with_tax'            => esc_html__( 'Regular Price With Tax', 'woo-feed' ),
				'current_price_with_tax'    => esc_html__( 'Price With Tax', 'woo-feed' ),
				'sale_price_with_tax'       => esc_html__( 'Sale Price With Tax', 'woo-feed' ),
				'sale_price_sdate'          => esc_html__( 'Sale Start Date', 'woo-feed' ),
				'sale_price_edate'          => esc_html__( 'Sale End Date', 'woo-feed' ),
				'sale_price_effective_date' => esc_html__( 'Sale Price Effective Date', 'woo-feed' ),
			],
		];

		$attributes [] = $priceAttributes;

		$shippingAttributes = [
			'optionGroup' => esc_html__( 'Shipping', 'woo-feed' ),
			'options'     => [
				'shipping'       => esc_html__( 'Shipping (Google Format)', 'woo-feed' ),
				'shipping_class' => esc_html__( 'Shipping Class', 'woo-feed' ),
//				'shipping_zone_name' => esc_html__( 'Shipping Zone Name', 'woo-feed' ),
//				'shipping_country'   => esc_html__( 'Shipping Country', 'woo-feed' ),
//				'shipping_region'    => esc_html__( 'Shipping Regions', 'woo-feed' ),
//				'shipping_postcode'  => esc_html__( 'Shipping Postcodes', 'woo-feed' ),
//				'shipping_service'   => esc_html__( 'Shipping Method Name', 'woo-feed' ),
//				'shipping_price'     => esc_html__( 'Shipping Cost', 'woo-feed' ),
			],
		];

		$attributes [] = $shippingAttributes;

		$taxAttributes = [
			'optionGroup' => esc_html__( 'Tax', 'woo-feed' ),
			'options'     => [
				'tax'       => esc_html__( 'Tax (Google Format)', 'woo-feed' ),
				'tax_class' => esc_html__( 'Tax Class', 'woo-feed' ),
//				'tax_status'   => esc_html__( 'Tax Status', 'woo-feed' ),
//				'tax_country'  => esc_html__( 'Tax Country', 'woo-feed' ),
//				'tax_state'    => esc_html__( 'Tax State', 'woo-feed' ),
//				'tax_postcode' => esc_html__( 'Tax Postcodes', 'woo-feed' ),
//				'tax_city'     => esc_html__( 'Tax City', 'woo-feed' ),
//				'tax_rate'     => esc_html__( 'Tax Rate', 'woo-feed' ),
//				'tax_label'    => esc_html__( 'Tax Name', 'woo-feed' ),
			],
		];

		$attributes [] = $taxAttributes;

		$subscriptionAttributes = [
			'optionGroup' => esc_html__( 'Subscription & Installment', 'woo-feed' ),
			'options'     => [
				'subscription_period'          => esc_html__( 'Subscription Period', 'woo-feed' ),
				'subscription_period_interval' => esc_html__( 'Subscription Period Length', 'woo-feed' ),
				'subscription_amount'          => esc_html__( 'Subscription Amount', 'woo-feed' ),
				'installment_months'           => esc_html__( 'Installment Months', 'woo-feed' ),
				'installment_amount'           => esc_html__( 'Installment Amount', 'woo-feed' ),
			],
		];

		$customXMLAttributes = [
			'optionGroup' => esc_html__( 'Custom Template 2 (XML)', 'woo-feed' ),
			'options'     => [
				'custom_xml_variations' => esc_html__( 'Product Variations', 'woo-feed' ),
				'custom_xml_images'     => esc_html__( 'Product Gallery Images', 'woo-feed' ),
				'custom_xml_categories' => esc_html__( 'Product Categories', 'woo-feed' ),
			]
		];

		/**
		 * Add subscription attributes if WooCommerce Subscription plugin installed.
		 *
		 * @link https://woocommerce.com/products/woocommerce-subscriptions/
		 */
		if ( class_exists( 'WC_Subscriptions' ) ) {
			$attributes[] = $subscriptionAttributes;
		}

		$attributes[] = self::getPluginsCustomFields();
		$attributes[] = self::getUnitPriceAttributes();
		$attributes[] = self::getSeoPluginAttributes();
		$attributes[] = self::getGlobalAttributes();
		$attributes[] = self::getCustomAttributes();
		$attributes[] = self::getAllTaxonomy();
		$attributes[] = self::getAllOptions();
		// Category Mapping
		$attributes[] = self::getCategoryMappedAttributes();
		// ACF Plugin custom fields getACFAttributes
		$attributes[] = self::getACFAttributes();
		// Custom Fields & Post Metas
		$attributes[] = self::getProductMetaKeyAttributes();

		if ( defined( 'WOO_FEED_PRO_VERSION' ) ) { //  class_exists( 'Woo_Feed_Products_v3_Pro' )
			$attributes [] = self::getMultiLanguageAttributes();
			$attributes [] = self::getMultiVendorAttributes();
			// Dynamic Attributes
			$attributes[] = self::getDynamicAttributes();
			// Attribute Mappings
			$attributes[] = self::getCustomMappedAttributes();
			// Custom Template 2 Attributes
			$attributes [] = $customXMLAttributes;
		}

		return apply_filters( 'woo_feed_product_attribute_dropdown', $attributes );
	}

	/**
	 * Get CTX Feed plugins Custom Fields.
	 *
	 * @return array
	 */
	private static function getPluginsCustomFields() {

		$custom_fields            = woo_feed_product_custom_fields();
		$custom_identifier_filter = new Woo_Feed_Custom_Identifier_Filter( $custom_fields );
		$custom_identifier        = iterator_to_array( $custom_identifier_filter );
		$activeAttributes         = [ 'optionGroup' => esc_html__( 'Custom Fields by CTX Feed', 'woo-feed' ), ];
		if ( ! empty( $custom_identifier ) ) {
			foreach ( $custom_identifier as $key => $value ) {
				$activeAttributes['options'][ 'woo_feed_identifier_' . sanitize_text_field( wp_unslash( $key ) ) ] = sanitize_text_field( $value[0] );
			}
		}

		return ! empty( $activeAttributes['options'] ) ? $activeAttributes : [];
	}

	/**
	 * Get Unit Price Attributes.
	 *
	 * @return array
	 */
	private static function getUnitPriceAttributes() {

		$unitPriceAttributes = [
//			'optionGroup' => esc_html__( 'Unit Price (CTX Feed)', 'woo-feed' ),
//			'options'     => [
//				'unit_price_unit'         => esc_html__( 'Unit', 'woo-feed' ),
//				'unit_price_measure'      => esc_html__( 'Unit Price Measure', 'woo-feed' ),
//				'unit_price_base_measure' => esc_html__( 'Unit Price Base Measure', 'woo-feed' ),
//			],
		];

		/**
		 * Get Germanized for WooCommerce plugins unit attributes.
		 *
		 * @link https://wordpress.org/plugins/woocommerce-germanized/
		 */
		if ( class_exists( 'WooCommerce_Germanized' ) ) {
			$wcUnitPriceAttributes = [
				'optionGroup' => esc_html__( 'Unit Price (WooCommerce Germanized)', 'woo-feed' ),
				'options'     => [
					'wc_germanized_unit_price_measure'      => esc_html__( 'Unit Price Measure', 'woo-feed' ),
					'wc_germanized_unit_price_base_measure' => esc_html__( 'Unit Price Base Measure', 'woo-feed' ),
					'wc_germanized_gtin'                    => esc_html__( 'GTIN', 'woo-feed' ),
					'wc_germanized_mpn'                     => esc_html__( 'MPN', 'woo-feed' ),
				],
			];
			$unitPriceAttributes   += $wcUnitPriceAttributes;
		}

		return $unitPriceAttributes;
	}

	/**
	 * Get installed SEO plugin attributes.
	 * Uses filter hooks to allow compatibility classes to provide their attributes.
	 *
	 * @return array
	 */
	private static function getSeoPluginAttributes() {
		/**
		 * Filter to allow SEO compatibility plugins to add their attributes.
		 *
		 * @param array $seoAttributes Empty array to be populated by compatibility classes.
		 * @return array SEO plugin attributes array with 'optionGroup' and 'options' keys.
		 */
		$seoAttributes = apply_filters( 'woo_feed_seo_plugin_attributes', [] );

		return $seoAttributes;
	}

	/**
	 * Get Product Global Attributes.
	 *
	 * @retun array
	 */
	private static function getGlobalAttributes() {
		$taxonomies = Cache::get( 'getAttributeTaxonomies' );
		if ( false === $taxonomies ) {
			// Load the main attributes
			$globalAttributes = wc_get_attribute_taxonomy_labels();
			if ( count( $globalAttributes ) ) {
				foreach ( $globalAttributes as $key => $value ) {
					$taxonomies[ AttributeValueByType::PRODUCT_ATTRIBUTE_PREFIX . 'pa_' . $key ] = $value;
				}
			}
			Cache::set( 'getAttributeTaxonomies', $taxonomies );
		}

		return [
			'optionGroup' => esc_html__( 'Product Attributes', 'woo-feed' ),
			'options'     => $taxonomies,
		];
	}

	/**
	 * Get Product Custom Attributes.
	 *
	 * @retun array
	 */
	private static function getCustomAttributes() {
		$attributes = Cache::get( 'woo_feed_dropdown_product_custom_attributes' );
		if ( false === $attributes ) {
			// Get Variation Attributes
			$attributes = self::queryVariationsAttributes();
			// Get Product Custom Attributes
			$attributes += self::queryCustomAttributes();

			Cache::set( 'woo_feed_dropdown_product_custom_attributes', $attributes );
		}

		return [
			'optionGroup' => esc_html__( 'Product Custom Attributes', 'woo-feed' ),
			'options'     => $attributes,
		];
	}

	/**
	 * Get Variation Attributes
	 * Local attributes will be found on variation product meta only with attribute_ suffix
	 */
	private static function queryVariationsAttributes() {
		// Get Variation Attributes
		global $wpdb;
		$attributes = array();
		$sql        = "SELECT DISTINCT( meta_key ) FROM $wpdb->postmeta
			WHERE post_id IN (
			    SELECT ID FROM $wpdb->posts WHERE post_type = 'product_variation' -- local attributes will be found on variation product meta only with attribute_ suffix
			) AND (
			    meta_key LIKE 'attribute_%' -- include only product attributes from meta list
			    AND meta_key NOT LIKE 'attribute_pa_%'
			)";
		// sanitization ok
		$localAttributes = $wpdb->get_col( $sql ); // phpcs:ignore

		foreach ( $localAttributes as $localAttribute ) {
			$localAttribute                                                                 = str_replace( 'attribute_', '', $localAttribute );
			$attributes[ AttributeValueByType::PRODUCT_ATTRIBUTE_PREFIX . $localAttribute ] = ucwords( str_replace( '-', ' ', $localAttribute ) );
		}

		return $attributes;
	}

	/**
	 * Get Product Custom Attributes
	 */
	private static function queryCustomAttributes() {
		global $wpdb;
		$attributes       = array();
		$sql              = 'SELECT meta.meta_id, meta.meta_key as name, meta.meta_value as type FROM ' . $wpdb->postmeta . ' AS meta, ' . $wpdb->posts . " AS posts WHERE meta.post_id = posts.id AND posts.post_type LIKE '%product%' AND meta.meta_key='_product_attributes';";
		$customAttributes = $wpdb->get_results( $sql ); // phpcs:ignore
		if ( ! empty( $customAttributes ) ) {
			foreach ( $customAttributes as $value ) {
				$product_attr = self::safe_unserialize( $value->type );
				if ( is_array( $product_attr ) ) {
					foreach ( $product_attr as $key => $arr_value ) {
						if ( \is_string( $key ) && strpos( $key, 'pa_' ) === false && isset( $arr_value['name'] ) ) {
							$attributes[ AttributeValueByType::PRODUCT_ATTRIBUTE_PREFIX . $key ] = ucwords( str_replace( '-', ' ', $arr_value['name'] ) );
						}
					}
				}
			}
		}

		return $attributes;
	}

	/**
	 * Get All Taxonomy
	 *
	 * @return array
	 */
	private static function getAllTaxonomy() {
		$info = Cache::get( 'woo_feed_dropdown_product_taxonomy' );
		if ( false === $info ) {
			$info = array();
			global $wp_taxonomies;
			$default_excludes = array(
				'product_type',
				'product_visibility',
				'product_cat',
				'product_tag',
				'product_shipping_class',
				'translation_priority',
			);

			/**
			 * Exclude Taxonomy from dropdown
			 *
			 * @param array $user_excludes
			 * @param array $default_excludes
			 */

			$user_excludes    = apply_filters( 'woo_feed_dropdown_exclude_taxonomy', null, $default_excludes );
			$default_excludes = ! empty( $user_excludes ) ? array_merge( $default_excludes, $user_excludes ) : $default_excludes;

			foreach ( get_object_taxonomies( 'product' ) as $value ) {
				$value = \is_string( $value ) && ! empty( $value ) ? trim( $value ) : '';
				if ( in_array( $value, $default_excludes, true ) || strpos( $value, 'pa_' ) !== false ) {
					continue;
				}
				$label                                                          = isset( $wp_taxonomies[ $value ] ) ? $wp_taxonomies[ $value ]->label . " [$value]" : $value;
				$info[ AttributeValueByType::PRODUCT_TAXONOMY_PREFIX . $value ] = $label;
			}

			Cache::set( 'woo_feed_dropdown_product_taxonomy', $info );
		}

		return [
			'optionGroup' => esc_html__( 'Product Taxonomies', 'woo-feed' ),
			'options'     => $info,
		];
	}

	/**
	 * Get All Options
	 *
	 * @return array
	 */
	private static function getAllOptions() {
		$_wp_options     = wp_list_pluck( get_option( 'wpfp_option', array() ), 'option_name' );
		$_wp_options_val = str_replace( 'wf_option_', '', $_wp_options );
		$_wp_options     = array_combine( $_wp_options, $_wp_options_val );

		return [
			'optionGroup' => esc_html__( 'Options', 'woo-feed' ),
			'options'     => $_wp_options,
		];
	}

	/**
	 * Get Category Mappings
	 *
	 * @return array
	 */
	private static function getCategoryMappedAttributes() {
		global $wpdb;
		// Load Custom Category Mapped Attributes
		$info = array();
		// query cached and escaped
		$data = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_name LIKE %s;", AttributeValueByType::PRODUCT_CATEGORY_MAPPING_PREFIX . '%' ) );  // phpcs:ignore
		if ( count( $data ) ) {
			foreach ( $data as $value ) {
				$opts                        = self::safe_unserialize( $value->option_value );
				$opts                        = self::safe_unserialize( $opts );
				$info[ $value->option_name ] = is_array( $opts ) && isset( $opts['mappingname'] ) ? $opts['mappingname'] : str_replace(
					'wf_cmapping_',
					'',
					$value->option_name
				);
			}
		}

		return [
			'optionGroup' => esc_html__( 'Category Mapping', 'woo-feed' ),
			'options'     => $info,
		];
	}

	/**
	 * Get Advance Custom Field (ACF) field list.
	 * Uses filter hooks to allow compatibility classes to provide ACF fields.
	 *
	 * @return array
	 */
	private static function getACFAttributes() {
		/**
		 * Filter to allow ACF compatibility plugin to provide field list.
		 *
		 * @param array $options Empty array to be populated by ACF compatibility class.
		 * @return array ACF fields array with field key => field title.
		 */
		$options = apply_filters( 'woo_feed_acf_field_list', [] );

		return [
			'optionGroup' => esc_html__( 'Advance Custom Fields (ACF)', 'woo-feed' ),
			'options'     => $options,
		];
	}

	/**
	 * Get All Custom Attributes
	 *
	 * @return array
	 */
	private static function getProductMetaKeyAttributes() {
		$info = Cache::get( 'woo_feed_dropdown_meta_keys' );
		if ( false === $info ) {
			global $wpdb;
			$info = [];
			// Load the main attributes.

			$default_exclude_keys = [
				// WP internals.
				'_edit_lock',
				'_wp_old_slug',
				'_edit_last',
				'_wp_old_date',
				// WC internals.
				'_downloadable_files',
				'_sku',
				'_weight',
				'_width',
				'_height',
				'_length',
				'_file_path',
				'_file_paths',
				'_default_attributes',
				'_product_attributes',
				'_children',
				'_variation_description',
				// ignore variation description, engine will get child product description from WC CRUD WC_Product::get_description().
				// Plugin Data.
				'_wpcom_is_markdown',
				// JetPack Meta.
				'_yith_wcpb_bundle_data',
				// Yith product bundle data.
				'_et_builder_version',
				// Divi builder data.
				'_vc_post_settings',
				// Visual Composer (WP Bakery) data.
				'_enable_sidebar',
				'frs_woo_product_tabs',
				// WooCommerce Custom Product Tabs http://www.skyverge.com/.
			];

			/**
			 * Exclude meta keys from dropdown
			 *
			 * @param array $exclude              meta keys to exclude.
			 * @param array $default_exclude_keys Exclude keys by default.
			 */
			$user_exclude = apply_filters( 'woo_feed_dropdown_exclude_meta_keys', null, $default_exclude_keys );

			if ( is_array( $user_exclude ) && ! empty( $user_exclude ) ) {
				$user_exclude         = esc_sql( $user_exclude );
				$default_exclude_keys = array_merge( $default_exclude_keys, $user_exclude );
			}

			$default_exclude_keys = array_map( 'esc_sql', $default_exclude_keys );
			$exclude_keys         = '\'' . implode( '\', \'', $default_exclude_keys ) . '\'';

			$default_exclude_key_patterns = [
				'%_et_pb_%', // Divi builder data
				'attribute_%', // Exclude product attributes from meta list
				'_yoast_wpseo_%', // Yoast SEO Data
				'_acf-%', // ACF duplicate fields
				'_aioseop_%', // All In One SEO Pack Data
				'_oembed%', // exclude oEmbed cache meta
				'_wpml_%', // wpml metas
				'_oh_add_script_%', // SOGO Add Script to Individual Pages Header Footer.
			];

			/**
			 * Exclude meta key patterns from dropdown
			 *
			 * @param array $exclude                      meta keys to exclude.
			 * @param array $default_exclude_key_patterns Exclude keys by default.
			 */
			$user_exclude_patterns = apply_filters( 'woo_feed_dropdown_exclude_meta_keys_pattern', null, $default_exclude_key_patterns );
			if ( is_array( $user_exclude_patterns ) && ! empty( $user_exclude_patterns ) ) {
				$default_exclude_key_patterns = array_merge( $default_exclude_key_patterns, $user_exclude_patterns );
			}
			$exclude_key_patterns = '';
			foreach ( $default_exclude_key_patterns as $pattern ) {
				$exclude_key_patterns .= $wpdb->prepare( ' AND meta_key NOT LIKE %s', $pattern );
			}

			$sql = sprintf( /** @lang text */ "SELECT DISTINCT( meta_key ) FROM %s WHERE 1=1 AND post_id IN ( SELECT ID FROM %s WHERE post_type = 'product' OR post_type = 'product_variation' ) AND ( meta_key NOT IN ( %s ) %s )", $wpdb->postmeta, $wpdb->posts, $exclude_keys, $exclude_key_patterns );

			// sql escaped, cached
			$data = $wpdb->get_results( $sql ); // phpcs:ignore

			if ( count( $data ) ) {
				foreach ( $data as $value ) {
					//TODO Remove ACF Fields
					$info[ AttributeValueByType::POST_META_PREFIX . $value->meta_key ] = $value->meta_key;
				}
			}
			Cache::set( 'woo_feed_dropdown_meta_keys', $info );
		}

		return [
			'optionGroup' => esc_html__( 'Custom Fields & Post Metas', 'woo-feed' ),
			'options'     => $info,
		];
	}

	/**
	 * Get Dynamic Attribute List
	 *
	 * @return array
	 */
	private static function getDynamicAttributes() {
		global $wpdb;

		// Load Custom Category Mapped Attributes
		$info = array();
		// query escaped and cached
		$data = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_name LIKE %s;", AttributeValueByType::PRODUCT_DYNAMIC_ATTRIBUTE_PREFIX . '%' ) ); // phpcs:ignore
		if ( count( $data ) ) {
			foreach ( $data as $value ) {
				$opts                        = self::safe_unserialize( $value->option_value );
				$opts                        = self::safe_unserialize( $opts );
				$info[ $value->option_name ] = is_array( $opts ) && isset( $opts['wfDAttributeName'] ) ? $opts['wfDAttributeName'] : str_replace(
					'wf_dattribute_',
					'',
					$value->option_name
				);
			}
		}

		return [
			'optionGroup' => esc_html__( 'Dynamic Attributes', 'woo-feed' ),
			'options'     => $info,
		];
	}

	/**
	 * Get Attribute Mappings
	 *
	 * @return array
	 */
	private static function getCustomMappedAttributes() {
		global $wpdb;
		// Load Custom Category Mapped Attributes
		$info = [];
		// query cached and escaped
		$data = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_name LIKE %s;", AttributeValueByType::PRODUCT_ATTRIBUTE_MAPPING_PREFIX . '%' ) );  // phpcs:ignore
		if ( count( $data ) ) {
			foreach ( $data as $value ) {
				$opts                        = self::safe_unserialize( $value->option_value );
				$info[ $value->option_name ] = is_array( $opts ) && isset( $opts['name'] ) ? $opts['name'] : str_replace( AttributeValueByType::PRODUCT_ATTRIBUTE_MAPPING_PREFIX, '', $value->option_name );
			}
		}

		return [
			'optionGroup' => esc_html__( 'Attribute Mappings', 'woo-feed' ),
			'options'     => $info,
		];
	}

	/**
	 * @return array
	 */
	private static function getMultiLanguageAttributes() {
		$attributes = [];
		if ( class_exists( 'SitePress' ) ) {
			$attributes = [
				'optionGroup' => esc_html__( 'WPML Attributes', 'woo-feed' ),
				'options'     => [
					'parent_id' => esc_html__( 'Parent Product ID', 'woo-feed' )
				]
			];
		}

		return $attributes;
	}

	/**
	 * @return array
	 */
	private static function getMultiVendorAttributes() {
		$attributes = [];
		if ( function_exists( 'woo_feed_is_multi_vendor' ) && woo_feed_is_multi_vendor() ) {
			$attributes = [
				'optionGroup' => esc_html__( 'Multi Vendor Attributes', 'woo-feed' ),
				'options'     => [
					'vendor_store_name' => esc_html__( 'Vendor Store Name', 'woo-feed' )
				]
			];
		}

		return $attributes;
	}
}

