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

namespace WriteTextAI\WriteTextAI\Controller\Adminhtml\Grid;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Data\Form\FormKey;
use Magento\Framework\HTTP\PhpEnvironment\RemoteAddress;
use Magento\Store\Model\ScopeInterface;
use Magento\Ui\Component\MassAction\Filter;
use WriteTextAI\WriteTextAI\Helper\Data;
use WriteTextAI\WriteTextAI\Ui\Component\MassAction\JsonFilter;
use WriteTextAI\WriteTextAI\Helper\Generate as GenerateHelper;
use WriteTextAI\WriteTextAI\Model\ApiManager;
use WriteTextAI\WriteTextAI\Model\Config\Source\ProductAttributes;
use WriteTextAI\WriteTextAI\Model\OptionSource\Filter\Fields;
use Magento\Catalog\Api\ProductRepositoryInterface;
use WriteTextAI\WriteTextAI\Model\AiProductManager;
use WriteTextAI\WriteTextAI\Model\Config\Source\ProductAttributes\Excluded;
use Magento\Customer\Api\GroupRepositoryInterface;
use Magento\Customer\Api\Data\GroupInterface;
use Magento\Catalog\Helper\Output as OutputHelper;
use WriteTextAI\WriteTextAI\Helper\Html as HtmlHelper;
use Magento\Framework\Filter\FilterManager;
use Magento\Framework\Escaper;
use Magento\Backend\Model\UrlInterface;
use WriteTextAI\WriteTextAI\ViewModel\Settings;
use WriteTextAI\WriteTextAI\ViewModel\UserFieldsSelected;
use Magento\Catalog\Helper\Image as ImageHelper;
use WriteTextAI\WriteTextAI\Helper\Image as WTAImageHelper;
use Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory as AttributeCollectionFactory;
use WriteTextAI\WriteTextAI\Model\BulkGenerateRequestsManager;
use WriteTextAI\WriteTextAI\Model\FullAutomationRequestsManager;
use WriteTextAI\WriteTextAI\Model\BulkKeywordAnalysisRequestsManager;
use WriteTextAI\WriteTextAI\Model\Api\Session as ApiSession;
use Magento\Framework\Exception\FileSystemException;
use WriteTextAI\WriteTextAI\Model\BulkTransferRequestsManager;
use Magento\Store\Model\Store;
use WriteTextAI\WriteTextAI\Helper\Store as StoreHelper;
use WriteTextAI\WriteTextAI\Model\Api\Keywords;
use WriteTextAI\WriteTextAI\Model\Config\Source\AutomaticTextOptimization;
use WriteTextAI\WriteTextAI\Helper\Product as ProductHelper;
use WriteTextAI\WriteTextAI\Helper\Fields as FieldHelper;

class MassGenerate extends Action implements HttpPostActionInterface
{
    public const ADMIN_RESOURCE = 'WriteTextAI_WriteTextAI::generate';

    /**
     * @var ApiManager
     */
    protected $apiManager;

    /**
     * @var RemoteAddress
     */
    protected $remoteAddress;

    /**
     * @var ScopeConfigInterface
     */
    protected $scopeConfig;
    
    /**
     * @var JsonFilter
     */
    protected $filter;

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

    /**
     * @var Data
     */
    protected $helper;

    /**
     * @var FormKey
     */
    protected $formKey;

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

    /**
     * @var ProductRepositoryInterface
     */
    protected $productRepository;

    /**
     * @var AiProductManager
     */
    protected $aiProductManager;

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

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

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

    /**
     * @var HtmlHelper
     */
    protected $htmlHelper;

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

    /**
     * @var Escaper
     */
    protected $escaper;

    /**
     * @var UrlInterface
     */
    protected $urlBuilder;

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

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

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

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

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

    /**
     * @var BulkGenerateRequestsManager
     */
    protected $bulkGenerateRequestsManager;

    /**
     * @var FullAutomationRequestsManager
     */
    protected $fullAutomationRequestsManager;

    /**
     * @var BulkKeywordAnalysisRequestsManager
     */
    protected $bulkKeywordAnalysisRequestsManager;

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

    /**
     * @var BulkTransferRequestsManager
     */
    protected $BulkTransferRequestsManager;

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

    /**
     * @var Keywords
     */
    protected $keywords;

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

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

