<?php
/**
 * Amazon Product Type Service
 *
 * @package    MOMCS_Sync
 * @subpackage MOMCS_Sync/includes/common/services/amazon
 * @author     miniOrange
 */

declare(strict_types=1);

namespace MOMCS_Sync\Includes\Common\Services\Amazon;

use MOMCS_Sync\Includes\Common\Utils\Logger;
use MOMCS_Sync\Includes\Common\Exceptions\Amazon_Api_Exception;

use MOMCS_Sync\Includes\Common\Services\Handlers\API_Handler;
use MOMCS_Sync\Includes\Common\Utils\Marketplace_IDs;

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

/**
 * Class for handling Amazon product type definitions and schema validation.
 */
class Product_Type_Service {

	/**
	 * API Handler instance.
	 *
	 * @var API_Handler
	 */
	private $api_handler;

	/**
	 * Token Service instance.
	 *
	 * @var Token_Service
	 */
	private $token_service;

	/**
	 * Logger instance.
	 *
	 * @var Logger
	 */
	private $logger;

	/**
	 * Product type definition endpoint path.
	 *
	 * @var string
	 */
	private $product_type_endpoint_path = '/definitions/2020-09-01/productTypes';

	/**
	 * Constructor.
	 */
	public function __construct() {
		$this->api_handler   = new API_Handler();
		$this->token_service = new Token_Service();
		$this->logger        = new Logger( 'product-type-service' );
	}

	/**
	 * Get dynamic base URL for Amazon API based on marketplace.
	 *
	 * @param string $marketplace_id Amazon marketplace ID.
	 * @return string Base URL.
	 */
	private function get_base_url( string $marketplace_id ): string {
		// Get dynamic URL based on marketplace.
		return Marketplace_IDs::get_api_base_url( $marketplace_id ) ?? 'https://sellingpartnerapi-eu.amazon.com';
	}

	/**
	 * Get product type definition from Amazon.
	 *
	 * @param string $channel_id     Channel UUID.
	 * @param string $product_type   Product type name.
	 * @param string $marketplace_id Amazon marketplace ID.
	 * @return array|WP_Error Product type definition or error.
	 * @throws Amazon_Api_Exception If API request fails.
	 */
	public function get_product_type_definition( $channel_id, $product_type, $marketplace_id ) {
		try {
			// Get access token.
			$access_token = $this->token_service->get_access_token( $channel_id );
			if ( is_wp_error( $access_token ) ) {
				return $access_token;
			}

			// Prepare request URL.
			$base_url = $this->get_base_url( $marketplace_id );
			$endpoint = $base_url . $this->product_type_endpoint_path . '/' . $product_type;
			$url      = add_query_arg(
				array(
					'marketplaceIds' => $marketplace_id,
				),
				$endpoint
			);

			// Make API request.
			$response = $this->api_handler->get(
				$url,
				array(
					'X-AMZ-Access-Token' => $access_token,
				)
			);

			// Check for errors.
			if ( is_wp_error( $response ) ) {
				return $response;
			}

			// Parse response.
			$definition = json_decode( wp_remote_retrieve_body( $response ), true );

			return $definition;
		} catch ( Amazon_Api_Exception $e ) {
			$this->logger->error( $e->getMessage() );
			throw $e;
		}
	}

