<?php

namespace KupShop\FeedsBundle\Wrapper;

use KupShop\CatalogBundle\Entity\Section;
use KupShop\FeedGeneratorBundle\Utils\Map;
use KupShop\FeedsBundle\Utils\FeedUtils;

class SectionWrapper extends BaseWrapper
{
    protected static $objectType = Section::class;

    /** @var Section */
    protected $object;

    /** @var \Product */
    protected $product;

    protected static $heurekaSkSections;

    protected static $searchEngineSections = [];

    /** @var Map */
    protected $map;

    /** @var SectionWrapperFactory */
    protected $sectionWrapperFactory;

    /** @var FeedUtils */
    protected $feedUtils;

    /** @var array */
    private $feedRow;

    /** @var bool */
    private $isAncestor = false;

    public function __construct(?Map $map, SectionWrapperFactory $sectionWrapperFactory, FeedUtils $feedUtils, bool $isAncestor = false)
    {
        $this->map = $map;
        $this->sectionWrapperFactory = $sectionWrapperFactory;
        $this->feedUtils = $feedUtils;
        $this->isAncestor = $isAncestor;
    }

    /**
     * @private
     */
    public function setProduct(\Product $product)
    {
        $this->product = $product;
    }

    /**
     * @private
     */
    public function setFeedRow($feedRow)
    {
        $this->feedRow = $feedRow;
    }

    protected function getSearchEngineSections(string $type)
    {
        if (!isset(static::$searchEngineSections[$type])) {
            $sections = [];
            $result = sqlQueryBuilder()->select('id, category_text')
                ->from('kupshop_shared.feed_'.$type)
                ->execute();
            foreach ($result as $row) {
                $sections[(int) $row['id']] = $row['category_text'];
            }
            static::$searchEngineSections[$type] = $sections;
        }

        return static::$searchEngineSections[$type];
    }

    protected function getHeurekaSkSections()
    {
        if (!isset(static::$heurekaSkSections)) {
            $result = sqlQueryBuilder()->select('id, name, category_text')
                ->from('kupshop_shared.feed_heureka_sk')
                ->execute();
            foreach ($result as $row) {
                static::$heurekaSkSections[(int) $row['id']] = $row['category_text'];
            }
        }

        return static::$heurekaSkSections;
    }

    /** Celý název */
    public function field_title()
    {
        return $this->object->getName();
    }

    /** URL adresa sekce */
    public function field_url()
    {
        return $this->object->getFullUrl();
    }

    /** Seznam názvů sekcí: [Úroveň => Název sekce] */
    public function field_path_array()
    {
        if ($this->isAncestor) {
            return null;
        }
        $parents = $this->object->getParents();

        $sections = [];
        $level = 1;
        foreach ($parents as $parent) {
            $sections[$level++] = $parent->getName();
        }

        return $sections;
    }

    /** Seznam sekcí: [Úroveň => Sekce] */
    public function field_path_sections()
    {
        if ($this->isAncestor) {
            return null;
        }
        $parents = $this->object->getParents();

        $sections = [];
        $level = 1;
        foreach ($parents as $parent) {
            $section = $this->sectionWrapperFactory->create(true);
            $section->setObject($parent);
            $sections[$level++] = $section;
        }

        return $sections;
    }

    /** Kompletni cesta ke kategorii se separatorem */
    public function path($separator = ' > ')
    {
        $parents = $this->object->getParents();
        $names = array_map(function ($p) { return $p->getName(); }, $parents);

        return implode($separator, $names);
    }

    /** Mapování kategorie podle parametrem vybrané mapy.
     *
     * @return string
     */
    public function map(string $mapName)
    {
        return $this->map->map($mapName, $this->object->getId(), $this->path());
    }

    /** Interní ID kategorie */
    public function field_id()
    {
        return $this->object->getId();
    }

    /** Anotace */
    public function field_annotation(): string
    {
        return $this->object->getAnnotation() ?? '';
    }

    /**
     * ID přiřazené sekce srovnávače.
     *
     * Typ srovnávače lze vybrat v nastavení feedu "Sekce srovnávače".
     */
    public function field_search_engine_id(): string
    {
        $type = $this->feedRow['section_mapping'] ?? false;
        if ($this->feedUtils->filterThirdPartySectionType($type)) {
            $sectionGetterName = $type === 'heureka_sk' ? 'getFeedHeurekaSk' : ('getFeed'.ucfirst($type));
            $mappedSectionID = isset($this->object) ? $this->object->$sectionGetterName() : null;

            $ID = $this->product['fp_id_section'] ?? $mappedSectionID;

            return $ID ?? '';
        } else {
            return '';
        }
    }

    /**
     * Název přiřazené sekce srovnávače.
     *
     * Typ srovnávače lze vybrat v nastavení feedu "Sekce srovnávače".
     */
    public function field_search_engine_name(): string
    {
        $type = $this->feedRow['section_mapping'] ?? false;
        $ID = $this->field_search_engine_id();
        if ($ID) {
            $searchEngineSections = $this->getSearchEngineSections($type);

            return $searchEngineSections[(int) $ID] ?? '';
        } else {
            return '';
        }
    }

    /**
     * Viditelná
     */
    public function field_visible(): int
    {
        return (int) $this->object->isVisible();
    }

    /**
     * Zobravovat ve vyhledávání.
     */
    public function field_show_in_search(): int
    {
        return $this->object->getShowInSearch() == 'Y' ? 1 : 0;
    }

    private function removePathFields(array $array)
    {
        if ($this->isAncestor) {
            foreach ($array as $index => $field) {
                if ($field['name'] === 'path_sections' || $field['name'] === 'path_array') {
                    unset($array[$index]);
                }
            }
        }

        return $array;
    }

    /**
     * @private
     */
    public function getRawFieldsAndMethods(): array
    {
        $arr = parent::getRawFieldsAndMethods();

        return $this->removePathFields($arr);
    }

    /**
     * @private
     */
    public function getFieldsAndMethods(): array
    {
        $arr = parent::getFieldsAndMethods();

        return $this->removePathFields($arr);
    }
}
