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

namespace WriteTextAI\WriteTextAI\Controller\Adminhtml\CategoriesGrid;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Catalog\Helper\Output as OutputHelper;
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory as CategoryCollectionFactory;
use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\HTTP\PhpEnvironment\RemoteAddress;
use Magento\Store\Model\ScopeInterface;
use Magento\Store\Model\Store;
use Magento\Backend\Model\UrlInterface;
use WriteTextAI\WriteTextAI\Helper\Data;
use WriteTextAI\WriteTextAI\Helper\Store as StoreHelper;
use WriteTextAI\WriteTextAI\Model\ApiManager;
use WriteTextAI\WriteTextAI\Model\Api\Keywords;
use WriteTextAI\WriteTextAI\Model\BulkKeywordAnalysisRequestsManager;
use WriteTextAI\WriteTextAI\Model\Config\Source\AutomaticTextOptimization;
use WriteTextAI\WriteTextAI\Ui\Component\MassAction\JsonFilter;
use WriteTextAI\WriteTextAI\ViewModel\Premium;

class MassKeywordAnalysis extends Action implements HttpPostActionInterface
{
    public const ADMIN_RESOURCE = 'WriteTextAI_WriteTextAI::keyword_analysis';

    /**
     * @var JsonFilter
     */
    private $filter;

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

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

    /**
     * @var Premium
     */
    private $premium;

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

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

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

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

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

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

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

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

        /**
         * Constructor
         *
         * @param Context $context
         * @param JsonFilter $filter
         * @param CategoryCollectionFactory $collectionFactory
         * @param UrlInterface $urlBuilder
         * @param Premium $premium
         * @param ApiManager $apiManager
         * @param Keywords $keywords
         * @param StoreHelper $storeHelper
         * @param RemoteAddress $remoteAddress
         * @param ScopeConfigInterface $scopeConfig
         * @param OutputHelper $outputHelper
         * @param Data $helper
         * @param BulkKeywordAnalysisRequestsManager $bulkKeywordAnalysisRequestsManager
         */
    public function __construct(
        Context $context,
        JsonFilter $filter,
        CategoryCollectionFactory $collectionFactory,
        UrlInterface $urlBuilder,
        Premium $premium,
        ApiManager $apiManager,
        Keywords $keywords,
        StoreHelper $storeHelper,
        RemoteAddress $remoteAddress,
        ScopeConfigInterface $scopeConfig,
        OutputHelper $outputHelper,
        Data $helper,
        BulkKeywordAnalysisRequestsManager $bulkKeywordAnalysisRequestsManager
    ) {
        parent::__construct($context);
        $this->filter = $filter;
        $this->collectionFactory = $collectionFactory;
        $this->urlBuilder = $urlBuilder;
        $this->premium = $premium;
        $this->apiManager = $apiManager;
        $this->keywords = $keywords;
        $this->storeHelper = $storeHelper;
        $this->remoteAddress = $remoteAddress;
        $this->scopeConfig = $scopeConfig;
        $this->outputHelper = $outputHelper;
        $this->helper = $helper;
        $this->bulkKeywordAnalysisRequestsManager = $bulkKeywordAnalysisRequestsManager;
    }

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

        if (!$this->premium->getHasProAccess()) {
            $response->setData([
                'success' => false,
                'reload' => true,
                'message' => __('Premium is required to do this action.')
            ]);

            return $response;
        }

