<?php

namespace ShopManagerPro\Products\Groups;

use ShopManagerPro\Products\Fields\DTO\ProductFieldGroupType;
use ShopManagerPro\Products\Fields\FieldNameEncoderService;
use ShopManagerPro\Products\Groups\DTO\ProductGroupUpdate;
use ShopManagerPro\Shared\Utils\Logger;

class ProductGroupUpdateService {
	public static function processProductGroupUpdates(\WC_Product $product, ProductGroupUpdate $productGroupUpdates) {
		\ShopManagerPro\ACF\ACFRepository::getACFFields();
		if ($productGroupUpdates->add) {
			foreach ($productGroupUpdates->add->fields as $fieldKey => $values) {
				self::updateField($product, $fieldKey, $values, 'add');
			}
		} if ($productGroupUpdates->remove) {
			foreach ($productGroupUpdates->remove->fields as $fieldKey => $values) {
				self::updateField($product, $fieldKey, $values, 'remove');
			}
		}
	}

	private static function updateField(\WC_Product $product, string $fieldKey, array $values, string $operation) {
		try {
			$decoded = FieldNameEncoderService::decode($fieldKey);
			$fieldType = $decoded->type;
			$fieldId = $decoded->key;
		} catch (\ValueError $e) {
			throw new \InvalidArgumentException("Invalid field format: $fieldKey. Fields must use type:key format (e.g., defaultTaxonomy:product_cat)");
		} switch ($fieldType) {
			case ProductFieldGroupType::ACF: self::updateACFField($product, intval($fieldId), $values, $operation);
				break;
			case ProductFieldGroupType::PRODUCT_ATTRIBUTE: case ProductFieldGroupType::DEFAULT_TAXONOMY: self::updateTaxonomyField($product, $fieldId, $values, $operation);
				break;
			default: throw new \InvalidArgumentException("Unsupported field type: {$fieldType->value} for field $fieldKey");
		}
	}

	private static function updateACFField(\WC_Product $product, int $fieldId, array $values, string $operation) {
		if (!\ShopManagerPro\Shared\PluginDetectorService::$acfVersion) {
			return;
		} $acfFields = \ShopManagerPro\ACF\ACFRepository::getACFFields();
		if (!isset($acfFields->acfFieldsById[$fieldId])) {
			Logger::error("ACF field with ID $fieldId not found in ACF fields repository.");

			return;
		} $acfField = $acfFields->acfFieldsById[$fieldId];
		$postId = $product->get_id();
		$currentValues = get_field($acfField->key, $postId);
		if ($acfField->multiple) {
			$currentValues = is_array($currentValues) ? $currentValues : [];
			switch ($operation) {
				case 'add': $newValues = array_unique(array_merge($currentValues, $values));
					break;
				case 'remove': $newValues = array_diff($currentValues, $values);
					break;
				default: throw new \InvalidArgumentException("Unknown operation: $operation for ACF field {$acfField->key}");
			} update_field($acfField->key, $newValues, $postId);
		} else {
			switch ($operation) {
				case 'add': if (!empty($values)) {
					update_field($acfField->key, $values[0], $postId);
				} break;
				case 'remove': $currentValue = $currentValues;
					if (in_array($currentValue, $values)) {
						delete_field($acfField->key, $postId);
					} break;
			}
		}
	}

	private static function updateTaxonomyField(\WC_Product $product, string $taxonomyKey, array $values, string $operation) {
		$termIds = array_map('intval', $values);
		$existingTerms = wp_get_object_terms($product->get_id(), $taxonomyKey, ['fields' => 'ids']);
		if (is_wp_error($existingTerms)) {
			$existingTerms = [];
		} $existingTermsArray = is_array($existingTerms) ? $existingTerms : [];
		switch ($operation) {
			case 'add': $newTerms = array_unique(array_merge($existingTermsArray, $termIds));
				break;
			case 'remove': $newTerms = array_diff($existingTermsArray, $termIds);
				break;
			default: throw new \InvalidArgumentException("Unknown operation: $operation for taxonomy $taxonomyKey");
		} wp_set_object_terms($product->get_id(), $newTerms, $taxonomyKey);
	}
}
