<?php

use External\ZNZBundle\Util\ZNZUtil;
use KupShop\CatalogBundle\ProductList\ProductCollection;
use KupShop\CatalogBundle\ProductList\ProductCollectionWrapper;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Functional\Mapping;

function smarty_function_get_znz_product_collection_variations($params, &$smarty)
{
    if (empty($params['products'])) {
        throw new InvalidArgumentException('Parameter \`products\` is missing!');
    }

    /** @var ProductCollection $products */
    $products = $params['products'];
    if ($products instanceof ProductCollectionWrapper) {
        $products = $products->getObject();
    }

    if (!($data = getCache('znzCollectionVariationsData'))) {
        $znzUtil = ServiceContainer::getService(ZNZUtil::class);

        $data = [
            'primaryParameterId' => $znzUtil->getParameterByKey('objemsJednotkou'),
            'secondaryParameterId' => $znzUtil->getParameterByKey('SpecifikaBaleni'),
        ];

        setCache('znzCollectionVariationsData', $data);
    }

    $primaryParameterId = $data['primaryParameterId'];
    $secondaryParameterId = $data['secondaryParameterId'];

    $products->fetchParameters([$primaryParameterId, $secondaryParameterId]);

    $listValueIds = [];
    // nactu si ID vsech listovych hodnot, abych si k nim mohl donacist pozice
    foreach ($products as $product) {
        $listValueIds[] = $product->param[$primaryParameterId]['value_id'] ?? null;
        $listValueIds[] = $product->param[$secondaryParameterId]['value_id'] ?? null;
    }

    $listValueIds = array_unique(array_filter($listValueIds));

    // nactu si pozice listovych hodnot
    $positions = Mapping::mapKeys(sqlQueryBuilder()
        ->select('id, position')
        ->from('parameters_list')
        ->where(\Query\Operator::inIntArray($listValueIds, 'id'))
        ->execute()->fetchAllAssociative(), fn ($k, $v) => [$v['id'], $v['position']]);

    // priradim pozice k produktum
    foreach ($products as $product) {
        $product->collectionPrimaryPosition = $positions[$product->param[$primaryParameterId]['value_id'] ?? null] ?? PHP_INT_MAX;
        $product->collectionSecondaryPosition = $positions[$product->param[$secondaryParameterId]['value_id'] ?? null] ?? PHP_INT_MAX;
    }

    $sortedProducts = $products->toArray();

    // seradim produkty podle pozic
    uasort($sortedProducts, function ($a, $b) {
        if ($rdiff = $b->collectionPrimaryPosition <=> $a->collectionPrimaryPosition) {
            return $rdiff;
        }

        return $b->collectionSecondaryPosition <=> $a->collectionSecondaryPosition;
    });

    // vratim novou, upravenou kolekci produktu
    $result = ProductCollectionWrapper::wrap(
        new ProductCollection($sortedProducts)
    );

    if (!empty($params['assign'])) {
        $smarty->assign($params['assign'], $result);
    } else {
        return $result;
    }
}