        try {
            $filters = (array) $this->getRequest()->getPost('filters', []);
            $storeId = isset($filters['store_id']) ? (int) $filters['store_id'] : Store::DEFAULT_STORE_ID;
            $language = $this->storeHelper->getFormattedLanguage($storeId);
            $ipAddress = $this->remoteAddress->getRemoteAddress();
            $country = (string) $this->scopeConfig->getValue(
                'general/country/default',
                ScopeInterface::SCOPE_STORE,
                $storeId
            );

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

            $texts = [];
            foreach ($collection as $category) {
                $texts[] = [
                    'name' => (string) $category->getName(),
                    'recordId' => (string) $category->getId(),
                    'url' => (string) $category->getUrl()
                ];
            }

            $params = [
                'type' => 'Category',
                'storeId' => (string) $storeId,
                'language' => $language,
                'countries' => [$country],
                'ipAddress' => $ipAddress,
                'texts' => $texts,
                'keywordOptimization' => $this->getKeywordOptimizationParams($country),
                'development' => filter_var($this->helper->getKoDev(), FILTER_VALIDATE_BOOLEAN),
                'fetchImages' => false,
                "fetchRecordData" => [
                    'hasProductNames' => true
                ],
            ];

            if ($this->helper->getForceQueueSeconds()) {
                $params['developmentQueueWaitTimeInSeconds'] = $this->helper->getForceQueueSeconds();
            }

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

            if ($apiResponse['requestId'] === null) {
                $result = [
                    'success' => false,
                    'unselectAll' => true,
                    'message' => __('The selected category/categories already have completed keyword analysis.')
                ];
            } else {
                $records = array_column($texts, 'recordId');
                $user = $this->_auth->getUser();
                $userEmail = $user ? (string) $user->getEmail() : '';
                $this->bulkKeywordAnalysisRequestsManager->setBulkRequest(
                    $apiResponse['requestId'],
                    $userEmail,
                    'Category',
                    $storeId,
                    $records
                );
                $result = [
                    'success' => true,
                    'params' => $jsonParams,
                    '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) {
            $message = $e->getMessage();
            if (!$message) {
                $message = __(
                    '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' => $message
            ];
        }

        $response->setData($result);
        return $response;
    }

    /**
     * Get keyword optimization parameters
     *
     * @param string $country
     * @return array
     */
    protected function getKeywordOptimizationParams($country)
    {
        $searchIntent = (string) $this->getRequest()->getPost('search_intent');
        $clusterCount = $this->getRequest()->getPost('cluster_count');
        $autoTextOptimization = $this->getRequest()->getPost('automatic_text_optimization');
        $triggerActionLow = $this->getRequest()->getPost('trigger_action_low');
        $triggerActionLowMid = $this->getRequest()->getPost('trigger_action_low_mid');
        $triggerActionMid = $this->getRequest()->getPost('trigger_action_mid');
        $triggerActionMidHigh = $this->getRequest()->getPost('trigger_action_mid_high');
        $triggerActionNPositionLow = $this->getRequest()->getPost('trigger_action_n_position_low');
        $triggerActionNPositionLowMid = $this->getRequest()->getPost('trigger_action_n_position_low_mid');
        $triggerActionNPositionMid = $this->getRequest()->getPost('trigger_action_n_position_mid');
        $triggerActionNPositionMidHigh = $this->getRequest()->getPost('trigger_action_n_position_mid_high');
        $triggerActionNDaysLow = $this->getRequest()->getPost('trigger_action_n_days_low');
        $triggerActionNDaysLowMid = $this->getRequest()->getPost('trigger_action_n_days_low_mid');
        $triggerActionNDaysMid = $this->getRequest()->getPost('trigger_action_n_days_mid');
        $triggerActionNDaysMidHigh = $this->getRequest()->getPost('trigger_action_n_days_mid_high');
        $products = (array) $this->getRequest()->getPost('product_texts', []);

        $action = $this->helper->getKeywordOptimizationSettings(
            'automatic_text_optimization'
        ) ?? AutomaticTextOptimization::FLAG;

        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;
        }

        $triggerSettings = [
            'pipeline_keyword' => [
                'low' => [
                    'trigger_action' => $triggerActionLow,
                    'trigger_action_n_position' => $triggerActionNPositionLow,
                    'trigger_action_n_days' => $triggerActionNDaysLow
                ],
                'low_mid' => [
                    'trigger_action' => $triggerActionLowMid,
                    'trigger_action_n_position' => $triggerActionNPositionLowMid,
                    'trigger_action_n_days' => $triggerActionNDaysLowMid
                ],
                'mid' => [
                    'trigger_action' => $triggerActionMid,
                    'trigger_action_n_position' => $triggerActionNPositionMid,
                    'trigger_action_n_days' => $triggerActionNDaysMid
                ],
                'mid_high' => [
                    'trigger_action' => $triggerActionMidHigh,
                    'trigger_action_n_position' => $triggerActionNPositionMidHigh,
                    'trigger_action_n_days' => $triggerActionNDaysMidHigh
                ]
            ],
            'automatic_text_optimization' => $autoTextOptimization,
            'products' => implode(',', $products)
        ];

        $triggers = $this->keywords->prepareCustomTriggerSettingsParameters(
            'Category',
            $triggerSettings
        );

        return [
            'intents' => explode(', ', $searchIntent),
            'countryCode' => $country,
            'clusters' => $clusterCount,
            'triggers' => $triggers,
            'doKeywordOptimizationOnly' => true
        ];
    }
}