    /**
     * Constructor
     *
     * @param Context $context
     * @param ApiManager $apiManager
     * @param RemoteAddress $remoteAddress
     * @param ScopeConfigInterface $scopeConfig
     * @param JsonFilter $filter
     * @param CollectionFactory $collectionFactory
     * @param Data $helper
     * @param FormKey $formKey
     * @param ProductAttributes $productAttributes
     * @param ProductRepositoryInterface $productRepository
     * @param AiProductManager $aiProductManager
     * @param GroupRepositoryInterface $groupRepository
     * @param OutputHelper $outputHelper
     * @param GenerateHelper $generateHelper
     * @param HtmlHelper $htmlHelper
     * @param FilterManager $filterManager
     * @param Escaper $escaper
     * @param UrlInterface $urlBuilder
     * @param Settings $settings
     * @param UserFieldsSelected $userFieldsSelected
     * @param ImageHelper $imageHelper
     * @param WTAImageHelper $wtaImageHelper
     * @param AttributeCollectionFactory $attributeCollectionFactory
     * @param BulkGenerateRequestsManager $bulkGenerateRequestsManager
     * @param FullAutomationRequestsManager $fullAutomationRequestsManager
     * @param BulkKeywordAnalysisRequestsManager $bulkKeywordAnalysisRequestsManager
     * @param ApiSession $apiSession
     * @param BulkTransferRequestsManager $BulkTransferRequestsManager
     * @param StoreHelper $storeHelper
     * @param Keywords $keywords
     * @param ProductHelper $productHelper
     * @param FieldHelper $fieldHelper
     */
    public function __construct(
        Context $context,
        ApiManager $apiManager,
        RemoteAddress $remoteAddress,
        ScopeConfigInterface $scopeConfig,
        JsonFilter $filter,
        CollectionFactory $collectionFactory,
        Data $helper,
        FormKey $formKey,
        ProductAttributes $productAttributes,
        ProductRepositoryInterface $productRepository,
        AiProductManager $aiProductManager,
        GroupRepositoryInterface $groupRepository,
        OutputHelper $outputHelper,
        GenerateHelper $generateHelper,
        HtmlHelper $htmlHelper,
        FilterManager $filterManager,
        Escaper $escaper,
        UrlInterface $urlBuilder,
        Settings $settings,
        UserFieldsSelected $userFieldsSelected,
        ImageHelper $imageHelper,
        WTAImageHelper $wtaImageHelper,
        AttributeCollectionFactory $attributeCollectionFactory,
        BulkGenerateRequestsManager $bulkGenerateRequestsManager,
        FullAutomationRequestsManager $fullAutomationRequestsManager,
        BulkKeywordAnalysisRequestsManager $bulkKeywordAnalysisRequestsManager,
        ApiSession $apiSession,
        BulkTransferRequestsManager $BulkTransferRequestsManager,
        StoreHelper $storeHelper,
        Keywords $keywords,
        ProductHelper $productHelper,
        FieldHelper $fieldHelper
    ) {
        $this->apiManager = $apiManager;
        $this->remoteAddress = $remoteAddress;
        $this->scopeConfig = $scopeConfig;
        $this->filter = $filter;
        $this->collectionFactory = $collectionFactory;
        $this->helper = $helper;
        $this->formKey = $formKey;
        $this->productAttributes = $productAttributes;
        $this->productRepository = $productRepository;
        $this->aiProductManager = $aiProductManager;
        $this->groupRepository = $groupRepository;
        $this->outputHelper = $outputHelper;
        $this->generateHelper = $generateHelper;
        $this->htmlHelper = $htmlHelper;
        $this->filterManager = $filterManager;
        $this->escaper = $escaper;
        $this->urlBuilder = $urlBuilder;
        $this->settings = $settings;
        $this->userFieldsSelected = $userFieldsSelected;
        $this->imageHelper = $imageHelper;
        $this->wtaImageHelper = $wtaImageHelper;
        $this->attributeCollectionFactory = $attributeCollectionFactory;
        $this->bulkGenerateRequestsManager = $bulkGenerateRequestsManager;
        $this->fullAutomationRequestsManager = $fullAutomationRequestsManager;
        $this->bulkKeywordAnalysisRequestsManager = $bulkKeywordAnalysisRequestsManager;
        $this->apiSession = $apiSession;
        $this->BulkTransferRequestsManager = $BulkTransferRequestsManager;
        $this->storeHelper = $storeHelper;
        $this->keywords = $keywords;
        $this->productHelper = $productHelper;
        $this->fieldHelper = $fieldHelper;
        parent::__construct($context);
    }

