<?php
/**
 * @author 1902 Software
 * @copyright Copyright © 2023 1902 Software (https://1902software.com/magento/)
 * @package WriteTextAI_WriteTextAI
 */

namespace WriteTextAI\WriteTextAI\Controller\Adminhtml\Categories\Edit;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Controller\ResultFactory;
use WriteTextAI\WriteTextAI\Model\ApiManager;
use WriteTextAI\WriteTextAI\Model\Api\Keywords as ApiKeywords;
use WriteTextAI\WriteTextAI\Model\OptionSource\Filter\Stores as StoresFilter;
use WriteTextAI\WriteTextAI\Model\Magento\Category as MagentoCategory;
use WriteTextAI\WriteTextAI\Helper\Store as StoreHelper;
use WriteTextAI\WriteTextAI\Helper\Data as DataHelper;
use WriteTextAI\WriteTextAI\Model\Api\Session as ApiSession;
use WriteTextAI\WriteTextAI\Helper\Categories\Fields as FieldHelper;
use WriteTextAI\WriteTextAI\Helper\Generate as GenerateHelper;
use WriteTextAI\WriteTextAI\Model\GenerateOptionsManager;
use WriteTextAI\WriteTextAI\ViewModel\UserFieldsSelected;
use WriteTextAI\WriteTextAI\Model\UserFieldsSelectedManager;
use WriteTextAI\WriteTextAI\ViewModel\Settings;
use WriteTextAI\WriteTextAI\Model\AiCategoryManager;
use WriteTextAI\WriteTextAI\Model\Categories\GeneratedText as CategoryGeneratedText;
use Magento\Store\Model\StoreManagerInterface;
use WriteTextAI\WriteTextAI\Helper\Categories\RepresentativeProducts as RepresentativeProductsHelper;
use WriteTextAI\WriteTextAI\Model\KeywordIdeaFiltersManager;
use WriteTextAI\WriteTextAI\Helper\ReviewStatus as ReviewHelper;
use WriteTextAI\WriteTextAI\Model\Categories\MarkReview;
use WriteTextAI\WriteTextAI\Helper\Categories\Data as CategoriesDataHelper;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\Catalog\Helper\Image as ImageHelper;
use WriteTextAI\WriteTextAI\Helper\Image as WtaImageHelper;
use Magento\Catalog\Model\Product\Attribute\Source\Status;
use Magento\Catalog\Helper\Output as OutputHelper;
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite as UrlRewriteData;
use Magento\UrlRewrite\Model\UrlFinderInterface;
use WriteTextAI\WriteTextAI\Helper\Optimization as OptimizationHelper;
use Magento\User\Model\ResourceModel\User\CollectionFactory as UserCollectionFactory;
use WriteTextAI\WriteTextAI\ViewModel\AiModels as AiModelsViewModel;

class Index extends Action
{
    /**
     * @var ApiManager
     */
    protected $apiManager;

    /**
     * @var ApiKeywords
     */
    protected $apiKeywords;

    /**
     * @var StoresFilter
     */
    protected $storesFilter;

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

    /**
     * @var StoreHelper
     */
    protected $storeHelper;

    /**
     * @var DataHelper
     */
    protected $dataHelper;

    /**
     * @var ApiSession
     */
    protected $apiSession;

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

    /**
     * @var GenerateHelper
     */
    protected $generateHelper;

    /**
     * @var GenerateOptionsManager
     */
    protected $generateOptionsManager;

    /**
     * @var UserFieldsSelected
     */
    protected $userFieldsSelected;

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

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

    /**
     * @var CategoryGeneratedText
     */
    protected $categoryGeneratedText;

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

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

    /**
     * @var KeywordIdeaFiltersManager
     */
    protected $keywordIdeaFiltersManager;

    /**
     * @var ReviewHelper
     */
    protected $reviewHelper;

    /**
     * @var MarkReview
     */
    protected $markReview;

    /**
     * @var CategoriesDataHelper
     */
    protected $categoriesDataHelper;

    /**
     * @var CollectionFactory
     */
    protected $productCollectionFactory;

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

    /**
     * @var WtaImageHelper
     */
    protected $wtaImageHelper;

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

    /**
     * @var UrlFinderInterface
     */
    protected $urlFinder;

    /**
     * @var OptimizationHelper
     */
    protected $optimizationHelper;

    /**
     * @var UserCollectionFactory
     */
    protected $userCollectionFactory;

    /**
     * @var AiModelsViewModel
     */
    protected $aiModelsViewModel;

