<?php
/**
 * Attribute Mapping Request DTO
 *
 * @category   WordPress_Plugin
 * @package    Common
 * @subpackage DTO
 * @author     miniOrange <info@miniorange.com>
 * @license    MIT/Expat
 * @link       https://plugins.miniorange.com/woocommerce-api-product-sync-with-woocommerce-rest-apis
 */

namespace MOWCPS\Common\DTO;

use WP_Error;
use MOWCPS\Common\Constants\Constants;
use MOWCPS\Common\Abstracts\Base_DTO;
use MOWCPS\Common\Utils\Utils;

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

/**
 * Class Attribute_Mapping_Request
 *
 * Handles attribute mapping request data transformation and validation
 */
class Attribute_Mapping_Request extends Base_DTO {

	/**
	 * Connection ID
	 *
	 * @var int
	 */
	private $connection_id;

	/**
	 * Product type
	 *
	 * @var string
	 */
	private $product_type;

	/**
	 * Mapping type
	 *
	 * @var string
	 */
	private $type;

	/**
	 * WooCommerce attribute
	 *
	 * @var string
	 */
	private $wc_attribute;

	/**
	 * Supplier attribute
	 *
	 * @var string
	 */
	private $supplier_attribute;

	/**
	 * Advanced configuration
	 *
	 * @var array|null
	 */
	private $advanced_configuration;

	/**
	 * Valid product types array
	 *
	 * @var array
	 */
	private static $valid_product_types = array(
		Constants::ATTRIBUTE_MAPPING_PRODUCT_TYPE_PARENT,
		Constants::ATTRIBUTE_MAPPING_PRODUCT_TYPE_VARIANT,
	);

	/**
	 * Valid mapping types array
	 *
	 * @var array
	 */
	private static $valid_types = array(
		Constants::ATTRIBUTE_MAPPING_TYPE_CORE,
		Constants::ATTRIBUTE_MAPPING_TYPE_ATTRIBUTE,
		Constants::ATTRIBUTE_MAPPING_TYPE_TAXONOMY,
		Constants::ATTRIBUTE_MAPPING_TYPE_CUSTOM,
		Constants::ATTRIBUTE_MAPPING_TYPE_INTEGRATION,
	);

	/**
	 * Create instance from request parameters
	 *
	 * @param array $params Request parameters.
	 * @return self|WP_Error Instance or error if validation fails
	 */
	public static function from_request_parameters( $params ) {
		$instance = new self();

		// Transform data.
		$instance->connection_id          = isset( $params['connection_id'] ) ? sanitize_text_field( wp_unslash( $params['connection_id'] ) ) : 0;
		$instance->product_type           = sanitize_text_field( wp_unslash( $params['product_type'] ?? Constants::ATTRIBUTE_MAPPING_PRODUCT_TYPE_PARENT ) );
		$instance->type                   = sanitize_text_field( wp_unslash( $params['type'] ?? Constants::ATTRIBUTE_MAPPING_TYPE_CORE ) );
		$instance->wc_attribute           = sanitize_text_field( wp_unslash( $params['wc_attribute'] ?? '' ) );
		$instance->advanced_configuration = isset( $params['advanced_configuration'] ) ? Utils::sanitize_json_field( wp_unslash( $params['advanced_configuration'] ) ) : null;

		// Allow description field to contain HTML.
		$supplier_attribute_value     = wp_unslash( $params['supplier_attribute'] ?? '' );
		$instance->supplier_attribute = ( 'description' === $instance->wc_attribute ) ? wp_kses_post( $supplier_attribute_value ) : sanitize_text_field( $supplier_attribute_value );

		return $instance->validate();
	}

	/**
	 * Validate the request data
	 *
	 * @return self|WP_Error Instance if valid, WP_Error if invalid
	 */
	protected function validate() {
		// Validate connection_id.
		if ( empty( $this->connection_id ) ) {
			return new WP_Error(
				Constants::ERROR_MISSING_REQUIRED_FIELD,
				sprintf( Constants::MSG_MISSING_REQUIRED_FIELD, 'connection_id' ),
				array( 'status' => Constants::HTTP_BAD_REQUEST )
			);
		}

		// Validate wc_attribute.
		if ( empty( $this->wc_attribute ) ) {
			return new WP_Error(
				Constants::ERROR_MISSING_REQUIRED_FIELD,
				sprintf( Constants::MSG_MISSING_REQUIRED_FIELD, 'wc_attribute' ),
				array( 'status' => Constants::HTTP_BAD_REQUEST )
			);
		}

		// Validate supplier_attribute.
		if ( ! isset( $this->supplier_attribute ) ) {
			return new WP_Error(
				Constants::ERROR_MISSING_REQUIRED_FIELD,
				sprintf( Constants::MSG_MISSING_REQUIRED_FIELD, 'supplier_attribute' ),
				array( 'status' => Constants::HTTP_BAD_REQUEST )
			);
		}

		// Validate product_type.
		if ( ! in_array( $this->product_type, self::$valid_product_types, true ) ) {
			return new WP_Error(
				Constants::ERROR_INVALID_PRODUCT_TYPE,
				Constants::MSG_INVALID_PRODUCT_TYPE,
				array( 'status' => Constants::HTTP_BAD_REQUEST )
			);
		}

		// Validate type.
		if ( ! in_array( $this->type, self::$valid_types, true ) ) {
			return new WP_Error(
				Constants::ERROR_INVALID_MAPPING_TYPE,
				Constants::MSG_INVALID_MAPPING_TYPE,
				array( 'status' => Constants::HTTP_BAD_REQUEST )
			);
		}

		// Validate advanced_configuration.
		if ( null !== $this->advanced_configuration && ! is_array( $this->advanced_configuration ) ) {
			return new WP_Error(
				Constants::ERROR_INVALID_CONFIGURATION,
				Constants::MSG_INVALID_CONFIGURATION,
				array( 'status' => Constants::HTTP_BAD_REQUEST )
			);
		}

		return $this;
	}

	/**
	 * Convert to array for database
	 *
	 * @return array Data ready for database
	 */
	public function to_array() {
		return array(
			'connection_id'          => $this->connection_id,
			'product_type'           => $this->product_type,
			'type'                   => $this->type,
			'wc_attribute'           => $this->wc_attribute,
			'supplier_attribute'     => $this->supplier_attribute,
			'advanced_configuration' => $this->advanced_configuration,
		);
	}
}