    /**
     * Execute
     *
     * @return \Magento\Framework\Controller\Result\Json
     */
    public function execute()
    {
        $response = $this->resultFactory->create(ResultFactory::TYPE_JSON);
        
        try {
            $uploadedImages = $this->getRequest()->getPost('uploaded_images', []);
            $selectedFields = $this->getRequest()->getPost('fields');
            $skipImages = $this->getRequest()->getPost('skip_images', []);
            $skipThumbnails = $this->getRequest()->getPost('skip_thumbnails', []);
            $tones = $this->getRequest()->getPost('tones', explode(",", (string) $this->helper->getTones()));
            $style = $this->getRequest()->getPost('styles', (string) $this->helper->getStyles());
            $customTone = $this->getRequest()->getPost('custom_tone', "");
            $customStyle = $this->getRequest()->getPost('custom_style', "");
            $audience = $this->getRequest()->getPost('audience');
            $attributes = $this->getRequest()->getPost('attributes', []);
            $otherDetails = $this->getRequest()->getPost('product_details');
            $pageTitleTemplate = $this->getRequest()->getPost('wtai_generate_template_page_title');
            $productDescriptionTemplate = $this->getRequest()->getPost('wtai_generate_template_product_description');
            $shortProductDescriptionTemplate = $this->getRequest()
                ->getPost('wtai_generate_template_short_product_description');
            $descriptionMin = $this->getRequest()->getPost(
                'description_min',
                $this->helper->getDescriptionSettings('min')
            );
            $descriptionMax = $this->getRequest()->getPost(
                'description_max',
                $this->helper->getDescriptionSettings('max')
            );
            $excerptMin = $this->getRequest()->getPost('excerpt_min', $this->helper->getExcerptSettings('min'));
            $excerptMax = $this->getRequest()->getPost('excerpt_max', $this->helper->getExcerptSettings('max'));
            $filters = $this->getRequest()->getPost('filters', []);
            $voiceAndStyleMethod = $this->getRequest()->getPost('voice_and_style_method', 'manual');
            $useAiModel = $voiceAndStyleMethod === 'ai_model';
            $selectedAiModel = $this->getRequest()->getPost('wtai_selected_ai_model', '');

            $storeId = isset($filters['store_id']) ? $filters['store_id'] : Store::DEFAULT_STORE_ID;
            
            $mappingSettings = $this->helper->getMappingSettings();

            $country =  $this->scopeConfig->getValue(
                'general/country/default',
                ScopeInterface::SCOPE_STORE,
                $storeId
            );
            $language = $this->storeHelper->getFormattedLanguage($storeId);
            $ipAddress = $this->remoteAddress->getRemoteAddress();

            $rules = $this->settings->getSettings('rules');
            $maxOutputWords = $rules['maxOutputWords'] ?? '';
            $maxReferenceTextLength = $rules['maxReferenceTextLength'] ?? '';
            $additionalReferenceTextLength = $rules['additionalReferenceTextLength'] ?? '';
            $maxAttributes = $rules['maxAttributes'] ?? '';
            $maxAttributeValueLength = $rules['maxAttributeValueLength'] ?? '';

            $credits = $this->settings->getSettings('credits');
            $wordsPerCredit = $credits['wordsPerCredit'] ?? '';
            
            $maxInputChar = ((($maxOutputWords / $wordsPerCredit) - 1) * $additionalReferenceTextLength)
                + $maxReferenceTextLength;

            $texts = [];
            $collection = $this->filter->getCollection($this->collectionFactory
                    ->create()
                    ->addAttributeToSelect('*'))
                    ->setStoreId($storeId)
                    ->addMediaGalleryData();

            $frontendStoreId = $this->storeHelper->getFrontendStoreId($storeId);
            $isProductResearchDataSelected = false;
            $fetchImages = false;
            $withAltTextGeneration = false;
            foreach ($collection as $product) {
                $attributesData = [];
                $images = [];
                $productId = $product->getId();
                $productName = $this->outputHelper->productAttribute(
                    $product,
                    $product->getName(),
                    'name'
                );
               // $productAttributes = $this->getProductAttributes($product, $attributes);
                foreach ($attributes as $attribute) {
                    if (strtolower($attribute)
                        === ProductAttributes::PRODUCT_RESEARCH_DATA_ATTRIBUTE_CODE
                    ) {
                        $isProductResearchDataSelected = true;
                        continue;
                    }

                    /*if ($maxAttributes <= count($attributesData)) {
                        break;
                    }*/
                    
                    if (strtolower($attribute) === 'thumbnail') {
                        $fetchImages = true;
                    }
                }
 
                // fields to generate
                $fieldNames = [
                    'page_title' => Fields::PAGE_TITLE,
                    'page_description' => Fields::PAGE_DESCRIPTION,
                    'product_description' => Fields::PRODUCT_DESCRIPTION,
                    'short_product_description' => Fields::EXCERPT,
                    'open_graph' => Fields::OPEN_GRAPH
                ];

                $templatesUsed = [
                    'page_title' => $pageTitleTemplate,
                    'product_description' => $productDescriptionTemplate,
                    'short_product_description' => $shortProductDescriptionTemplate
                ];

                $fields = [];
                foreach ($fieldNames as $fieldName => $fieldConstant) {
                    if (in_array($fieldName, $selectedFields)) {
                        $field = [
                            "field" => $fieldConstant
                        ];

                        if ($fieldName == 'product_description') {
                            $field["minWords"] = $descriptionMin;
                            $field["maxWords"] = $descriptionMax;
                        } elseif ($fieldName == 'short_product_description') {
                            $field["minWords"] = $excerptMin;
                            $field["maxWords"] = $excerptMax;
                        }

                        if (isset($templatesUsed[$fieldName]) && $templatesUsed[$fieldName]) {
                            $field['templateId'] = $templatesUsed[$fieldName];
                        }
                        
                        $fields[] = $field;
                    }
                }

                $_product = $product;

                $textData = [
                    "name" => $productName,
                    "recordId" => $productId,
                    "sku" => $product->getSku(),
                    "fields" => $fields,
                    "url" => $_product->setStoreId($frontendStoreId)->getUrlInStore()
                ];

                if (in_array('product_description', $selectedFields)
                    || in_array('short_product_description', $selectedFields)
                ) {
                    $fetchImages = true;
                }

                $publishedContents = [
                    'product_description' => $this->fieldHelper->getAttributesValues($product, 'product_description'),
                    'short_product_description' => $this->fieldHelper->getAttributesValues(
                        $product,
                        'short_product_description'
                    )
                ];

                if (in_array('alt_text', $selectedFields)) {
                    $fetchImages = true;
                    $withAltTextGeneration  = true;
                }

                $autoOptimizeKeywords = filter_var(
                    $this->getRequest()->getPost('auto_optimize_keywords'),
                    FILTER_VALIDATE_BOOLEAN
                );
                $keywords = null;

                if (!empty($fields) || $withAltTextGeneration) {
                    $texts[] = $textData;
                }
            }

            $params = [
                "type" => "Product",
                "storeId" => (string) $storeId,
                "language" => $language,
                "countries" => [$country],
                "ipAddress" => $ipAddress,
                "texts" => $texts,
                "fetchImages" => $fetchImages,
                "withAltTextGeneration" => $withAltTextGeneration,
                "fetchRecordData" => [
                    "attributes" => $attributes
                ],
                "generationParameters" => [
                    "enableResearch" => $isProductResearchDataSelected
                ]
            ];

            if (filter_var($useAiModel, FILTER_VALIDATE_BOOLEAN)) {
                $params['generationParameters']['brandVoiceId'] = $selectedAiModel;
            }

            if (!$useAiModel) {
                if (in_array('custom', $tones)) {
                    $params['generationParameters']['customTone'] = $customTone;
                } else {
                    $params['generationParameters']['tones'] = $tones;
                }

                if ($style == 'custom') {
                    $params['generationParameters']['customStyle'] = $customStyle;
                } else {
                    $params['generationParameters']['style'] = $style;
                }

                if (!empty($audience)) {
                    $params['generationParameters']['audiences'] = $audience;
                }
            }

            $autoOptimizeKeywords = filter_var(
                $this->getRequest()->getPost('auto_optimize_keywords'),
                FILTER_VALIDATE_BOOLEAN
            );
            $keywordOpParams = $this->getKeywordOptimizationParams($country);
            if (!empty($keywordOpParams)) {
                $params['keywordOptimization'] = $keywordOpParams;
                $params['development'] = filter_var($this->helper->getKoDev(), FILTER_VALIDATE_BOOLEAN);
            }
            if ($this->helper->getForceQueueSeconds()) {
                $params['developmentQueueWaitTimeInSeconds'] = $this->helper->getForceQueueSeconds();
            }

            if ($otherDetails) {
                $params['specialInstructions'] = $otherDetails;
            }
            
            $singleRecordId = null;
            if (count($texts) === 1 && $autoOptimizeKeywords) {
                $singleRecordId = $texts[0]['recordId'];
            }

            if (count($texts) < 2) {
                $params['queue'] = true;
            }

            $params = json_encode($params, JSON_INVALID_UTF8_IGNORE);
            $apiResponse = $this->apiManager->generate($params);

            //$this->saveBulkRequest($apiResponse, $singleRecordId);

            foreach ($collection as $product) {
                $this->aiProductManager->saveDate($product->getId(), $storeId, 'generated');
                $this->aiProductManager->saveDate($product->getId(), $storeId, 'edited');
            }

            $result = [
                'success' => true,
                'form_key' => $this->formKey->getFormKey(),
                'params' => $params,
                'api_response' => $apiResponse
            ];
        } catch (\WriteTextAI\WriteTextAI\Exception\UnauthorizedException $e) {
            $result = [
                'success' => false,
                'unauthorized' => true,
                'login_url' => $this->urlBuilder->getUrl('wtai/setup/index'),
                'message' => $e->getMessage()
            ];
        } catch (\Exception $e) {
            $errorMessage = $e->getMessage();

            if (!$errorMessage) {
                $errorMessage = __(
                    'A system error has occurred. Please try again. If the issue persists,'
                    . ' please contact our support team at support@writetext.ai.'
                );
            }
            
            $result = [
                'success' => false,
                'message' => $errorMessage,
                'params' => $params ?? []
            ];
        }

        $response->setData($result);

        return $response;
    }