	/**
	 * Get JSON schema for a product type.
	 *
	 * @param string $channel_id     Channel UUID.
	 * @param string $product_type   Product type name.
	 * @param string $marketplace_id Amazon marketplace ID.
	 * @return array|WP_Error JSON schema or error.
	 * @throws Amazon_Api_Exception If API request fails.
	 */
	public function get_product_type_schema( $channel_id, $product_type, $marketplace_id ) {
		try {
			// Get product type definition.
			$definition = $this->get_product_type_definition( $channel_id, $product_type, $marketplace_id );

			$this->logger->debug( 'Product type definition received: ' . ( is_array( $definition ) ? json_encode( array_keys( $definition ) ) : 'not an array' ) );

			// Check if schema URL is available.
			$schema_url = '';
			if ( isset( $definition['schema']['link']['resource'] ) && ! empty( $definition['schema']['link']['resource'] ) ) {
				$schema_url = $definition['schema']['link']['resource'];
				$this->logger->debug( 'Using schema URL from definition: ' . $schema_url );
			}

			// Get schema from URL.
			$this->logger->debug( 'Fetching schema from URL: ' . $schema_url );
			$response = wp_remote_get( $schema_url );

			// Check for errors.
			if ( is_wp_error( $response ) ) {
				$this->logger->debug( 'Error fetching schema: ' . $response->get_error_message() );
				$this->logger->debug( 'Using local schema file instead' );
			}

			$response_code = wp_remote_retrieve_response_code( $response );
			$this->logger->debug( 'Schema response code: ' . $response_code );

			// If response code is not 200, use local schema.
			if ( 200 !== $response_code ) {
				$this->logger->debug( 'Bad response code, using local schema file instead' );
			}

			$body = wp_remote_retrieve_body( $response );

			// Parse schema.
			$schema = json_decode( $body, true );

			if ( ! $schema ) {
				$this->logger->debug( 'JSON decode error: ' . json_last_error_msg() );
			}

			$this->logger->debug( 'Schema parsed successfully with keys: ' . ( is_array( $schema ) ? json_encode( array_keys( $schema ) ) : 'not an array' ) );

			return $schema;

		} catch ( Amazon_Api_Exception $e ) {
			$this->logger->error( $e->getMessage() );
			throw $e;
		}
	}

	/**
	 * Extract required fields from JSON schema.
	 *
	 * @param array $schema JSON schema.
	 * @return array Required fields with their details.
	 * @throws Amazon_Api_Exception If schema is not an array.
	 */
	public function extract_required_fields( $schema ) {
		$this->logger->debug( 'Extracting required fields from schema' );

		if ( ! is_array( $schema ) ) {
			$this->logger->debug( 'Schema is not an array: ' . gettype( $schema ) );
			return array();
		}

		$required_fields = array();

		// Check for direct required fields.
		if ( isset( $schema['required'] ) && is_array( $schema['required'] ) ) {
			$this->logger->debug( 'Found direct required fields: ' . json_encode( $schema['required'] ) );
			foreach ( $schema['required'] as $field ) {
				$required_fields[ $field ] = $this->get_field_details( $schema, $field );
			}
		} else {
			$this->logger->debug( 'No direct required fields found in schema' );
		}

		// Check for required fields in allOf conditions.
		if ( isset( $schema['allOf'] ) && is_array( $schema['allOf'] ) ) {
			$this->logger->debug( 'Found allOf conditions: ' . count( $schema['allOf'] ) );
			foreach ( $schema['allOf'] as $index => $condition ) {
				if ( isset( $condition['then']['required'] ) && is_array( $condition['then']['required'] ) ) {
					$this->logger->debug( 'Found required fields in condition ' . $index . ': ' . json_encode( $condition['then']['required'] ) );
					foreach ( $condition['then']['required'] as $field ) {
						if ( ! isset( $required_fields[ $field ] ) ) {
							$required_fields[ $field ] = $this->get_field_details( $schema, $field );
						}
					}
				}
			}
		} else {
			$this->logger->debug( 'No allOf conditions found in schema' );
		}

		$this->logger->debug( 'Total required fields found: ' . count( $required_fields ) );
		if ( count( $required_fields ) > 0 ) {
			$this->logger->debug( 'Required field names: ' . json_encode( array_keys( $required_fields ) ) );
		}

		return $required_fields;
	}

	/**
	 * Extract all fields from schema, marking required ones.
	 *
	 * @param array $schema JSON schema.
	 * @return array All fields with their details including a 'required' flag.
	 * @throws Amazon_Api_Exception If schema is not an array.
	 */
	public function extract_all_fields( $schema ) {
		$this->logger->debug( 'Extracting all fields from schema' );

		if ( ! is_array( $schema ) ) {
			$this->logger->debug( 'Schema is not an array: ' . gettype( $schema ) );
			return array();
		}

		$all_fields = array();

		// Get top-level required fields.
		$top_level_required = isset( $schema['required'] ) ? $schema['required'] : array();

		if ( isset( $schema['properties'] ) ) {
			foreach ( $schema['properties'] as $field_name => $field_schema ) {
				$this->extract_field_recursive( $field_name, $field_schema, $schema['required'] ?? array(), '', $all_fields, $top_level_required );
			}
		}

		return $all_fields;
	}

