<?php
declare(strict_types=1);

namespace WriteTextAI\WriteTextAI\Model;

use WriteTextAI\WriteTextAI\Api\RecordDetailsApiInterface;
use Magento\Framework\Webapi\Rest\Response as RestResponse;
use WriteTextAI\WriteTextAI\Model\Config\Source\ProductAttributes;
use WriteTextAI\WriteTextAI\Model\Config\Source\ProductAttributes\Excluded;
use Magento\Customer\Api\GroupRepositoryInterface;
use Magento\Customer\Api\Data\GroupInterface;
use Magento\Catalog\Helper\Image as ImageHelper;
use WriteTextAI\WriteTextAI\Helper\Image as WTAImageHelper;
use Magento\Catalog\Helper\Output as OutputHelper;
use Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory as AttributeCollectionFactory;
use Magento\Framework\Exception\FileSystemException;
use Magento\Framework\Filter\FilterManager;
use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus;
use WriteTextAI\WriteTextAI\Helper\Product as ProductHelper;
use WriteTextAI\WriteTextAI\Helper\Fields as FieldHelper;
use WriteTextAI\WriteTextAI\ViewModel\Settings;
use WriteTextAI\WriteTextAI\Model\Magento\Category as MagentoCategory;
use WriteTextAI\WriteTextAI\Helper\Categories\RepresentativeProducts as RepresentativeProductsHelper;
use WriteTextAI\WriteTextAI\Model\AiCategoryManager;
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory as CategoryCollectionFactory;
use Magento\Store\Model\StoreManagerInterface;

/**
 * Implementation for record details API endpoint
 */
class RecordDetailsApi implements RecordDetailsApiInterface
{
    private const CUSTOMIZABLE_OPTIONS_ATTRIBUTE_CODE = 'wtai_customizable_options';

    private const CUSTOMIZABLE_OPTIONS_WITH_VALUES_ATTRIBUTE_CODE = 'wtai_customizable_options_with_values';

    private const CUSTOM_OPTION_ATTRIBUTE_PREFIX = 'wtai_custom_option_';

    /**
     * @var RestResponse
     */
    private $response;

    /**
     * @var WTAImageHelper
     */
    private $wtaImageHelper;

    /**
     * @var ProductHelper
     */
    private $productHelper;

    /**
     * @var FilterManager
     */
    private $filterManager;

    /**
     * @var ImageHelper
     */
    private $imageHelper;

    /**
     * @var OutputHelper
     */
    private $outputHelper;

    /**
     * @var AttributeCollectionFactory
     */
    private $attributeCollectionFactory;

    /**
     * @var GroupRepositoryInterface
     */
    private $groupRepository;

    /**
     * @var ProductAttributes
     */
    private $productAttributes;

    /**
     * @var FieldHelper
     */
    private $fieldHelper;

    /**
     * @var Settings
     */
    private $settings;

    /**
     * @var CategoryCollectionFactory
     */
    private $categoryCollectionFactory;

    /**
     * @var StoreManagerInterface
     */
    private $storeManager;

    /**
     * @var MagentoCategory
     */
    private $magentoCategory;

    /**
     * @var RepresentativeProductsHelper
     */
    private $representativeProductsHelper;

    /**
     * @var AiCategoryManager
     */
    private $aiCategoryManager;