    /**
     * Get keywords
     *
     * @param int $storeId
     * @param int $productId
     * @param string $productName
     *
     * @return array
     */
    protected function getKeywords($storeId, $productId, $productName)
    {
        $optimizationData = $this->keywords->getOptimization(
            $storeId,
            $productId,
            'Product'
        );

        $keywords = [];
        if (!empty($optimizationData)) {
            $optimizingKeywords = $optimizationData['allOptimizingKeywords'] ?? [];
            $manualKeywords = $optimizationData['manualKeywords'] ?? [];
            $keywords = !empty($optimizingKeywords) ? $optimizingKeywords : $manualKeywords;
        }

        return $keywords;
    }

    /**
     * Get keyword optimization params
     *
     * @param string $country
     * @return array
     */
    protected function getKeywordOptimizationParams($country)
    {
        $autoOptimizeKeywords = filter_var(
            $this->getRequest()->getPost('auto_optimize_keywords'),
            FILTER_VALIDATE_BOOLEAN
        );
        if (!$autoOptimizeKeywords) {
            return [];
        }

        $searchIntent = $this->getRequest()->getPost('search_intent');
        $clusterCount = $this->getRequest()->getPost('cluster_count');
        $action = $this->getRequest()->getPost('automatic_text_optimization');
        switch ($action) {
            case AutomaticTextOptimization::AUTO_REWRITE_AND_QUEUE:
                $action = 'AutomaticRewrite';
                break;
            case AutomaticTextOptimization::FLAG:
                $action = 'FlagForRewrite';
                break;
            case AutomaticTextOptimization::AUTO_REWRITE_AND_TRANSFER:
                $action = 'FullAutomation';
                break;
        }

        $triggers = $this->keywords->prepareDefaultTriggerSettingsParameters();
        foreach ($triggers as $key => $trigger) {
            $triggers[$key]['action'] = $action;
        }

        $params = [
            "intents" => explode(', ', $searchIntent),
            "countryCode" => $country,
            "clusters" => $clusterCount,
            "triggers" => $triggers
        ];
        
        if (filter_var($this->helper->getKoDev(), FILTER_VALIDATE_BOOLEAN)) {
            $params["developmentSettings"] = [
                "waitTimePerStep" => 1000,
                "maxSteps" => 9,
                "failAfterFirstStep" => filter_var($this->helper->getForceFailed(), FILTER_VALIDATE_BOOLEAN)
            ];
        }

        return $params;
    }

