<?php

declare(strict_types=1);

namespace External\PompoBundle\Admin\Actions;

use External\PompoBundle\Util\Configuration;
use External\PompoBundle\Util\PompoGraphQLUpdater;
use GraphQL\Exception\QueryError;
use KupShop\AdminBundle\Admin\Actions\AbstractAction;
use KupShop\AdminBundle\Admin\Actions\ActionResult;
use KupShop\AdminBundle\Admin\Actions\IAction;
use KupShop\ContentBundle\Util\Block;
use KupShop\KupShopBundle\Util\Functional\Mapping;

/**
 * Aktualizuje data produktu na `prod/nejhracka`. Tahle akce se zobrazuje pouze na `prod/pompo`.
 */
class UpdateNejhrackaProductAction extends AbstractAction implements IAction
{
    private Configuration $configuration;
    private Block $block;
    private PompoGraphQLUpdater $updater;

    public function __construct(Configuration $configuration, Block $block, PompoGraphQLUpdater $updater)
    {
        $this->configuration = $configuration;
        $this->block = $block;
        $this->updater = $updater;
    }

    public function getTypes(): array
    {
        return ['products'];
    }

    public function isEnabled()
    {
        return $this->configuration->isPompo();
    }

    public function getName(): string
    {
        return '[Pompo] Aktualizovat na nejhračce';
    }

    public function showInMassEdit()
    {
        return true;
    }

    public function execute(&$data, array $config, string $type): ActionResult
    {
        $product = $this->updater->getProduct((int) $this->getId());

        try {
            if (empty($product->code)) {
                return new ActionResult(false, 'Produkt nemá nastavený kód. Aktualizace produktu není možná.');
            }

            // Podle kodu najdu ID produktu
            if (!($externalProductId = $this->updater->getProductIdByCode($product->code))) {
                return new ActionResult(false, sprintf('Produkt s kódem "%s" nebyl nalezen!', $product->code));
            }

            // pripravim si data, ktere chci aktualizovat
            $productData = [
                'title' => $product->title,

                'visibility' => $this->updater->getProductVisibility($product->visible),

                'description' => $product->descr,
                'longDescription' => $product->longDescr,

                'weight' => (float) $product->weight,
                'width' => (float) $product->width,
                'height' => (float) $product->height,
                'depth' => (float) $product->depth,

                'seo' => [
                    'title' => $product->meta_title,
                    'description' => $product->meta_description,
                    'keywords' => $product->meta_keywords,
                ],
            ];

            if (!empty($product->producer['name'])) {
                $productData['producerId'] = $this->updater->getProducerIdByName($product->producer['name']);
            }

            // Pridam sekce do dat produktu
            foreach ($product->sections as $section) {
                $remoteSectionId = $this->updater->getSectionIdByPath(
                    Mapping::mapKeys($section->getParents(), fn ($k, $v) => [$k, $v->getName()])
                );

                if ($remoteSectionId) {
                    $productData['sections'][] = $remoteSectionId;
                }
            }

            $response = $this->updater->updateProduct($externalProductId, $productData);

            if (!($response['result'] ?? false)) {
                return new ActionResult(false, 'Produkt se nepodařilo aktualizovat!');
            }

            $externalEditableContentId = $response['product']['descriptionPlus']['id'];

            if ($product->id_block) {
                // aktualizace popisu+
                $this->updater->updateEditableContent(
                    $externalEditableContentId,
                    $this->updater->createEditableContentFromBlocks(
                        $this->block->getBlocks((int) $product->id_block)
                    )
                );
            }

            // Aktualizace parametru
            $this->updater->updateProductParameters($externalProductId, $product);
            // Aktualizace odkazu
            $this->updater->updateProductLinks($externalProductId, $product);
            // Aktualizace kolekci produktu
            $this->updater->updateProductCollection($externalProductId, $product);
            // Aktualizace souvisejiciho zbozi
            $this->updater->updateProductRelated($externalProductId, $product);
            // aktualizovat SK preklady produktu
            $this->updater->updateProductTranslations(
                $externalProductId,
                $externalEditableContentId,
                'sk',
                $this->updater->getProduct((int) $this->getId(), 'sk')
            );
        } catch (QueryError $e) {
            return new ActionResult(
                false,
                sprintf('Komunikace selhala! Chyba: %s', $e->getMessage())
            );
        }

        return new ActionResult(true);
    }
}