    /**
     * Constructor
     *
     * @param Context $context
     * @param ApiManager $apiManager
     * @param ApiKeywords $apiKeywords
     * @param StoresFilter $storesFilter
     * @param MagentoCategory $magentoCategory
     * @param StoreHelper $storeHelper
     * @param DataHelper $dataHelper
     * @param ApiSession $apiSession
     * @param FieldHelper $fieldHelper
     * @param GenerateHelper $generateHelper
     * @param GenerateOptionsManager $generateOptionsManager
     * @param UserFieldsSelected $userFieldsSelected
     * @param Settings $settings
     * @param AiCategoryManager $aiCategoryManager
     * @param CategoryGeneratedText $categoryGeneratedText
     * @param StoreManagerInterface $storeManager
     * @param RepresentativeProductsHelper $representativeProductsHelper
     * @param KeywordIdeaFiltersManager $keywordIdeaFiltersManager
     * @param ReviewHelper $reviewHelper
     * @param MarkReview $markReview
     * @param CategoriesDataHelper $categoriesDataHelper
     * @param CollectionFactory $productCollectionFactory
     * @param ImageHelper $imageHelper
     * @param WtaImageHelper $wtaImageHelper
     * @param OutputHelper $outputHelper
     * @param UrlFinderInterface $urlFinder
     * @param OptimizationHelper $optimizationHelper
     * @param UserCollectionFactory $userCollectionFactory
     * @param AiModelsViewModel $aiModelsViewModel
     */
    public function __construct(
        Context $context,
        ApiManager $apiManager,
        ApiKeywords $apiKeywords,
        StoresFilter $storesFilter,
        MagentoCategory $magentoCategory,
        StoreHelper $storeHelper,
        DataHelper $dataHelper,
        ApiSession $apiSession,
        FieldHelper $fieldHelper,
        GenerateHelper $generateHelper,
        GenerateOptionsManager $generateOptionsManager,
        UserFieldsSelected $userFieldsSelected,
        Settings $settings,
        AiCategoryManager $aiCategoryManager,
        CategoryGeneratedText $categoryGeneratedText,
        StoreManagerInterface $storeManager,
        RepresentativeProductsHelper $representativeProductsHelper,
        KeywordIdeaFiltersManager $keywordIdeaFiltersManager,
        ReviewHelper $reviewHelper,
        MarkReview $markReview,
        CategoriesDataHelper $categoriesDataHelper,
        CollectionFactory $productCollectionFactory,
        ImageHelper $imageHelper,
        WtaImageHelper $wtaImageHelper,
        OutputHelper $outputHelper,
        UrlFinderInterface $urlFinder,
        OptimizationHelper $optimizationHelper,
        UserCollectionFactory $userCollectionFactory,
        AiModelsViewModel $aiModelsViewModel
    ) {
        $this->apiManager = $apiManager;
        $this->apiKeywords = $apiKeywords;
        $this->storesFilter = $storesFilter;
        $this->magentoCategory = $magentoCategory;
        $this->storeHelper = $storeHelper;
        $this->dataHelper = $dataHelper;
        $this->apiSession = $apiSession;
        $this->fieldHelper = $fieldHelper;
        $this->generateHelper = $generateHelper;
        $this->generateOptionsManager = $generateOptionsManager;
        $this->userFieldsSelected = $userFieldsSelected;
        $this->settings = $settings;
        $this->aiCategoryManager = $aiCategoryManager;
        $this->categoryGeneratedText = $categoryGeneratedText;
        $this->storeManager = $storeManager;
        $this->representativeProductsHelper = $representativeProductsHelper;
        $this->keywordIdeaFiltersManager = $keywordIdeaFiltersManager;
        $this->reviewHelper = $reviewHelper;
        $this->markReview = $markReview;
        $this->categoriesDataHelper = $categoriesDataHelper;
        $this->productCollectionFactory = $productCollectionFactory;
        $this->imageHelper = $imageHelper;
        $this->wtaImageHelper = $wtaImageHelper;
        $this->outputHelper = $outputHelper;
        $this->urlFinder = $urlFinder;
        $this->optimizationHelper = $optimizationHelper;
        $this->userCollectionFactory = $userCollectionFactory;
        $this->aiModelsViewModel = $aiModelsViewModel;
        parent::__construct($context);
    }
    
    // phpcs:disable Generic.Metrics.NestingLevel.TooHigh