	/**
	 * Extract hierarchical field structure for frontend collapsible UI.
	 *
	 * @param array $schema JSON schema.
	 * @return array Hierarchical field structure.
	 * @throws Amazon_Api_Exception If schema is not an array.
	 */
	public function extract_hierarchical_fields( $schema ) {
		$this->logger->debug( 'Extracting hierarchical fields from schema' );

		if ( ! is_array( $schema ) ) {
			$this->logger->debug( 'Schema is not an array: ' . gettype( $schema ) );
			return array();
		}

		$hierarchical_fields = array();

		// Get top-level required fields.
		$top_level_required = isset( $schema['required'] ) ? $schema['required'] : array();

		if ( isset( $schema['properties'] ) ) {
			foreach ( $schema['properties'] as $field_name => $field_schema ) {
				$this->extract_hierarchical_field_recursive(
					$field_name,
					$field_schema,
					$schema['required'] ?? array(),
					$hierarchical_fields,
					$top_level_required
				);
			}
		}

		return $hierarchical_fields;
	}

	/**
	 * Recursively build hierarchical field structure.
	 *
	 * @param string $field_name Current field name.
	 * @param array  $field_schema Schema for this field.
	 * @param array  $required_fields List of required fields at this level.
	 * @param array  &$hierarchical_fields Reference to hierarchical structure.
	 * @param array  $top_level_required List of fields required at schema root.
	 * @throws Amazon_Api_Exception If schema is not an array.
	 */
	private function extract_hierarchical_field_recursive( $field_name, $field_schema, $required_fields, &$hierarchical_fields, $top_level_required ) {
		// Check if this field is required at top level.
		$is_top_level_required = in_array( $field_name, $top_level_required, true );

		// Handle array type with nested properties.
		if ( 'array' === $field_schema['type'] && isset( $field_schema['items']['properties'] ) ) {
			$children       = array();
			$items_required = $field_schema['items']['required'] ?? array();

			foreach ( $field_schema['items']['properties'] as $child_name => $child_schema ) {
				$is_child_required = in_array( $child_name, $items_required, true );
				$is_mappable       = $this->is_field_mappable( $child_name, $child_schema );

				$children[ $child_name ] = array(
					'title'           => $child_schema['title'] ?? ucfirst( str_replace( '_', ' ', $child_name ) ),
					'description'     => $child_schema['description'] ?? '',
					'type'            => $child_schema['type'] ?? 'string',
					'required'        => $is_top_level_required && $is_child_required,
					'nested_required' => $is_child_required,
					'mappable'        => $is_mappable,
					'enum'            => $child_schema['enum'] ?? null,
					'pattern'         => $child_schema['pattern'] ?? null,
				);

				// Handle nested structures within array items (recursive).
				if ( ! empty( $child_schema['type'] ) && 'object' === $child_schema['type'] && isset( $child_schema['properties'] ) ) {
					$children[ $child_name ]['children'] = array();
					$child_required                      = $child_schema['required'] ?? array();

					foreach ( $child_schema['properties'] as $nested_name => $nested_schema ) {
						$is_nested_required = in_array( $nested_name, $child_required, true );
						$is_nested_mappable = $this->is_field_mappable( $nested_name, $nested_schema );

						$children[ $child_name ]['children'][ $nested_name ] = array(
							'title'           => $nested_schema['title'] ?? ucfirst( str_replace( '_', ' ', $nested_name ) ),
							'description'     => $nested_schema['description'] ?? '',
							'type'            => $nested_schema['type'] ?? 'string',
							'required'        => $is_top_level_required && $is_child_required && $is_nested_required,
							'nested_required' => $is_nested_required,
							'mappable'        => $is_nested_mappable,
							'enum'            => $nested_schema['enum'] ?? null,
							'enumNames'       => $nested_schema['enumNames'] ?? null,
						);
					}
				} elseif ( ! empty( $child_schema['type'] ) && 'array' === $child_schema['type'] && isset( $child_schema['items']['properties'] ) ) {
					$children[ $child_name ]['children'] = array();
					$this->extract_nested_array_properties(
						$child_schema['items'],
						$children[ $child_name ]['children'],
						$is_top_level_required && $is_child_required
					);
				}
			}

			$hierarchical_fields[ $field_name ] = array(
				'title'       => $field_schema['title'] ?? ucfirst( str_replace( '_', ' ', $field_name ) ),
				'description' => $field_schema['description'] ?? '',
				'type'        => 'array',
				'required'    => $is_top_level_required,
				'parent'      => true,
				'children'    => $children,
			);
		} elseif ( ! empty( $field_schema['type'] ) && 'object' === $field_schema['type'] && isset( $field_schema['properties'] ) ) {
			$children        = array();
			$object_required = $field_schema['required'] ?? array();

			foreach ( $field_schema['properties'] as $child_name => $child_schema ) {
				$is_child_required = in_array( $child_name, $object_required, true );
				$is_mappable       = $this->is_field_mappable( $child_name, $child_schema );

				$children[ $child_name ] = array(
					'title'           => $child_schema['title'] ?? ucfirst( str_replace( '_', ' ', $child_name ) ),
					'description'     => $child_schema['description'] ?? '',
					'type'            => $child_schema['type'] ?? 'string',
					'required'        => $is_top_level_required && $is_child_required,
					'nested_required' => $is_child_required,
					'mappable'        => $is_mappable,
					'enum'            => $child_schema['enum'] ?? null,
				);
			}

			$hierarchical_fields[ $field_name ] = array(
				'title'       => $field_schema['title'] ?? ucfirst( str_replace( '_', ' ', $field_name ) ),
				'description' => $field_schema['description'] ?? '',
				'type'        => 'object',
				'required'    => $is_top_level_required,
				'parent'      => true,
				'children'    => $children,
			);
		} else {
			$is_mappable = $this->is_field_mappable( $field_name, $field_schema );

			$hierarchical_fields[ $field_name ] = array(
				'title'       => $field_schema['title'] ?? ucfirst( str_replace( '_', ' ', $field_name ) ),
				'description' => $field_schema['description'] ?? '',
				'type'        => $field_schema['type'] ?? 'string',
				'required'    => $is_top_level_required,
				'parent'      => false,
				'mappable'    => $is_mappable,
				'enum'        => $field_schema['enum'] ?? null,
				'pattern'     => $field_schema['pattern'] ?? null,
			);
		}
	}

