<?php

declare(strict_types=1);

namespace External\ZNZBundle\Synchronizers;

use KupShop\CatalogBundle\Parameters\ParameterFinder;
use KupShop\I18nBundle\Translations\ParametersListTranslation;
use Query\Operator;

class ParameterSynchronizer extends BaseSynchronizer
{
    protected static string $type = 'parameter';
    public static string $typeValues = 'parameters_value';

    /** @required */
    public ParameterFinder $parameterFinder;

    /** @required */
    public ParametersListTranslation $parametersListTranslation;

    public static function getHandledTables(): array
    {
        return [
            'ProduktAtributOptions1' => 'processParameterValues',
            'ProduktAtributOptions2' => 'processParameterValues',
        ];
    }

    /** Synchronizuje hodnoty parametru. Pripadne zaklada parametr, pokud jeste neexistuje. */
    public function processParameterValues(array $item): void
    {
        if ($isDeleteMessage = $this->isDeleteMessage($item)) {
            $item = $this->getParameterValueDeleteItem($item);
        }

        if (!$isDeleteMessage && (empty($item['Nazev']) || empty($item['atribut']))) {
            return;
        }

        $parameterId = $this->znzUtil->getParameterByKey($item['atribut']);

        // kouknu jestli uz dana hodnota existuje
        $valueId = $this->znzUtil->getParameterValueMapping($parameterId, $item['IDoption']);

        $labelValueId = null;
        if ($valueId) {
            $tmpLabelValueId = sqlQueryBuilder()
                ->select('id_label_value')
                ->from('znz_label_values')
                ->where(Operator::equals(['id_znz' => $item['IDoption']]))
                ->execute()->fetchOne();

            if ($tmpLabelValueId) {
                $labelValueId = (int) $tmpLabelValueId;
            }
        }

        // pokud mam hodnotu a jedna se o preklad, tak ho aktualizuju
        if ($item['meta']['translation'] ?? false) {
            if ($valueId) {
                $this->parametersListTranslation->saveSingleObject($item['meta']['language'], $valueId, ['value' => $item['Nazev']]);

                if ($labelValueId) {
                    $this->znzUtil->updateLabelValueByParameterValue($labelValueId, $valueId, $item['meta']['language']);
                }
            }

            // vyskocim pryc, protoze to je preklad a nechci prekladem prerazit hodnotu v defaultnim jazyku
            return;
        }

        if ($isDeleteMessage) {
            if ($valueId) {
                sqlQueryBuilder()
                    ->delete('parameters_list')
                    ->where(Operator::equals(['id' => $valueId]))
                    ->execute();
            }

            if ($labelValueId) {
                sqlQueryBuilder()
                    ->delete('products_variations_choices_values')
                    ->where(Operator::equals(['id' => $labelValueId]))
                    ->execute();
            }

            return;
        }

        // pokud hodnota neexistuje, tak ji vytvorim
        if (!$valueId) {
            $valueId = sqlGetConnection()->transactional(function () use ($item, $parameterId) {
                sqlQueryBuilder()
                    ->insert('parameters_list')
                    ->directValues(
                        [
                            'id_parameter' => $parameterId,
                            'value' => $item['Nazev'],
                            'description' => $item['IDoption'],
                        ]
                    )->execute();

                $valueId = (int) sqlInsertId();

                $this->znzUtil->createParameterValueMapping($parameterId, $valueId, $item['IDoption']);

                return $valueId;
            });
        }

        // aktualizace hodnoty
        sqlQueryBuilder()
            ->update('parameters_list')
            ->directValues(['value' => $item['Nazev']])
            ->where(Operator::equals(['id' => $valueId]))
            ->execute();

        if ($labelValueId) {
            $this->znzUtil->updateLabelValueByParameterValue($labelValueId, $valueId, $item['meta']['language']);
        }
    }

    private function getParameterValueDeleteItem(array $item): array
    {
        $parts = explode('-', $item['meta']['unique_id']);

        $item['atribut'] = $parts[1];
        $item['IDoption'] = $parts[0];
        $item['Nazev'] = '';

        return $item;
    }
}