    /**
     * Execute
     *
     * @return \Magento\Framework\Controller\Result\Json
     */
    public function execute()
    {
        $response = $this->resultFactory->create(ResultFactory::TYPE_JSON);

        try {
            $request = $this->getRequest();
            $categoryId = $request->getParam('category_id');
            $storeId = $request->getParam('store_id');
            $currentUser = $this->apiSession->getCurrentUser();
            $category = $this->magentoCategory->getCategory($categoryId, $storeId);
            $subcategories = $this->magentoCategory->getAllChildren(true, $categoryId, $storeId);
            $representativeProducts = $this->magentoCategory->getProductCollection($subcategories, $storeId);
            $generatedText = $this->categoryGeneratedText->getGenerated($categoryId, $storeId, 'Category');
            $aiCategory = $this->aiCategoryManager->getCategory($categoryId, $storeId);

            $mappingSettings = $this->fieldHelper->getMappingSettings();
            $useDefault = [];
            foreach ($mappingSettings as $field => $value) {
                $useDefault[$field] = $this->fieldHelper->isUsingDefaultValues(
                    $category,
                    $storeId,
                    $value
                );
            }
        
            $languageCode = $this->storeHelper->getRegionIndependentLanguage($storeId);

            $categoryImage = '';

            $categoryImage = $this->wtaImageHelper->getCategoryImageUrl($category);

            $categoryName = $category->getName();

            $optionValues = array_values($this->storesFilter->toOptionArray());
            $storesForCategory = $this->filterStoresByCategory($optionValues, (string) $category->getPath());

            $frontendStoreId = (int) $this->storeHelper->getFrontendStoreId($storeId);
            if ((int) $storeId === 0) {
                $firstCategoryStoreId = $this->getFirstStoreViewIdFromOptions($storesForCategory, (int) $categoryId);
                if ($firstCategoryStoreId > 0) {
                    $frontendStoreId = $firstCategoryStoreId;
                }
            }

            $useStoreSwitchUrl = ((int) $storeId === 0);
            if (!$useStoreSwitchUrl) {
                try {
                    $defaultStoreView = $this->storeManager->getDefaultStoreView();
                    if ($defaultStoreView) {
                        $selectedStore = $this->storeManager->getStore((int) $frontendStoreId);

                        $defaultGroupId = (int) $defaultStoreView->getGroupId();
                        $selectedGroupId = (int) $selectedStore->getGroupId();

                        if ($defaultGroupId && $selectedGroupId && $defaultGroupId !== $selectedGroupId) {
                            $defaultBaseUrl =
                                (string) $this->storeHelper->getFrontendStoreBaseUrl((int) $defaultStoreView->getId());
                            $selectedBaseUrl =
                                (string) $this->storeHelper->getFrontendStoreBaseUrl((int) $frontendStoreId);
                            // phpcs:disable Magento2.Functions.DiscouragedFunction.Discouraged
                            $defaultHost = (string) (parse_url($defaultBaseUrl, PHP_URL_HOST) ?? '');
                            $selectedHost = (string) (parse_url($selectedBaseUrl, PHP_URL_HOST) ?? '');
                            // phpcs:enable Magento2.Functions.DiscouragedFunction.Discouraged
                            if ($defaultHost !== '' && $selectedHost !== '' && $defaultHost === $selectedHost) {
                                $useStoreSwitchUrl = true;
                            }
                        }
                    }
                } catch (\Exception $e) {
                    $useStoreSwitchUrl = false;
                }
            }

            $categoryUrl =
                $this->getUrlByCategoryId($category, $categoryId, $frontendStoreId);
            $categoryUrl = $useStoreSwitchUrl
                ? $this->normalizeFrontendUrl((int) $frontendStoreId, (string) $categoryUrl)
                : $categoryUrl;
            $categoryUrlForSwitch = $useStoreSwitchUrl
                ? $this->buildFrontendStoreSwitchUrl((int) $frontendStoreId, (string) $categoryUrl)
                : $categoryUrl;

            $isEnabledInPreviewStore = $this->isCategoryEnabledInStoreView((int) $categoryId, (int) $frontendStoreId);

            $searchIntent = $this->userFieldsSelected->getUserFieldsSelected(
                UserFieldsSelectedManager::ACTION_TYPE_SEARCH_INTENT,
                'category',
                ''
            );
            if ($searchIntent) {
                $searchIntentSelected = explode(',', $searchIntent);
            } else {
                $searchIntentSelected = explode(
                    ',',
                    'commercial'
                );
            }
            
            $optimizationData = $this->apiKeywords->getOptimization(
                $storeId,
                $categoryId,
                'Category'
            );

            $aiModelsUsed = $this->categoryGeneratedText->getTextFieldsModel(
                $categoryId,
                $storeId,
                $generatedText
            );
            $datesGenerated = $this->categoryGeneratedText->getTextFieldsDate(
                $categoryId,
                $storeId,
                $generatedText
            );
            
            $lastModelUsed = $this->getLastGenerated($aiModelsUsed, $datesGenerated);
            
            if ($this->aiModelsViewModel && !$this->aiModelsViewModel->hasAiModels()) {
                $lastModelUsed = '';
            }
            
            $result = [
                'success' => true,
                'api_texts' => $generatedText,
                'language' => strtoupper($languageCode),
                'country' => $this->keywordIdeaFiltersManager->getCountryCode($storeId),
                'stores' => $storesForCategory,
                'store_scope' => $this->storeHelper->getStoreScope($storeId),
                'store_id' => $storeId,
                'category_data' => $category->getData(),
                'name' => $categoryName,
                'is_active' => (bool)$category->getIsActive(),
                'category_placeholder_image' => $this->imageHelper->getDefaultPlaceholderUrl('thumbnail'),
                'image' => $categoryImage,
                'image_id' => $this->wtaImageHelper->getCategoryImageId($categoryId, $storeId, $categoryImage),
                'api_thumbnail' => $optimizationData['imageId'] ?? '',
                'breadcrumbs' => $this->categoriesDataHelper->getBreadcrumbs($category, $storeId),
                'users' => $this->getUsers(),
                'use_default_image' => $this->fieldHelper->isUsingDefaultValues(
                    $category,
                    $storeId,
                    'image'
                ),
                'representative_products' => [
                    'options' => $representativeProducts['options'],
                    'total' => $representativeProducts['total'],
                    'selected' => $this->removeNonExistingProducts(
                        $this->representativeProductsHelper->getRepresentativeProductsSelected($aiCategory),
                        $representativeProducts['all_options'],
                        $storeId
                    ),
                    'other_details_checked' => (bool)$aiCategory->getOtherDetailsChecked(),
                    'other_details' => $aiCategory->getOtherDetails(),
                    'product_research_data' => $this->userFieldsSelected->getUserFieldsSelected(
                        UserFieldsSelectedManager::ACTION_TYPE_PRODUCT_RESEARCH_DATA,
                        '',
                        ''
                    ) === "true"
                ],
                'additional_prompt' => $aiCategory->getAdditionalPrompt(),
                'category_url' => $categoryUrl,
                'link_preview_url' => $isEnabledInPreviewStore ? $categoryUrlForSwitch : '',
                'preview_changes_url' => $isEnabledInPreviewStore
                ? (function () use ($useStoreSwitchUrl, $frontendStoreId, $categoryUrl, $currentUser) {
                    $previewUrl = (string) ($categoryUrl . '?' . http_build_query([
                        'wtai-preview' => base64_encode($currentUser->getId())
                    ]));
                    $previewUrl = $useStoreSwitchUrl
                    ? $this->normalizeFrontendUrl((int) $frontendStoreId, $previewUrl) : $previewUrl;
                    return $useStoreSwitchUrl
                        ? $this->buildFrontendStoreSwitchUrl((int) $frontendStoreId, $previewUrl)
                        : $previewUrl;
                })() : '',
                'texts' => [
                    'category_description' => (string) $this->outputHelper->categoryAttribute(
                        $category,
                        $category->getData($mappingSettings['category_description'] ?? 'description'),
                        $mappingSettings['category_description'] ?? 'description'
                    ),
                    'page_title' => (string) $this->outputHelper->categoryAttribute(
                        $category,
                        $category->getData($mappingSettings['page_title'] ?? 'meta_title'),
                        $mappingSettings['page_title'] ?? 'meta_title'
                    ),
                    'page_description' => (string) $this->outputHelper->categoryAttribute(
                        $category,
                        $category->getData($mappingSettings['page_description'] ?? 'meta_description'),
                        $mappingSettings['page_description'] ?? 'meta_description'
                    )
                ],
                'generated_texts' => $this->categoryGeneratedText->getTextFields(
                    $categoryId,
                    $storeId,
                    false,
                    $generatedText
                ),
                'textfields_statuses' => $this->categoryGeneratedText->getTextFieldsStatuses(
                    $categoryId,
                    $storeId,
                    $generatedText
                ),
                'keywords_used' => $this->categoryGeneratedText->getTextsKeywordsUsed($generatedText),
                'use_default' => $useDefault,
                'reviewed' => $this->markReview->getReviewed($categoryId, $storeId, $generatedText),
                'review_status' => $this->reviewHelper->getCategoryReviewStatus($categoryId, $storeId),
                'feedback' => $this->categoryGeneratedText->getTextsFeedback($generatedText),
                'search_intent_selected' => $searchIntentSelected,
                'templates_used' => $this->categoryGeneratedText->getTextFieldsTemplate(
                    $categoryId,
                    $storeId,
                    $generatedText
                ),
                'ai_models_used' => $aiModelsUsed,
                'last_brandvoice_used' => $lastModelUsed
            ];

            $result['optimization'] = $optimizationData;
            $selectedKeywords = $this->getSelectedKeywords(
                $optimizationData,
                $categoryName,
                $storeId,
                $categoryId
            );

            $settingsData = $this->getSettingsData($storeId, $categoryId, $categoryName, $selectedKeywords);
            $userPreferences = $this->getUserPreferences();

            $result = array_merge(
                $result,
                $settingsData,
                $userPreferences,
                $selectedKeywords
            );
        } catch (\Exception $e) {
            $result = [
                'success' => false,
                'message' => __(
                    'A system error has occurred. Please try again. If the issue persists,'
                    . ' please contact our support team at support@writetext.ai.'
                ),
                'error' => $e->getMessage(),
                'trace' => $e->getTrace()
            ];
        }

        $response->setData($result);

        return $response;
    }
    // phpcs:enable Generic.Metrics.NestingLevel.TooHigh
    