	/**
	 * Recursively extract nested array properties with unlimited depth support.
	 *
	 * @param array $items_schema Schema for array items.
	 * @param array &$children Reference to children array to populate.
	 * @param bool  $parent_required Whether parent chain is required.
	 */
	private function extract_nested_array_properties( $items_schema, &$children, $parent_required ) {
		if ( ! isset( $items_schema['properties'] ) ) {
			return;
		}

		$items_required = $items_schema['required'] ?? array();

		foreach ( $items_schema['properties'] as $nested_name => $nested_schema ) {
			$is_nested_required = in_array( $nested_name, $items_required, true );
			$is_nested_mappable = $this->is_field_mappable( $nested_name, $nested_schema );

			$children[ $nested_name ] = array(
				'title'           => $nested_schema['title'] ?? ucfirst( str_replace( '_', ' ', $nested_name ) ),
				'description'     => $nested_schema['description'] ?? '',
				'type'            => $nested_schema['type'] ?? 'string',
				'required'        => $parent_required && $is_nested_required,
				'nested_required' => $is_nested_required,
				'mappable'        => $is_nested_mappable,
				'enum'            => $nested_schema['enum'] ?? null,
				'enumNames'       => $nested_schema['enumNames'] ?? null,
			);

			// Recursively handle deeper nesting.
			if ( ! empty( $nested_schema['type'] ) && 'array' === $nested_schema['type'] && isset( $nested_schema['items']['properties'] ) ) {
				$children[ $nested_name ]['children'] = array();
				$this->extract_nested_array_properties(
					$nested_schema['items'],
					$children[ $nested_name ]['children'],
					$parent_required && $is_nested_required
				);
			} elseif ( ! empty( $nested_schema['type'] ) && 'object' === $nested_schema['type'] && isset( $nested_schema['properties'] ) ) {
				$children[ $nested_name ]['children'] = array();
				$nested_required                      = $nested_schema['required'] ?? array();

				foreach ( $nested_schema['properties'] as $obj_name => $obj_schema ) {
					$is_obj_required = in_array( $obj_name, $nested_required, true );
					$is_obj_mappable = $this->is_field_mappable( $obj_name, $obj_schema );

					$children[ $nested_name ]['children'][ $obj_name ] = array(
						'title'           => $obj_schema['title'] ?? ucfirst( str_replace( '_', ' ', $obj_name ) ),
						'description'     => $obj_schema['description'] ?? '',
						'type'            => $obj_schema['type'] ?? 'string',
						'required'        => $parent_required && $is_nested_required && $is_obj_required,
						'nested_required' => $is_obj_required,
						'mappable'        => $is_obj_mappable,
						'enum'            => $obj_schema['enum'] ?? null,
						'enumNames'       => $obj_schema['enumNames'] ?? null,
					);

					// Continue recursion for objects and arrays within objects.
					if ( ! empty( $obj_schema['type'] ) && 'array' === $obj_schema['type'] && isset( $obj_schema['items']['properties'] ) ) {
						$children[ $nested_name ]['children'][ $obj_name ]['children'] = array();
						$this->extract_nested_array_properties(
							$obj_schema['items'],
							$children[ $nested_name ]['children'][ $obj_name ]['children'],
							$parent_required && $is_nested_required && $is_obj_required
						);
					}
				}
			}
		}
	}