    /**
     * @param RestResponse $response
     * @param WTAImageHelper $wtaImageHelper
     * @param ProductHelper $productHelper
     * @param FilterManager $filterManager
     * @param ImageHelper $imageHelper
     * @param OutputHelper $outputHelper
     * @param AttributeCollectionFactory $attributeCollectionFactory
     * @param GroupRepositoryInterface $groupRepository
     * @param ProductAttributes $productAttributes
     * @param FieldHelper $fieldHelper
     * @param Settings $settings
     * @param CategoryCollectionFactory $categoryCollectionFactory
     * @param StoreManagerInterface $storeManager
     * @param MagentoCategory $magentoCategory
     * @param RepresentativeProductsHelper $representativeProductsHelper
     * @param AiCategoryManager $aiCategoryManager
     */
    public function __construct(
        RestResponse $response,
        WTAImageHelper $wtaImageHelper,
        ProductHelper $productHelper,
        FilterManager $filterManager,
        ImageHelper $imageHelper,
        OutputHelper $outputHelper,
        AttributeCollectionFactory $attributeCollectionFactory,
        GroupRepositoryInterface $groupRepository,
        ProductAttributes $productAttributes,
        FieldHelper $fieldHelper,
        Settings $settings,
        CategoryCollectionFactory $categoryCollectionFactory,
        StoreManagerInterface $storeManager,
        MagentoCategory $magentoCategory,
        RepresentativeProductsHelper $representativeProductsHelper,
        AiCategoryManager $aiCategoryManager
    ) {
        $this->response = $response;
        $this->wtaImageHelper = $wtaImageHelper;
        $this->productHelper = $productHelper;
        $this->filterManager = $filterManager;
        $this->imageHelper = $imageHelper;
        $this->outputHelper = $outputHelper;
        $this->attributeCollectionFactory = $attributeCollectionFactory;
        $this->groupRepository = $groupRepository;
        $this->productAttributes = $productAttributes;
        $this->fieldHelper = $fieldHelper;
        $this->settings = $settings;
        $this->categoryCollectionFactory = $categoryCollectionFactory;
        $this->storeManager = $storeManager;
        $this->magentoCategory = $magentoCategory;
        $this->representativeProductsHelper = $representativeProductsHelper;
        $this->aiCategoryManager = $aiCategoryManager;
    }

    /**
     * Extract custom option IDs from attribute codes like wtai_custom_option_123
     *
     * @param array $selectedAttributes
     * @return int[]
     */
    private function extractSelectedCustomOptionIds(array $selectedAttributes): array
    {
        $ids = [];
        foreach ($selectedAttributes as $code) {
            $code = (string) $code;
            if (strpos($code, self::CUSTOM_OPTION_ATTRIBUTE_PREFIX) !== 0) {
                continue;
            }
            $idStr = substr($code, strlen(self::CUSTOM_OPTION_ATTRIBUTE_PREFIX));
            if ($idStr === '' || !ctype_digit($idStr)) {
                continue;
            }
            $id = (int) $idStr;
            if ($id > 0) {
                $ids[] = $id;
            }
        }

        $ids = array_values(array_unique($ids));
        sort($ids);
        return $ids;
    }

    /**
     * Build attributes payload for specifically selected custom option IDs.
     *
     * @param \Magento\Catalog\Model\Product $product
     * @param int[] $selectedOptionIds
     * @return array
     */
    private function getCustomOptionsByIdAttributesData($product, array $selectedOptionIds): array
    {
        try {
            if (empty($selectedOptionIds)) {
                return [];
            }
            if (!$product || !method_exists($product, 'getOptions')) {
                return [];
            }

            $options = $product->getOptions();
            if (!is_array($options) || empty($options)) {
                return [];
            }

            $selectedOptionIds = array_values(array_unique(array_filter(array_map('intval', $selectedOptionIds))));
            $selectedOptionIds = array_filter($selectedOptionIds, static fn($id) => $id > 0);
            if (empty($selectedOptionIds)) {
                return [];
            }

            $selectedLookup = array_fill_keys($selectedOptionIds, true);

            $attributesData = [];
            foreach ($options as $option) {
                if (!$option || !method_exists($option, 'getOptionId')) {
                    continue;
                }

                $optionId = $option->getOptionId();
                $optionId = is_numeric($optionId) ? (int) $optionId : 0;
                if ($optionId <= 0 || !isset($selectedLookup[$optionId])) {
                    continue;
                }

                $values = [];
                if (method_exists($option, 'getValues')) {
                    $values = $option->getValues();
                }

                if (!is_array($values) || empty($values)) {
                    continue;
                }

                $optTitle = '';
                if (method_exists($option, 'getTitle')) {
                    $optTitle = trim((string) $option->getTitle());
                }
                if ($optTitle === '') {
                    $optTitle = 'Option #' . $optionId;
                }

                $valueTitles = [];
                foreach ($values as $value) {
                    if (!$value || !method_exists($value, 'getTitle')) {
                        continue;
                    }
                    $valTitle = trim((string) $value->getTitle());
                    if ($valTitle !== '') {
                        $valueTitles[] = $valTitle;
                    }
                }

                $valueTitles = array_values(array_unique(array_filter($valueTitles)));
                if (empty($valueTitles)) {
                    continue;
                }

                $valueStr = implode(', ', $valueTitles);
                $valueStr = $this->filterManager->stripTags($valueStr);
                // phpcs:ignore Magento2.Functions.DiscouragedFunction.DiscouragedWithAlternative
                $valueStr = htmlspecialchars(
                    $valueStr,
                    ENT_QUOTES | ENT_SUBSTITUTE,
                    'UTF-8'
                );

                $attributesData[] = [
                    'name' => $optTitle ,
                    'value' => $valueStr,
                    'isCustom' => 'true'
                ];
            }

            return $attributesData;
        } catch (\Exception $e) {
            return [];
        }
    }