    /**
     * Build frontend store switch url so frontend store cookie is set before redirect.
     *
     * @param int $storeId
     * @param string $targetUrl
     * @return string
     */
    private function buildFrontendStoreSwitchUrl($storeId, $targetUrl)
    {
        if (!$this->storeHelper->hasMultipleStoreViews()) {
            return $targetUrl;
        }

        $storeCode = $this->storeHelper->getFrontendStoreCode($storeId);
        $fromStoreCode = $this->storeHelper->getDefaultStoreCode();
        $baseUrl = rtrim($this->storeHelper->getFrontendStoreBaseUrl($storeId), '/');

        return $baseUrl
            . '/stores/store/switch'
            . '?___store=' . urlencode($storeCode)
            . '&uenc=' . urlencode(base64_encode($targetUrl));
    }
                        
    // phpcs:disable Magento2.Functions.DiscouragedFunction.Discouraged
    /**
     * Normalize frontend url
     *
     * @param int $storeId
     * @param string $url
     * @return string
     */
    private function normalizeFrontendUrl($storeId, $url)
    {
        $baseUrl = rtrim($this->storeHelper->getFrontendStoreBaseUrl($storeId), '/');
        if ($baseUrl === '') {
            return $url;
        }

        $baseParts = parse_url($baseUrl);
        if (is_array($baseParts) && !empty($baseParts['scheme']) && !empty($baseParts['host'])) {
            $cleanBaseUrl = $baseParts['scheme'] . '://' . $baseParts['host'];
            if (!empty($baseParts['port'])) {
                $cleanBaseUrl .= ':' . $baseParts['port'];
            }
            $baseUrl = $cleanBaseUrl;
        }
        
        $parts = parse_url($url);
        if (!is_array($parts) || empty($parts['path'])) {
            return $url;
        }

        $normalized = $baseUrl . '/' . ltrim((string) $parts['path'], '/');
        if (!empty($parts['query'])) {
            $normalized .= '?' . $parts['query'];
        }
        if (!empty($parts['fragment'])) {
            $normalized .= '#' . $parts['fragment'];
        }

        return $normalized;
    }
    // phpcs:enable Magento2.Functions.DiscouragedFunction.Discouraged