	/**
	 * Check if a field should be mappable (exclude auto-handled fields).
	 *
	 * @param string $field_name Field name.
	 * @param array  $field_schema Field schema.
	 * @return bool True if field should be mappable.
	 */
	private function is_field_mappable( $field_name, $field_schema ) {
		// Skip marketplace_id and language_tag as they're auto-handled.
		$auto_handled_fields = array( 'marketplace_id', 'language_tag' );

		if ( in_array( $field_name, $auto_handled_fields, true ) ) {
			return false;
		}

		// Check if field references auto-handled definitions.
		if ( isset( $field_schema['$ref'] ) ) {
			foreach ( $auto_handled_fields as $auto_field ) {
				if ( strpos( $field_schema['$ref'], $auto_field ) !== false ) {
					return false;
				}
			}
		}

		return true;
	}

	/**
	 * Recursively extract field details from schema, handling nested objects and arrays.
	 *
	 * @param string $field_name Current field name.
	 * @param array  $field_schema Schema for this field.
	 * @param array  $required_fields List of required fields at this level.
	 * @param string $path_prefix Path accumulated so far.
	 * @param array  &$all_fields Reference to collection of all fields.
	 * @param array  $top_level_required List of fields required at schema root.
	 */
	private function extract_field_recursive( $field_name, $field_schema, $required_fields, $path_prefix, &$all_fields, $top_level_required ) {
		$current_path = $path_prefix ? $path_prefix . '.' . $field_name : $field_name;

		// Handle array type.
		if ( ! empty( $field_schema['type'] ) && 'array' === $field_schema['type'] && isset( $field_schema['items'] ) ) {
			if ( isset( $field_schema['items']['properties'] ) ) {
				foreach ( $field_schema['items']['properties'] as $item_field => $item_schema ) {
					$array_path = $current_path . '[]';
					$this->extract_field_recursive(
						$item_field,
						$item_schema,
						$field_schema['items']['required'] ?? array(),
						$array_path,
						$all_fields,
						$top_level_required
					);
				}
			}
			return;
		}

		// Handle object type.
		if ( ! empty( $field_schema['type'] ) && 'object' === $field_schema['type'] && isset( $field_schema['properties'] ) ) {
			foreach ( $field_schema['properties'] as $prop_name => $prop_schema ) {
				$this->extract_field_recursive(
					$prop_name,
					$prop_schema,
					$field_schema['required'] ?? array(),
					$current_path,
					$all_fields,
					$top_level_required
				);
			}
			return;
		}

		// Get the full path components.
		$path_parts = explode( '.', $current_path );
		$root_field = explode( '[', $path_parts[0] )[0];

		// Check if this field's root ancestor is in the top-level required list.
		$is_top_level_required = in_array( $root_field, $top_level_required, true );

		// Check if this specific field is required at its current nesting level.
		$is_nested_required = in_array( $field_name, $required_fields, true );

		/*
		 * A field is only truly required if:
		 * 1. Its root ancestor is in the top-level required array AND
		 * 2. It is itself required within its immediate parent's schema.
		 */
		$is_required = $is_top_level_required && $is_nested_required;

		/*
		 * A field should be marked as required ONLY if it is explicitly listed in
		 * the "required" array that applies to its own level (i.e. $required_fields).
		 * This prevents treating every descendant of a required parent as required.
		 */
		$details = array(
			'name'            => $current_path,
			'type'            => $field_schema['type'] ?? 'string',
			'title'           => $field_schema['title'] ?? '',
			'description'     => $field_schema['description'] ?? '',
			// Field is required only when its root is required AND it's required at its level.
			'required'        => $is_required,
			// Enable dropdown configuration for all fields.
			'configurable'    => true,
			// Keep track of nested requirement separately for styling/UI cues.
			'nested_required' => $is_nested_required,
		);

		// Add enum if present.
		if ( isset( $field_schema['enum'] ) ) {
			$details['enum'] = $field_schema['enum'];
		}

		// Add validation constraints if present.
		if ( isset( $field_schema['minLength'] ) ) {
			$details['minLength'] = $field_schema['minLength'];
		}
		if ( isset( $field_schema['maxLength'] ) ) {
			$details['maxLength'] = $field_schema['maxLength'];
		}

		$all_fields[ $current_path ] = $details;
	}