    /**
     * Get alt text params
     *
     * @param \Magento\Catalog\Model\Product $product
     * @param array $galleryImages
     * @param array $failedImages
     * @return array
     */
    protected function getAltTextParams($product, $galleryImages, $failedImages = [])
    {
        $uploadedImages = $this->getRequest()->getPost('uploaded_images', []);
        $altTexts = [];

        $images = $product->getMediaGalleryImages()->setOrder('position', 'ASC')->getItems();
        /**
         * Need to manually sort as setOrder is not getting the right position order
         */
        usort($images, function ($a, $b) {
            return $a->getPosition() <=> $b->getPosition();
        });
        $imageLimit = 10;
        $imageCount = 0;

        $featuredImageData = [];
        $featuredImageId = null;
        $isFeaturedImageIncluded = false;
        foreach ($galleryImages as $image) {
            if (isset($image['is_featured']) && $image['is_featured']) {
                $featuredImageId = $image['id'];
                $featuredImageData = [
                    'imageId' => $image['id']
                ];
            }
        }

        foreach ($images as $image) {
            if ($image->getDisabled()) {
                continue;
            }
            
            if (in_array($image->getId(), $failedImages)) {
                $imageCount++;
                continue;
            }

            if ($imageCount >= $imageLimit) {
                break;
            }

            $imageFile = $image->getFile();
            $imageFilePreview = $this->imageHelper->init(
                $product,
                'product_listing_thumbnail_preview'
            )->setImageFile($imageFile);
            $url = $imageFilePreview->getUrl();
            if ($url == $imageFilePreview->getDefaultPlaceholderUrl()) {
                continue;
            }

            if (in_array($image->getId(), $uploadedImages)) {
                if ($image->getId() === $featuredImageId) {
                    $isFeaturedImageIncluded = true;
                    continue;
                }

                $altTexts[] = [
                    'imageId' => $image->getId()
                ];
            }
                
            $imageCount++;
        }
        
        /** Add featured image to the beginning of the array */
        if ($isFeaturedImageIncluded) {
            array_unshift($altTexts, $featuredImageData);
        }

        return $altTexts;
    }