    /**
     * Get last generated
     *
     * @param array $aiModelsUsed
     * @param array $datesGenerated
     * @return string
     */
    public function getLastGenerated($aiModelsUsed, $datesGenerated)
    {
        $latestDate = null;
        $latestModel = '';
        $latestField = '';

        foreach ($datesGenerated as $field => $date) {
            if (!empty($date)) {
                try {
                    $dateTime = new \DateTime($date);
                } catch (\Exception $e) {
                    $dateTime = false;
                }
                if ($dateTime && (!$latestDate || $dateTime > $latestDate)) {
                    $latestDate = $dateTime;
                    $latestModel = $aiModelsUsed[$field] ?? '';
                    $latestField = $field;
                }
            }
        }

        return $latestModel;
    }

    /**
     * Get category url
     *
     * @param \Magento\Catalog\Model\Category $category
     * @param int $categoryId
     * @param int $storeId
     * @return string
     */
    public function getUrlByCategoryId($category, $categoryId, $storeId)
    {
        $storeId = (int) $storeId;
        $storeId = (int) $this->storeHelper->getFrontendStoreId($storeId);

        $store = $this->storeManager->getStore($storeId);
        $rewrite = $this->urlFinder->findOneByData([
            UrlRewriteData::ENTITY_ID => $categoryId,
            UrlRewriteData::ENTITY_TYPE => 'category',
            UrlRewriteData::STORE_ID => $storeId
        ]);
        
        $category->getUrlInstance()->setScope($storeId);

        if ($rewrite && $rewrite->getRequestPath()) {
            return rtrim($store->getBaseUrl(), '/') . '/' . ltrim($rewrite->getRequestPath(), '/');
        }

        return rtrim($store->getBaseUrl(), '/') . '/catalog/category/view/id/' . (int) $categoryId . '/';
    }