    /**
     * Get record details
     *
     * @param string $storeId
     * @param string $type
     * @param string $recordId
     * @param mixed $parameters
     * @return void
     */
    public function getRecordDetails($storeId, $type, $recordId, $parameters)
    {
        $attributesData = [];
        $responseData = [];
        $rules = $this->settings->getSettings('rules');

        // try {
        if ($type === 'Product') {
            $responseData['attributes'] = [];
            $product = $this->productHelper->getProduct($recordId, $storeId);
            $productType = $this->getProductTypeMapping((string) $product->getTypeId());
            $flags = $this->getVirtualDownloadableFlags($product->getTypeId());
            $isVirtual = (bool) ($flags['isVirtual'] ?? false);
            $isDownloadable = (bool) ($flags['isDownloadable'] ?? false);
            $childProducts = $this->getChildProducts($product);
            $attributesData = $this->getProductDetails($storeId, $type, $recordId, $parameters, $rules);
            $categories = $this->getProductCategoryPaths($product, (int) $storeId);

            $responseData['attributes'] = $attributesData;
            $responseData['productType'] = $productType;
            $responseData['isVirtual'] = $isVirtual;
            $responseData['isDownloadable'] = $isDownloadable;
            $responseData['childProducts'] = $childProducts;
            $responseData['categories'] = $categories;
        } elseif ($type === 'Category') {
            // TODO: Add category details
            $aiCategory = $this->aiCategoryManager->getCategory($recordId, $storeId);

            if (!$aiCategory->getId()) {
                $aiCategory->setCategoryId($recordId);
                $aiCategory->setStoreId($storeId);
            }
            $responseData['products'] =
                $this->representativeProductsHelper->getRepresentativeProductsSelectedRecord($aiCategory);
            if ($parameters['hasProductNames']) {
                $responseData['productNames'] = $this->getProductsNames($recordId, $storeId);
            }
        }

        $this->response->setBody(json_encode($responseData))->sendResponse();
    }

    /**
     * Product get child producs
     *
     * @param \Magento\Catalog\Model\Product $product
     * @return array
     */
    private function getChildProducts($product): array
    {
        $typeId = (string) $product->getTypeId();
        $childProducts = [];

        try {
            if ($typeId === 'configurable') {
                $children = $product->getTypeInstance()->getUsedProducts($product);
            } elseif ($typeId === 'grouped') {
                $children = $product->getTypeInstance()->getAssociatedProducts($product);
            } elseif ($typeId === 'bundle') {
                $typeInstance = $product->getTypeInstance();
                $optionIds = $typeInstance->getOptionsIds($product);
                $children = $typeInstance->getSelectionsCollection($optionIds, $product);
            } else {
                return [];
            }

            foreach ($children as $child) {
                if ((int)$child->getStatus() === ProductStatus::STATUS_DISABLED) {
                    continue;
                }

                $childProducts[] = [
                    'ID' => (string) $child->getId(),
                    'Name' => (string) $child->getName()
                ];
            }
        } catch (\Exception $e) {
            return [];
        }

        return $childProducts;
    }
    
