<?php

namespace ShopManagerPro\Products\Fields;

use ShopManagerPro\Products\DTO\Generated\Product;
use ShopManagerPro\Products\Fields\DTO\Basic\BasicFieldKeys;
use ShopManagerPro\Products\Fields\DTO\FieldOperator;
use ShopManagerPro\Products\Fields\DTO\ProductFieldGroupType;
use ShopManagerPro\Products\Fields\DTO\ProductFieldType;
use ShopManagerPro\Products\ProductRepository;
use ShopManagerPro\Taxonomies\DTO\TaxonomyCollection;

class ProductFieldResolverService {
	public function __construct(public TaxonomyCollection $taxonomies, public \ShopManagerPro\ACF\DTO\ACFCollection $acfFields, public array $productAttributes) {
	}

	public static function createFromDatabase() {
		return new self(taxonomies: \ShopManagerPro\Taxonomies\TaxonomyRepository::getTaxonomies(), acfFields: \ShopManagerPro\ACF\ACFRepository::getACFFields(), productAttributes: ProductRepository::getProductAttributes());
	}

	public function resolveField(Product $product, string $fieldPath) {
		$parsedField = FieldNameEncoderService::decode($fieldPath);
		$type = $parsedField->type;

		return match ($type) {
			ProductFieldGroupType::ACF => $this->resolveAcfField($product, $parsedField->key), ProductFieldGroupType::BASIC => $this->resolveBasicField($product, $parsedField->key), ProductFieldGroupType::DEFAULT_TAXONOMY => $this->resolveTaxonomy($product->getDefaultTaxonomy(), $parsedField->key), ProductFieldGroupType::GERMAN_MARKET => $this->resolveGermanMarket($product, $parsedField->key), ProductFieldGroupType::META => $this->resolveCustomMeta($product, $parsedField->key), ProductFieldGroupType::PRODUCT_ATTRIBUTE => $this->resolveTaxonomy($product->getProductAttribute(), $parsedField->key), default => '???',
		};
	}

	private function resolveBasicField(Product $product, string $fieldPath) {
		$basic = $product->getBasic();
		if ($fieldPath === 'galleryImageIds') {
			return $this->resolveGalleryField($product);
		} try {
			$fieldKey = BasicFieldKeys::from($fieldPath);
		} catch (\ValueError $e) {
			return '';
		}

return (string) match ($fieldKey) {
			BasicFieldKeys::DESCRIPTION_LONG => $basic->getDescriptionLong(), BasicFieldKeys::DESCRIPTION_SHORT => $basic->getDescriptionShort(), BasicFieldKeys::GALLERY_IMAGE_IDS => implode(', ', $basic->getGalleryImageIds()), BasicFieldKeys::ID => $basic->getId(), BasicFieldKeys::IMAGE_ID => $basic->getImageId() ?? '', BasicFieldKeys::NAME => $basic->getName(), BasicFieldKeys::PARENT_ID => $basic->getParentId(), BasicFieldKeys::POST_STATUS => $basic->getPostStatus()->value, BasicFieldKeys::REGULAR_PRICE => $basic->getRegularPrice() ?? '', BasicFieldKeys::SALE_PRICE => $basic->getSalePrice() ?? '', BasicFieldKeys::SKU => $basic->getSku(), BasicFieldKeys::STOCK_COUNT => $basic->getStock() ?? '', BasicFieldKeys::STOCK_STATUS => $basic->getStockStatus() ? $basic->getStockStatus()->value : '', BasicFieldKeys::TAX_CLASS => $basic->getTaxClass(), BasicFieldKeys::TAX_STATUS => $basic->getTaxStatus() ? $basic->getTaxStatus()->value : '', BasicFieldKeys::TOTAL_SALES => $basic->getTotalSales(),
		};
	}

	private function resolveGalleryField(Product $product) {
		return implode(', ', $product->getBasic()->getGalleryImageIds());
	}

	private function resolveAcfField(Product $product, string $fieldId) {
		if (str_starts_with($fieldId, 'field_')) {
			$fieldId = substr($fieldId, 6);
		} $acfFields = $product->getAcf();
		if (!isset($acfFields[$fieldId])) {
			return '';
		} $values = $acfFields[$fieldId];
		foreach ($this->acfFields->acfFieldGroups as $group) {
			if (!isset($group->fields[$fieldId])) {
				continue;
			} $field = $group->fields[$fieldId];
			if (!empty($field->choices)) {
				if (is_array($values)) {
					$labeledValues = [];
					foreach ($values as $value) {
						$labeledValues[] = $field->choices[$value] ?? $value;
					}

return implode(', ', $labeledValues);
				} else {
					return $field->choices[$values] ?? (string) $values;
				}
			}

return is_array($values) ? implode(', ', $values) : (string) $values;
		}

return is_array($values) ? implode(', ', $values) : (string) $values;
	}

	private function resolveCustomMeta(Product $product, string $fieldName) {
		$customMeta = $product->getCustomMeta();
		if (!isset($customMeta[$fieldName])) {
			return '';
		}

return (string) $customMeta[$fieldName];
	}

	private function resolveGermanMarket(Product $product, string $fieldName) {
		return '';
	}

	private function resolveTaxonomy(array $taxonomies, string $fieldName) {
		$termIds = $taxonomies[$fieldName] ?? [];
		$termNames = [];
		foreach ($termIds as $termId) {
			if (!isset($this->taxonomies->termsByTermId[$termId])) {
				continue;
			} $termNames[] = $this->taxonomies->termsByTermId[$termId]->name;
		} natcasesort($termNames);

		return implode(', ', $termNames);
	}

	private function getOperatorsForType(ProductFieldType $fieldType) {
		switch ($fieldType) {
			case ProductFieldType::INTEGER: case ProductFieldType::POSITIVE_INTEGER: case ProductFieldType::CURRENCY: return [FieldOperator::EQUALS, FieldOperator::GREATER_THAN, FieldOperator::LESS_THAN, FieldOperator::GREATER_OR_EQUAL, FieldOperator::LESS_OR_EQUAL, FieldOperator::IS_EMPTY];
			case ProductFieldType::TEXT: return [FieldOperator::EQUALS, FieldOperator::CONTAINS, FieldOperator::STARTS_WITH, FieldOperator::ENDS_WITH, FieldOperator::IS_EMPTY];
			case ProductFieldType::BOOLEAN: return [FieldOperator::EQUALS];
			case ProductFieldType::SELECT: case ProductFieldType::MULTISELECT: return [FieldOperator::EQUALS, FieldOperator::IN, FieldOperator::IS_EMPTY];
			case ProductFieldType::DATETIME: return [FieldOperator::EQUALS, FieldOperator::GREATER_THAN, FieldOperator::LESS_THAN, FieldOperator::GREATER_OR_EQUAL, FieldOperator::LESS_OR_EQUAL];
			default: return [FieldOperator::EQUALS];
		}
	}
}