    /**
     * Remove non-existing products
     *
     * @param array $selected
     * @param array $options
     * @param int $storeId
     *
     * @return array
     */
    private function removeNonExistingProducts($selected, $options, $storeId)
    {
        $newSelected = [];

        foreach ($selected as $_selected) {
            if (in_array($_selected->value, $options)) {
                $newSelected[] = $_selected;
            }
        }

        $newSelected = $this->updateProductData($newSelected, $storeId);

        return $newSelected;
    }

    /**
     * Update product data
     *
     * @param array $selected
     * @param int $storeId
     *
     * @return array
     */
    private function updateProductData($selected, $storeId)
    {
        $ids = [];
        foreach ($selected as $_selected) {
            $ids[] = $_selected->value;
        }

        $collection = $this->productCollectionFactory->create();
        $collection->setStoreId($storeId);
        $collection->addAttributeToSelect('*');
        $collection->addFieldToFilter('entity_id', ['in' => $ids]);
        $collection->addMediaGalleryData();

        $newSelected = [];
        $mappingSettings = $this->dataHelper->getMappingSettings();
        foreach ($collection as $product) {
            $image = $this->imageHelper->init($product, 'product_listing_thumbnail')
                ->setImageFile($product->getThumbnail())
                ->getUrl();
            $imageId = $this->wtaImageHelper->getImageValue($product);
            $status = $product->getStatus() == Status::STATUS_ENABLED ? __('enabled') : __('disabled');
            $newSelected[] = [
                'value' => $product->getId(),
                'label' => $product->getName(),
                'image' => $image,
                'image_id' => $imageId,
                'description' => $product->getData($mappingSettings['product_description']),
                'status' => sprintf("(%s)", $status)
            ];
        }

        return $newSelected;
    }

    /**
     * Get user preferences
     *
     * @return array
     */
    private function getUserPreferences()
    {

            $userDescMin = $this->dataHelper->getCategoryDescriptionSettings('min');
    
            $userDescMax = $this->dataHelper->getCategoryDescriptionSettings('max');

        return [
            'guide_steps' => filter_var($this->userFieldsSelected->getUserFieldsSelected(
                UserFieldsSelectedManager::ACTION_TYPE_GUIDE_STEPS,
                '',
                'edit'
            ), FILTER_VALIDATE_BOOLEAN),
            'selected_fields' => $this->userFieldsSelected->getUserFieldsSelected(
                UserFieldsSelectedManager::ACTION_TYPE_SINGLE_EDITOR_FIELDS,
                'category',
                'edit'
            ),
            'highlight_pronouns' => $this->userFieldsSelected->getUserFieldsSelected(
                UserFieldsSelectedManager::ACTION_TYPE_HIGHLIGHT_PRONOUNS,
                '',
                'edit'
            ),
            'category_image_selected' => $this->userFieldsSelected->getUserFieldsSelected(
                UserFieldsSelectedManager::ACTION_TYPE_CATEGORY_IMAGE,
                'category',
                'edit'
            ),
            'auto_generate_after_ko' => filter_var($this->userFieldsSelected->getUserFieldsSelected(
                UserFieldsSelectedManager::ACTION_TYPE_AUTO_GENERATE_AFTER_KO,
                '',
                'edit'
            ), FILTER_VALIDATE_BOOLEAN),
            'desc_min' => $userDescMin,
            'desc_max' => $userDescMax
        ];
    }