    /**
     * Save bulk request
     *
     * @param array $apiResponse
     * @param string $singleRecordId
     * @return void
     */
    protected function saveBulkRequest($apiResponse, $singleRecordId = null)
    {
        $user = $this->apiSession->getCurrentUser();

        if ($apiResponse['requestId']) {
            $this->bulkGenerateRequestsManager->setBulkRequest(
                $apiResponse['requestId'],
                $user->getEmail(),
                $apiResponse['type'],
                $apiResponse['storeId'],
                $singleRecordId
            );
        }
        $this->BulkTransferRequestsManager->delete($user->getEmail());
        $this->fullAutomationRequestsManager->deleteByUser($user->getEmail());
        $this->bulkKeywordAnalysisRequestsManager->deleteByUser($user->getEmail());
    }

    // 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 image URLs for a product
     *
     * @param array $gallery
     * @return array
     */
    public function getImageUrls($gallery)
    {
        try {
            $uploadedImages = $this->getRequest()->getPost('uploaded_images', []);
            //$product = $this->productRepository->getById($productId, false, $storeId);
            //$language = $this->storeHelper->getFormattedLanguage($storeId);

            $imageUrls = [];
            $mainImage = '';
            foreach ($gallery as $image) {
                if (!in_array($image['id'], $uploadedImages)) {
                    continue;
                }

                if ($image['is_featured']) {
                    $mainImage = [
                        "url" => $image['noncached_url'],
                        "imageId" => $image['id']
                    ];
                    continue;
                }

                $imageUrls[] = [
                    "url" => $image['noncached_url'],
                    "imageId" => $image['id']
                ];
            }

            // Get main product image
            // $mainImage = $this->magentoImageHelper->init($product, 'product_page_image_large')
            //     ->setImageFile($product->getImage())
            //     ->getUrl();
            
            return [
                'main_image' => $mainImage,
                'gallery_images' => $imageUrls
            ];
        } catch (\Exception $e) {
            return [
                'main_image' => '',
                'gallery_images' => []
            ];
        }
    }
}