    /**
     * Is virtual and/or downloadable
     *
     * @param string $typeId
     * @return array{isVirtual: bool, isDownloadable: bool}
     */
    private function getVirtualDownloadableFlags($typeId)
    {
        $typeId = (string)$typeId;
        $isVirtual = ($typeId === 'virtual');
        $isDownloadable = ($typeId === 'downloadable');

        if ($isDownloadable) {
            return ['isVirtual' =>true, 'isDownloadable' => $isDownloadable];
        }

        return ['isVirtual' => $isVirtual, 'isDownloadable' => $isDownloadable];
    }

    /**
     * Product get details
     *
     * @param string $storeId
     * @param string $type
     * @param string $recordId
     * @param mixed $parameters
     * @param array $rules
     * @return array
     */
    public function getProductDetails($storeId, $type, $recordId, $parameters, $rules)
    {
        $maxAttributes = $rules['maxAttributes'] ?? '';
        $maxAttributeValueLength = $rules['maxAttributeValueLength'] ?? '';
        $product = $this->productHelper->getProduct($recordId, $storeId);
        if (empty($parameters['attributes'])) {
            return [];
        }
        
        $selectedAttributes = (array) ($parameters['attributes'] ?? []);

        $selectedCustomOptionIds = $this->extractSelectedCustomOptionIds($selectedAttributes);

        $includeCustomOptionsNoValues = in_array(self::CUSTOMIZABLE_OPTIONS_ATTRIBUTE_CODE, $selectedAttributes, true);
        $includeCustomOptionsWithValues = in_array(
            self::CUSTOMIZABLE_OPTIONS_WITH_VALUES_ATTRIBUTE_CODE,
            $selectedAttributes,
            true
        );

        $customizableOptionsAttributesData = [];
        if ($includeCustomOptionsNoValues || $includeCustomOptionsWithValues) {
            $customizableOptionsAttributesData = $this->getCustomizableOptionsAttributesData(
                $product,
                $includeCustomOptionsNoValues,
                $includeCustomOptionsWithValues
            );
            $selectedAttributes = array_values(array_filter(
                $selectedAttributes,
                static fn($code) => !in_array(
                    $code,
                    [
                        self::CUSTOMIZABLE_OPTIONS_ATTRIBUTE_CODE,
                        self::CUSTOMIZABLE_OPTIONS_WITH_VALUES_ATTRIBUTE_CODE
                    ],
                    true
                )
            ));
        }

        $customOptionsByIdAttributesData = [];
        if (!empty($selectedCustomOptionIds)) {
            $customOptionsByIdAttributesData = $this->getCustomOptionsByIdAttributesData(
                $product,
                $selectedCustomOptionIds
            );
            $selectedAttributes = array_values(array_filter(
                $selectedAttributes,
                static fn($code) => strpos((string) $code, self::CUSTOM_OPTION_ATTRIBUTE_PREFIX) !== 0
            ));
        }

        $productAttributes = $this->getProductAttributes($product, $selectedAttributes);
        $attributesData = [];
        foreach ($productAttributes as $attribute) {
            try {
                if (strtolower($attribute['attribute'])
                    === ProductAttributes::PRODUCT_RESEARCH_DATA_ATTRIBUTE_CODE
                ) {
                    continue;
                }
                
                if (strtolower($attribute['attribute']) !== 'thumbnail') {
                    $stringAttribute = (string)$attribute['details'];
                    if (!empty(trim($stringAttribute))) {
                        $attributeValue = str_replace("<br />", "\n", $stringAttribute);
                        $attributeValue = $this->filterManager->stripTags($attributeValue);
                        //@codingStandardsIgnoreStart
                        $attributeValue = htmlspecialchars(
                            $attributeValue,
                            ENT_QUOTES | ENT_SUBSTITUTE,
                            'UTF-8'
                        );
                        //@codingStandardsIgnoreEnd
                        $attributesData[] = [
                            "name" => $attribute['attribute'],
                            "value" => $attributeValue,
                            "isCustom" => "false"
                        ];
                    }
                }
            } catch (\Exception $e) {
                continue;
            }
        }

        if (!empty($customizableOptionsAttributesData)) {
            $attributesData = array_merge($attributesData, $customizableOptionsAttributesData);
        }

        if (!empty($customOptionsByIdAttributesData)) {
            $attributesData = array_merge($attributesData, $customOptionsByIdAttributesData);
        }

        return $attributesData;
    }