	/**
	 * Get field details from schema.
	 *
	 * @param array  $schema JSON schema.
	 * @param string $field  Field name.
	 * @return array Field details.
	 */
	private function get_field_details( $schema, $field ) {
		$details = array(
			'name'        => $field,
			'type'        => 'string',
			'description' => '',
			'required'    => true,
		);

		// Get field properties from schema.
		if ( isset( $schema['properties'][ $field ] ) ) {
			$field_schema = $schema['properties'][ $field ];

			if ( isset( $field_schema['type'] ) ) {
				$details['type'] = $field_schema['type'];
			}

			if ( isset( $field_schema['description'] ) ) {
				$details['description'] = $field_schema['description'];
			}

			// Add more field details as needed.
			if ( isset( $field_schema['enum'] ) ) {
				$details['enum'] = $field_schema['enum'];
			}

			if ( isset( $field_schema['minLength'] ) ) {
				$details['minLength'] = $field_schema['minLength'];
			}

			if ( isset( $field_schema['maxLength'] ) ) {
				$details['maxLength'] = $field_schema['maxLength'];
			}
		}

		// Check if field is defined in $defs.
		if ( isset( $schema['$defs'][ $field ] ) ) {
			$def_schema = $schema['$defs'][ $field ];

			if ( isset( $def_schema['type'] ) ) {
				$details['type'] = $def_schema['type'];
			}

			if ( isset( $def_schema['description'] ) ) {
				$details['description'] = $def_schema['description'];
			}

			// Add more field details as needed.
			if ( isset( $def_schema['enum'] ) ) {
				$details['enum'] = $def_schema['enum'];
			}
		}

		return $details;
	}

	/**
	 * Validate product data against JSON schema.
	 *
	 * @param array $product_data Product data.
	 * @param array $schema       JSON schema.
	 * @return array|WP_Error Validation result or error.
	 */
	public function validate_product_data( $product_data, $schema ) {
		// Basic validation for required fields.
		$errors = array();

		// Check for direct required fields.
		if ( isset( $schema['required'] ) && is_array( $schema['required'] ) ) {
			foreach ( $schema['required'] as $field ) {
				if ( ! isset( $product_data[ $field ] ) || empty( $product_data[ $field ] ) ) {
					$errors[] = sprintf( 'Required field "%s" is missing', $field );
				}
			}
		}

		// Check for required fields in allOf conditions.
		if ( isset( $schema['allOf'] ) && is_array( $schema['allOf'] ) ) {
			foreach ( $schema['allOf'] as $index => $condition ) {
				// Check if condition has an "if" clause.
				if ( isset( $condition['if'] ) ) {
					$if_condition  = $condition['if'];
					$condition_met = $this->check_if_condition( $if_condition, $product_data );

					// If condition is met, check the "then" requirements.
					if ( $condition_met && isset( $condition['then']['required'] ) ) {
						foreach ( $condition['then']['required'] as $field ) {
							if ( ! isset( $product_data[ $field ] ) || empty( $product_data[ $field ] ) ) {
								$errors[] = sprintf( 'Required field "%s" is missing (condition %d)', $field, $index );
							}
						}
					}
				}
			}
		}

		if ( ! empty( $errors ) ) {
			return new \WP_Error( 'validation_failed', 'Product data validation failed', $errors );
		}

		return array( 'valid' => true );
	}