    /**
     * Get settings parameters
     *
     * @param int $storeId
     * @param int $categoryId
     * @param string $categoryName
     * @param array $selectedKeywords
     *
     * @return array
     */
    private function getSettingsData($storeId, $categoryId, $categoryName, $selectedKeywords)
    {
        $tonesOptions = $this->generateOptionsManager->getOptions('tones');
        $stylesOptions = $this->generateOptionsManager->getOptions('styles');
        $audienceOptions = $this->generateOptionsManager->getOptions('audience');

        $userTones = $this->userFieldsSelected->getUserFieldsSelected(
            UserFieldsSelectedManager::ACTION_TYPE_TONES,
            'global',
            'grid'
        );

        if (empty($userTones)) {
            $defaultTones = array_filter($tonesOptions, function ($tone) {
                return !empty($tone['default']);
            });
            $userTones = array_column($defaultTones, 'id');
        }

        $tones = $this->generateHelper->updateDefault(
            $tonesOptions,
            $userTones
        );

        $userStyles = $this->userFieldsSelected->getUserFieldsSelected(
            UserFieldsSelectedManager::ACTION_TYPE_STYLE,
            'global',
            'grid'
        );

        if (empty($userStyles)) {
            $defaultStyles = array_filter($stylesOptions, function ($style) {
                return !empty($style['default']);
            });
            $styleIds = array_column($defaultStyles, 'id');
            $userStyles = array_shift($styleIds);
        }

        $styles = $this->generateHelper->updateDefault(
            $stylesOptions,
            $userStyles ? [$userStyles] : []
        );

        $userAudiences = $this->userFieldsSelected->getUserFieldsSelected(
            UserFieldsSelectedManager::ACTION_TYPE_AUDIENCES,
            'global',
            'grid'
        );

        if (empty($userAudiences)) {
            $defaultAudiences = array_filter($audienceOptions, function ($audience) {
                return !empty($audience['default']);
            });
            $userAudiences = array_column($defaultAudiences, 'id');
        }

        $audiences = $this->generateHelper->updateDefault(
            $audienceOptions,
            $userAudiences
        );
        
        $audience = [];
        $keywords = [$categoryName];
        if (isset($selectedKeywords['selected_keywords'])) {
            $keywordsData = $selectedKeywords['selected_keywords'];
            if (isset($selectedKeywords['optimizing_keywords']) && !empty($selectedKeywords['optimizing_keywords'])) {
                $keywordsData = $selectedKeywords['optimizing_keywords'];
            }
            //make sure selected_keywords are all small letters
            $keywordsData = array_map('strtolower', $keywordsData);
            $keywords = array_merge($keywords, $keywordsData);
            $audience = $this->apiManager->getSuggestedAudience(
                $storeId,
                $categoryId,
                $keywords,
                'false',
                'Category'
            );
        }

        $formalLanguageSupport = $this->settings->getSettings('formalLanguageSupport');

        $langCode = $this->storeHelper->getRegionIndependentLanguage($storeId);

        $formalLanguages = [];
        if (in_array($langCode, $formalLanguageSupport)) {
            $formalLanguages = $this->settings->getFormalLanguages($langCode);
        }
        $customTone = $this->getCustomTones($tones);
        $customStyle = $this->getCustomStyles($styles);

        // Remove 'custom' from tones array
        $tones = array_filter($tones, function ($tone) {
            return !isset($tone['id']) || $tone['id'] !== 'custom';
        });

        return [
            'user_tones' => $userTones,
            'user_styles' => $userStyles,
            'tones' => $tones,
            'styles' => $styles,
            'audience' => $audiences,
            'custom_tone' => $customTone,
            'custom_style' => $customStyle,
            'selected_audience' => $audience['selected'] ?? [],
            'suggested_audience' => $audience['values'] ?? [],
            'disallowed_combinations' => $this->settings->getSettings('disallowedCombinations'),
            'formal_language_support' => $formalLanguageSupport,
            'formal_languages' => $formalLanguages,
            'global_triggers' => $this->optimizationHelper->getGlobalTriggers('Category')
        ];
    }

    /**
     * Get selected keywords
     *
     * @param array $optimizationData
     * @param string $categoryName
     * @param int $storeId
     * @param int $categoryId
     */
    private function getSelectedKeywords($optimizationData, $categoryName, $storeId, $categoryId)
    {
        /**
         * Get selected keywords for optimizationData
         */
        $keywords = [];
        $optimizingKeywords = [];
        if (!empty($optimizationData)) {
            $keywords = $optimizationData['manualKeywords'] ?? [];
            $optimizingKeywords = $optimizationData['optimizingKeywords'] ?? [];
        }

        return [
            'selected_keywords' => $keywords,
            'optimizing_keywords' => $optimizingKeywords
        ];
    }
    