    /**
     * Build attributes payload from product customizable options.
     *
     * @param \Magento\Catalog\Model\Product $product
     * @param bool $includeNoValues
     * @param bool $includeWithValues
     * @return array
     */
    private function getCustomizableOptionsAttributesData(
        $product,
        bool $includeNoValues,
        bool $includeWithValues
    ): array {
        try {
            if (!$product || !method_exists($product, 'getOptions')) {
                return [];
            }

            $options = $product->getOptions();
            if (!is_array($options) || empty($options)) {
                return [];
            }

            $attributesData = [];
            $noValueTitles = [];

            foreach ($options as $option) {
                if (!$option || !method_exists($option, 'getTitle')) {
                    continue;
                }

                $optTitle = trim((string) $option->getTitle());
                if ($optTitle === '') {
                    continue;
                }

                $optionId = null;
                if (method_exists($option, 'getOptionId')) {
                    $optionId = $option->getOptionId();
                }
                $optionId = is_numeric($optionId) ? (int) $optionId : null;

                $values = [];
                if (method_exists($option, 'getValues')) {
                    $values = $option->getValues();
                }

                $valueTitles = [];
                if (is_array($values) && !empty($values)) {
                    foreach ($values as $value) {
                        if (!$value || !method_exists($value, 'getTitle')) {
                            continue;
                        }
                        $valTitle = trim((string) $value->getTitle());
                        if ($valTitle !== '') {
                            $valueTitles[] = $valTitle;
                        }
                    }
                }

                $valueTitles = array_values(array_unique(array_filter($valueTitles)));

                if (!empty($valueTitles)) {
                    if (!$includeWithValues) {
                        continue;
                    }

                    $valueStr = implode(', ', $valueTitles);
                    $valueStr = $this->filterManager->stripTags($valueStr);
                    // phpcs:ignore Magento2.Functions.DiscouragedFunction.DiscouragedWithAlternative
                    $valueStr = htmlspecialchars(
                        $valueStr,
                        ENT_QUOTES | ENT_SUBSTITUTE,
                        'UTF-8'
                    );

                    $name = $optTitle;

                    $attributesData[] = [
                        'name' => $name,
                        'value' => $valueStr,
                        'isCustom' => 'true'
                    ];
                } else {
                    if (!$includeNoValues) {
                        continue;
                    }
                    $noValueTitles[] = $optTitle;
                }
            }

            $noValueTitles = array_values(array_unique(array_filter($noValueTitles)));
            if ($includeNoValues && !empty($noValueTitles)) {
                $valueStr = implode(' | ', $noValueTitles);
                $valueStr = $this->filterManager->stripTags($valueStr);
                // phpcs:ignore Magento2.Functions.DiscouragedFunction.DiscouragedWithAlternative
                $valueStr = htmlspecialchars(
                    $valueStr,
                    ENT_QUOTES | ENT_SUBSTITUTE,
                    'UTF-8'
                );

                $attributesData[] = [
                    'name' => 'Customizable options',
                    'value' => $valueStr,
                    'isCustom' => 'true'
                ];
            }

            return $attributesData;
        } catch (\Exception $e) {
            return [];
        }
    }
    // phpcs:disable Generic.Metrics.NestingLevel.TooHigh
    /**
     * Get product attributes
     *
     * @param \Magento\Catalog\Model\Product $product
     * @param array $selectedAttributes
     * @return array
     */
    protected function getProductAttributes($product, $selectedAttributes = [])
    {
        $attributes = $this->productAttributes->toOptionArray();

        $attributeSetId = $product->getAttributeSetId();
        $attributeSet = $this->attributeCollectionFactory->create()
            ->addFieldToSelect('attribute_id')
            ->setAttributeSetFilter($attributeSetId)
            ->load()
            ->getItems();
        $attributeIds = array_map(fn($attribute) => $attribute->getAttributeId(), $attributeSet);
        
        $data = [];
        foreach ($attributes as &$attribute) {
            if ($attribute['value'] === 'wtai_product_research_data'
                && in_array($attribute['value'], $selectedAttributes)
            ) {
                $selectedAttribute = [
                    'attribute' => $attribute['value'],
                    'value' => $attribute['value'],
                    'details' => ''
                ];
                $data[] = $selectedAttribute;
                continue;
            }
            
            if (!in_array($attribute['value'], $selectedAttributes) ||
                !in_array($attribute['id'], $attributeIds)
            ) {
                continue;
            }
            
            $selectedAttribute = [
                'attribute' => $attribute['label'],
                'value' => $attribute['value']
            ];

            if (in_array($attribute['value'], Excluded::ARRAY_ATTRIBUTES)) {
                try {
                    switch ($attribute['value']) {
                        case 'tier_price':
                            $selectedAttribute['details'] = '';
                            foreach ($product->getTierPrices() as $tierPrice) {
                                $qty = $tierPrice['qty'] ?? '';
                                $price = $tierPrice['value'] ?? '';
                                $groupName = $tierPrice['customer_group_id'] !== GroupInterface::CUST_GROUP_ALL ?
                                    $this->groupRepository->getById($tierPrice['customer_group_id']) :
                                    __('ALL GROUPS');
                                
                                // Check if it's an object and get the group name
                                if (is_object($groupName) && method_exists($groupName, 'getCode')) {
                                    $groupName = $groupName->getCode();
                                }

                                $selectedAttribute['details'] .= sprintf("%s: ", __('Customer Group'))
                                    . $groupName . "<br />"
                                    . sprintf("%s: ", __('Quantity')) . $qty . "<br />"
                                    . sprintf("%s: ", __('Price')) . $price . "<br /><br />";
                            }
                            
                            break;

                        case 'quantity_and_stock_status':
                            $quantityAndStockStatus = $product->getQuantityAndStockStatus();
                            $qty = $quantityAndStockStatus['qty'] ?? '';
                            $stockStatus = $quantityAndStockStatus['is_in_stock'] ?? '';
                            $stockStatusLabel = $stockStatus ? __('In Stock') : __('Out of Stock');
                            $selectedAttribute['details'] = '';

                            if ($qty || $stockStatus) {
                                $selectedAttribute['details'] = sprintf("%s: ", __('Quantity')) . $qty . "<br />"
                                    . sprintf("%s: ", __('Stock status')) . $stockStatusLabel;
                            }
                            
                            break;
                    }
                } catch (\Exception $e) {
                    continue;
                }

                $data[] = $selectedAttribute;
            } else {
                $selectedAttribute['details'] = '';

                if (strtolower($attribute['value']) === 'thumbnail') {
                    $imageHelper = $this->imageHelper->init($product, 'product_listing_thumbnail_preview');
                    try {
                        $thumbnail = $imageHelper->setImageFile($product->getData('thumbnail'));
                        $thumbnail->getUrl();
                        $thumbnail->getOriginalWidth();
                    } catch (\InvalidArgumentException | FileSystemException $e) {
                        continue;
                    }
                    
                    $selectedAttribute['details'] = $imageHelper->getUrl();
                    $imageHelper = $this->imageHelper->init($product, 'product_listing_thumbnail');
                    $selectedAttribute['thumbnail'] = $imageHelper->getUrl();
                    $value = $this->wtaImageHelper->getImageValue($product);
                    $selectedAttribute['value'] = $value;

                    if ($value) {
                        $data[] = $selectedAttribute;
                    }
                } else {
                    try {
                        $details = $product->getResource()
                            ->getAttribute($attribute['value'])
                            ->getFrontend()
                            ->getValue($product);

                        if ($details) {
                            $selectedAttribute['details'] = $this->outputHelper->productAttribute(
                                $product,
                                $details,
                                $attribute['value']
                            );
                        }

                        $data[] = $selectedAttribute;
                    } catch (\Exception $e) {
                        /** Skip attributes with error */
                        continue;
                    }
                }
            }
        }
        return $data;
    }
    // phpcs:enable Generic.Metrics.NestingLevel.TooHigh

