<?php
/**
 * Promostandards Sanmar Canada Supplier Implementation
 *
 * @package    Common
 * @subpackage Suppliers
 */
namespace MOWCPS\Common\Suppliers;
use MOWCPS\Common\Abstracts\Base_Supplier_App;
use MOWCPS\Common\Constants\Constants;
use MOWCPS\Common\Constants\Plugin_Filters;
use MOWCPS\Common\Utils\Configuration_Loader;

if ( ! defined( 'ABSPATH' ) ) {
	die;
}
/**
 * Class Promostandards_Sanmar_Ca
 */
class Promostandards_Sanmar_Ca extends Base_Supplier_App {
	/**
	 * Maps overlay JSON keys under "Connections" to connection "name" in the Promostandards template.
	 *
	 * @var array<string, string>
	 */
	private static $connections_overlay_aliases = array(
		'Products'         => 'Products',
		'Name_Description' => 'Name Description',
		'Prices'           => 'Prices',
		'Stocks'           => 'Stocks',
		'Images'           => 'Images',
	);
	/**
	 * WC attribute name => default API connection used when expanding compact attribute_mapping.
	 *
	 * @var array<string, string>
	 */
	private static $compact_attribute_connection_defaults = array(
		'stock_quantity' => 'Stocks',
		'regular_price'  => 'Prices',
	);
	/**
	 * Constructor
	 */
	public function __construct() {
		parent::__construct( Constants::SUPPLIER_APP_TYPE_PROMOSTANDARDS_SANMAR_CA );
	}
	/**
	 * Perform connection test for Promostandards Sanmar Canada
	 *
	 * @param array $authorization_config Authorization configuration.
	 * @return array|\WP_Error Success response or error.
	 */
	public function get_supplier_config( $authorization_config ) {
		$processed_config = $this->load_and_process_configuration( $authorization_config );
		if ( is_wp_error( $processed_config ) ) {
			return $this->get_test_result(
				false,
				sprintf( Constants::SUPPLIER_CONFIG_LOADING_FAILED, $this->supplier_name, $processed_config->get_error_message() ),
			);
		}
		return $processed_config;
	}
	/**
	 * Perform connection test
	 *
	 * @param array $supplier_data Supplier data.
	 * @return array Test result.
	 */
	public function perform_connection_test( $supplier_data ) {}
	/**
	 * Validate supplier-specific configuration
	 *
	 * @param array $configuration Supplier configuration.
	 * @return true|\WP_Error True on success, WP_Error on failure.
	 */
	public function validate_supplier_specific_configuration( $configuration ) {}
	/**
	 * Expand fragment-style JSON (Connections + optional compact attribute_mapping) into a full supplier template.
	 *
	 * @param array $config Loaded promostandards-sanmar-ca.json.
	 * @return array|\WP_Error Full template or error loading base.
	 */
	public static function resolve_full_template( array $config ) {
		if ( empty( $config['Connections'] ) ) {
			return $config;
		}
		$base = Configuration_Loader::load_supplier_config( 'promostandards' );
		if ( is_wp_error( $base ) ) {
			return $base;
		}
		return self::merge_promostandards_sanmar_ca_overlay( $base, $config );
	}
	/**
	 * Merge Sanmar CA overlay (Connections, attribute_mapping) onto the base Promostandards template.
	 *
	 * @param array $base    Full promostandards.json structure.
	 * @param array $overlay Loaded promostandards-sanmar-ca.json (may include Connections).
	 * @return array
	 */
	public static function merge_promostandards_sanmar_ca_overlay( array $base, array $overlay ) {
		$merged = $base;
		if ( ! empty( $overlay['Connections'] ) && is_array( $overlay['Connections'] ) ) {
			foreach ( $merged['connections'] as $idx => $conn ) {
				$name = $conn['name'] ?? '';
				if ( '' === $name ) {
					continue;
				}
				$overlay_key = array_search( $name, self::$connections_overlay_aliases, true );
				if ( false === $overlay_key || empty( $overlay['Connections'][ $overlay_key ] ) ) {
					continue;
				}
				$slice = self::normalize_connections_overlay_slice( $overlay['Connections'][ $overlay_key ], $name );
				if ( ! empty( $slice['configuration'] ) ) {
					$merged['connections'][ $idx ]['configuration'] = array_replace_recursive(
						$conn['configuration'],
						$slice['configuration']
					);
				}
			}
		}
		if ( ! empty( $overlay['attribute_mapping'] ) && is_array( $overlay['attribute_mapping'] ) ) {
			$merged['attribute_mapping'] = self::merge_attribute_mapping_lists(
				$merged['attribute_mapping'] ?? array(),
				$overlay['attribute_mapping']
			);
		}
		foreach ( $merged['connections'] as $conn ) {
			$n = $conn['name'] ?? '';
			if ( '' !== $n && ! empty( $conn['configuration']['body']['data'] ) ) {
				$merged[ str_replace( ' ', '_', $n ) . '_body' ] = $conn['configuration']['body']['data'];
			}
		}
		return $merged;
	}
	/**
	 * Normalize overlay slices where endpoint/body were placed under prerequisites, and Images_* sibling keys.
	 *
	 * @param array  $slice Overlay entry under Connections.{Key}.
	 * @param string $connection_name Resolved connection name (e.g. Images).
	 * @return array{configuration: array}
	 */
	private static function normalize_connections_overlay_slice( array $slice, $connection_name ) {
		$cfg = isset( $slice['configuration'] ) && is_array( $slice['configuration'] ) ? $slice['configuration'] : array();
		if ( isset( $cfg['prerequisites']['endpoint'] ) ) {
			if ( empty( $cfg['endpoint'] ) ) {
				$cfg['endpoint'] = $cfg['prerequisites']['endpoint'];
			}
			unset( $cfg['prerequisites']['endpoint'] );
		}
		if ( isset( $cfg['prerequisites']['body']['data'] ) && is_string( $cfg['prerequisites']['body']['data'] ) ) {
			if ( empty( $cfg['body']['data'] ) ) {
				$cfg['body'] = array(
					'type' => 'xml',
					'data' => $cfg['prerequisites']['body']['data'],
				);
			}
			unset( $cfg['prerequisites']['body'] );
		}
		if ( 'Images' === $connection_name ) {
			if ( ! empty( $slice['Images_endpoint'] ) && empty( $cfg['endpoint'] ) ) {
				$cfg['endpoint'] = $slice['Images_endpoint'];
			}
			if ( ! empty( $slice['Images_body'] ) && empty( $cfg['body']['data'] ) ) {
				$cfg['body'] = array(
					'type' => 'xml',
					'data' => $slice['Images_body'],
				);
			}
		}
		return array( 'configuration' => $cfg );
	}
	/**
	 * @param array $base_mappings Mappings from promostandards.json.
	 * @param array $overlay_rows  Rows from overlay (compact or standard).
	 * @return array
	 */
	private static function merge_attribute_mapping_lists( array $base_mappings, array $overlay_rows ) {
		$first = $overlay_rows[0] ?? null;
		if ( self::is_compact_attribute_mapping_row( $first ) ) {
			$expanded = self::expand_compact_attribute_mapping( $first );
			$wc_attrs = array();
			foreach ( $expanded as $row ) {
				if ( ! empty( $row['wc_attribute'] ) ) {
					$wc_attrs[] = $row['wc_attribute'];
				}
			}
			$filtered = array();
			foreach ( $base_mappings as $row ) {
				if ( empty( $row['wc_attribute'] ) ) {
					$filtered[] = $row;
					continue;
				}
				if ( ! in_array( $row['wc_attribute'], $wc_attrs, true ) ) {
					$filtered[] = $row;
				}
			}
			return array_merge( $filtered, $expanded );
		}
		return array_replace_recursive( $base_mappings, $overlay_rows );
	}
	/**
	 * @param mixed $row First attribute_mapping row.
	 */
	private static function is_compact_attribute_mapping_row( $row ) {
		if ( ! is_array( $row ) ) {
			return false;
		}
		foreach ( array_keys( self::$compact_attribute_connection_defaults ) as $wc_attr ) {
			if ( isset( $row[ $wc_attr ] ) && is_array( $row[ $wc_attr ] ) ) {
				return true;
			}
		}
		return false;
	}
	/**
	 * @param array $compact Single object holding wc_attribute keys.
	 * @return array<int, array<string, mixed>>
	 */
	private static function expand_compact_attribute_mapping( array $compact ) {
		$out = array();
		foreach ( $compact as $wc_attr => $spec ) {
			if ( ! is_array( $spec ) ) {
				continue;
			}
			$conn = self::$compact_attribute_connection_defaults[ $wc_attr ] ?? 'Name Description';
			if ( isset( $spec['parent']['supplier_attribute'] ) ) {
				$out[] = array(
					'connection'             => $conn,
					'product_type'           => Constants::ATTRIBUTE_MAPPING_PRODUCT_TYPE_PARENT,
					'type'                   => Constants::ATTRIBUTE_MAPPING_TYPE_CORE,
					'wc_attribute'           => $wc_attr,
					'supplier_attribute'     => $spec['parent']['supplier_attribute'],
					'advanced_configuration' => null,
				);
			}
			if ( isset( $spec['variant']['supplier_attribute'] ) ) {
				$out[] = array(
					'connection'             => $conn,
					'product_type'           => Constants::ATTRIBUTE_MAPPING_PRODUCT_TYPE_VARIANT,
					'type'                   => Constants::ATTRIBUTE_MAPPING_TYPE_CORE,
					'wc_attribute'           => $wc_attr,
					'supplier_attribute'     => $spec['variant']['supplier_attribute'],
					'advanced_configuration' => null,
				);
			}
		}
		return $out;
	}
	/**
	 * Alter product data
	 *
	 * @param array $arguments Arguments.
	 * @return array Arguments.
	 */
	public static function alter_product_data( $arguments ) {
		if ( Plugin_Filters::FILTER_CURRENT_DATA_ALTERATION_FILTER === $arguments['event_specifier'] ) {
			$current_data                           = $arguments['product_data'];
			$prod_id                                = $current_data['productId'];
			$prod_id                                = self::remove_parentheses_content( $prod_id );
			$arguments['product_data']['productId'] = $prod_id;
		}
		return $arguments;
	}
	/**
	 * Remove parentheses content from product ID
	 *
	 * @param string $prod_id Product ID.
	 * @return string Product ID.
	 */
	public static function remove_parentheses_content( $prod_id ) {
		return preg_replace( '/\s*\(.*?\)/', '', $prod_id );
	}
}