	/**
	 * Check if a condition is met.
	 *
	 * @param array $if_condition If condition from schema.
	 * @param array $product_data Product data.
	 * @return bool Whether condition is met.
	 */
	private function check_if_condition( $if_condition, $product_data ) {
		// Check for "not" condition.
		if ( isset( $if_condition['not'] ) ) {
			return ! $this->check_if_condition( $if_condition['not'], $product_data );
		}

		// Check for "required" condition.
		if ( isset( $if_condition['required'] ) ) {
			foreach ( $if_condition['required'] as $field ) {
				if ( ! isset( $product_data[ $field ] ) || empty( $product_data[ $field ] ) ) {
					return false;
				}
			}
			return true;
		}

		// Check for "properties" condition.
		if ( isset( $if_condition['properties'] ) ) {
			foreach ( $if_condition['properties'] as $field => $field_condition ) {
				if ( ! isset( $product_data[ $field ] ) ) {
					return false;
				}

				// Add more specific property checks as needed.
			}
			return true;
		}

		return false;
	}

	/**
	 * Get a basic fallback schema for specific product types.
	 *
	 * @param string $product_type Product type name.
	 * @return array Basic schema with common required fields.
	 */
	private function get_fallback_schema_for_product_type( $product_type ) {
		$this->logger->debug( 'Using fallback schema for product type: ' . $product_type );

		// Basic schema structure with common fields.
		$schema = array(
			'required'   => array( 'title', 'brand', 'manufacturer', 'product_description' ),
			'properties' => array(
				'title'               => array(
					'type'        => 'string',
					'description' => 'Product title',
				),
				'brand'               => array(
					'type'        => 'string',
					'description' => 'Brand name',
				),
				'manufacturer'        => array(
					'type'        => 'string',
					'description' => 'Manufacturer name',
				),
				'product_description' => array(
					'type'        => 'string',
					'description' => 'Product description',
				),
				'bullet_point'        => array(
					'type'        => 'array',
					'description' => 'Product bullet points',
					'items'       => array(
						'type' => 'string',
					),
				),
				'item_dimensions'     => array(
					'type'        => 'object',
					'description' => 'Product dimensions',
					'properties'  => array(
						'length' => array(
							'type'       => 'object',
							'properties' => array(
								'value' => array( 'type' => 'number' ),
								'unit'  => array( 'type' => 'string' ),
							),
						),
						'width'  => array(
							'type'       => 'object',
							'properties' => array(
								'value' => array( 'type' => 'number' ),
								'unit'  => array( 'type' => 'string' ),
							),
						),
						'height' => array(
							'type'       => 'object',
							'properties' => array(
								'value' => array( 'type' => 'number' ),
								'unit'  => array( 'type' => 'string' ),
							),
						),
					),
				),
			),
		);

		// Add product type specific fields.
		switch ( $product_type ) {
			case 'LUGGAGE':
				$schema['required'][]          = 'color';
				$schema['required'][]          = 'size';
				$schema['properties']['color'] = array(
					'type'        => 'string',
					'description' => 'Product color',
				);
				$schema['properties']['size']  = array(
					'type'        => 'string',
					'description' => 'Product size',
				);
				break;

			case 'SHOES':
				$schema['required'][]          = 'color';
				$schema['required'][]          = 'size';
				$schema['properties']['color'] = array(
					'type'        => 'string',
					'description' => 'Shoe color',
				);
				$schema['properties']['size']  = array(
					'type'        => 'string',
					'description' => 'Shoe size',
				);
				break;

			case 'MAJOR_APPLIANCES':
				$schema['required'][]            = 'wattage';
				$schema['properties']['wattage'] = array(
					'type'        => 'object',
					'description' => 'Appliance wattage',
					'properties'  => array(
						'value' => array( 'type' => 'number' ),
						'unit'  => array( 'type' => 'string' ),
					),
				);
				break;

			case 'COMPUTERS':
				$schema['required'][]                    = 'processor_type';
				$schema['required'][]                    = 'hard_drive_size';
				$schema['properties']['processor_type']  = array(
					'type'        => 'string',
					'description' => 'Processor type',
				);
				$schema['properties']['hard_drive_size'] = array(
					'type'        => 'object',
					'description' => 'Hard drive size',
					'properties'  => array(
						'value' => array( 'type' => 'number' ),
						'unit'  => array( 'type' => 'string' ),
					),
				);
				break;
		}

		return $schema;
	}
}