    /**
     * Get product type mapping
     *
     * @param string $type
     * @return string
     */
    private function getProductTypeMapping($type)
    {
        if ($type === 'virtual' || $type === 'downloadable' || $type === 'simple') {
            return 'Simple';
        } elseif ($type === 'configurable') {
            return 'Variable';
        } elseif ($type === 'grouped') {
            return 'Grouped';
        } elseif ($type === 'bundle') {
            return 'Bundle';
        }
        return $type;
    }
    /**
     * Get product category paths
     *
     * @param \Magento\Catalog\Model\Product $product
     * @param int $storeId
     * @return array
     */
    private function getProductCategoryPaths($product, int $storeId): array
    {
        try {
            $categoryIds = $product->getCategoryIds();
            if (!is_array($categoryIds) || empty($categoryIds)) {
                return [];
            }

            $rootCategoryId = null;
            try {
                $rootCategoryId = (int) $this->storeManager->getStore($storeId)->getRootCategoryId();
            } catch (\Exception $e) {
                $rootCategoryId = null;
            }

            $collection = $this->categoryCollectionFactory->create();
            $collection->setStoreId($storeId);
            $collection->addAttributeToSelect(['name', 'path']);
            $collection->addFieldToFilter('entity_id', ['in' => $categoryIds]);

            $allPathIds = [];
            $categoryPathIdsByCategoryId = [];
            foreach ($collection as $category) {
                $pathIds = $category->getPathIds();
                $filteredPathIds = [];
                foreach ($pathIds as $pathId) {
                    $pathId = (int) $pathId;
                    if ($pathId <= 2) {
                        continue;
                    }
                    if ($rootCategoryId !== null && $pathId === $rootCategoryId) {
                        continue;
                    }
                    $filteredPathIds[] = $pathId;
                    $allPathIds[$pathId] = true;
                }
                $categoryPathIdsByCategoryId[(int) $category->getId()] = $filteredPathIds;
            }

            if (empty($allPathIds)) {
                return [];
            }

            $allCategoriesCollection = $this->categoryCollectionFactory->create();
            $allCategoriesCollection->setStoreId($storeId);
            $allCategoriesCollection->addAttributeToSelect(['name']);
            $allCategoriesCollection->addFieldToFilter('entity_id', ['in' => array_keys($allPathIds)]);

            $nameLookup = [];
            foreach ($allCategoriesCollection as $category) {
                $nameLookup[(int) $category->getId()] = (string) $category->getName();
            }

            $paths = [];
            foreach ($categoryPathIdsByCategoryId as $categoryId => $pathIds) {
                $pathNames = [];
                foreach ($pathIds as $pathId) {
                    if (isset($nameLookup[$pathId]) && $nameLookup[$pathId] !== '') {
                        $pathNames[] = $nameLookup[$pathId];
                    }
                }

                if (!empty($pathNames)) {
                    $categoryName = array_pop($pathNames);
                    $fullPath = implode('/', $pathNames);
                    $paths[] = [
                        'id' => (string) end($pathIds),
                        'name' => $categoryName,
                        'path' => $fullPath
                    ];
                }
            }

            return $paths;
        } catch (\Exception $e) {
            return [];
        }
    }

      /**
       * Get random product names for KO
       *
       * @param int $categoryID
       * @param int $storeId
       * @return array
       */
    public function getProductsNames($categoryID, $storeId)
    {
        try {
            $productsNames = $this->magentoCategory->getAllProductsNameRandomly($categoryID, $storeId, 100);
            $productsNamesString[] = implode(',', $productsNames);
            return $productsNamesString;
        } catch (\Exception $e) {
            return '';
        }
    }
}