    /**
     * Get users
     *
     * @return array
     */
    private function getUsers()
    {
        $collection = $this->userCollectionFactory->create();
        $users = [];

        foreach ($collection as $user) {
            $users[] = [
                'id' => $user->getUserId(),
                'name' => $user->getFirstname() . ' ' . $user->getLastname()
            ];
        }

        return $users;
    }
    
    /**
     * Get custom tones
     *
     * @param array $tones
     * @return string
     */
    public function getCustomTones($tones)
    {
        $customTone = '';
        foreach ($tones as $tone) {
            if (isset($tone['id']) && $tone['id'] === 'custom') {
                if (!$tone['default']) {
                    return '';
                }
            }
        }
        
        $customTone = $this->userFieldsSelected->getUserFieldsSelected(
            UserFieldsSelectedManager::ACTION_TYPE_CUSTOM_TONE,
            'global',
            'grid'
        );
        
        if (isset($customTone)) {
            return $customTone;
        }
        
        return $this->generateOptionsManager->getCustomTones();
    }
    /**
     * Get custom styles
     *
     * @param array $styles
     * @return array
     */
    public function getCustomStyles($styles)
    {
        foreach ($styles as $style) {
            if (isset($style['id']) && $style['id'] === 'custom') {
                if (!$style['default']) {
                    return '';
                }
            }
        }
        
        $customStyle = $this->userFieldsSelected->getUserFieldsSelected(
            UserFieldsSelectedManager::ACTION_TYPE_CUSTOM_STYLE,
            'global',
            'grid'
        );
        
        if (isset($customStyle)) {
            return $customStyle;
        }
        
        return $this->generateOptionsManager->getCustomStyles();
    }

    /**
     * Filter store switcher options by category availability.
     *
     * @param array $options
     * @param string $categoryPath
     * @return array
     */
    private function filterStoresByCategory(array $options, string $categoryPath): array
    {
        $filtered = [];

        foreach ($options as $option) {
            if (isset($option['value']) && is_array($option['value'])) {
                $children = $this->filterStoresByCategory($option['value'], $categoryPath);

                if (!empty($children)) {
                    $option['value'] = $children;
                    $filtered[] = $option;
                }
            } else {
                $storeViewId = (int) ($option['value'] ?? 0);
                if ($storeViewId > 0 && $this->isCategoryAvailableInStoreView($storeViewId, $categoryPath)) {
                    $filtered[] = $option;
                }
            }
        }

        return $filtered;
    }

    /**
     * Check whether the category belongs to the store view (based on root category).
     *
     * @param int $storeViewId
     * @param string $categoryPath
     * @return bool
     */
    private function isCategoryAvailableInStoreView(int $storeViewId, string $categoryPath): bool
    {
        try {
            $store = $this->storeManager->getStore($storeViewId);
            $rootCategoryId = (int) $store->getRootCategoryId();
            if ($rootCategoryId <= 0) {
                return false;
            }

            $pathParts = array_filter(explode('/', $categoryPath));
            return in_array((string) $rootCategoryId, $pathParts, true);
        } catch (\Exception $e) {
            return false;
        }
    }
    /**
     * Check whether the category is enabled in the store view.
     *
     * @param int $categoryId
     * @param int $storeViewId
     * @return bool
     */
    private function isCategoryEnabledInStoreView(int $categoryId, int $storeViewId): bool
    {
        try {
            $category = $this->magentoCategory->getCategory($categoryId, $storeViewId);
            return (bool) $category->getIsActive();
        } catch (\Exception $e) {
            return false;
        }
    }

    /**
     * Get first store view id from nested store switcher options.
     *
     * @param array $options
     * @param int $categoryId
     * @return int
     */
    private function getFirstStoreViewIdFromOptions(array $options, int $categoryId): int
    {
        $ids = [];
        foreach ($options as $option) {
            if (isset($option['value']) && is_array($option['value'])) {
                $childId = $this->getFirstStoreViewIdFromOptions($option['value'], $categoryId);
                if ($childId > 0) {
                    $ids[] = $childId;
                }
                continue;
            }

            $id = (int) ($option['value'] ?? 0);
            if ($id > 0 && $this->isCategoryEnabledInStoreView($categoryId, $id)) {
                $ids[] = $id;
            }
        }

        if (empty($ids)) {
            return 0;
        }

        sort($ids);
        return (int) $ids[0];
    }
}
