<?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\Controller\ResultFactory;
use Magento\Ui\Component\MassAction\Filter;
use WriteTextAI\WriteTextAI\Ui\Component\MassAction\JsonFilter;
use Magento\Backend\Model\UrlInterface;
use WriteTextAI\WriteTextAI\ViewModel\Premium;
use Magento\Store\Model\Store;
use WriteTextAI\WriteTextAI\Model\ApiManager;
use WriteTextAI\WriteTextAI\Model\Api\Keywords;
use Magento\Framework\HTTP\PhpEnvironment\RemoteAddress;
use WriteTextAI\WriteTextAI\Helper\Store as StoreHelper;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\ScopeInterface;
use WriteTextAI\WriteTextAI\Model\Config\Source\AutomaticTextOptimization;
use Magento\Catalog\Helper\Output as OutputHelper;
use Magento\Catalog\Helper\Image as ImageHelper;
use WriteTextAI\WriteTextAI\Helper\Image as WTAImageHelper;
use WriteTextAI\WriteTextAI\Model\BulkKeywordAnalysisRequestsManager;
use WriteTextAI\WriteTextAI\Model\BulkTransferRequestsManager;
use WriteTextAI\WriteTextAI\Model\BulkGenerateRequestsManager;
use WriteTextAI\WriteTextAI\Model\FullAutomationRequestsManager;
use WriteTextAI\WriteTextAI\Model\Api\Session as ApiSession;
use WriteTextAI\WriteTextAI\Helper\Data;

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

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

    /**
     * @var CollectionFactory
     */
    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 ImageHelper
     */
    protected $imageHelper;

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

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

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

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

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

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

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

    /**
     * Constructor
     *
     * @param Context $context
     * @param JsonFilter $filter
     * @param CollectionFactory $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 ImageHelper $imageHelper
     * @param WTAImageHelper $wtaImageHelper
     * @param BulkKeywordAnalysisRequestsManager $bulkKeywordAnalysisRequestsManager
     * @param BulkTransferRequestsManager $bulkTransferRequestsManager
     * @param BulkGenerateRequestsManager $bulkGenerateRequestsManager
     * @param FullAutomationRequestsManager $fullAutomationRequestsManager
     * @param ApiSession $apiSession
     * @param Data $helper
     */
    public function __construct(
        Context $context,
        JsonFilter $filter,
        CollectionFactory $collectionFactory,
        UrlInterface $urlBuilder,
        Premium $premium,
        ApiManager $apiManager,
        Keywords $keywords,
        StoreHelper $storeHelper,
        RemoteAddress $remoteAddress,
        ScopeConfigInterface $scopeConfig,
        OutputHelper $outputHelper,
        ImageHelper $imageHelper,
        WTAImageHelper $wtaImageHelper,
        BulkKeywordAnalysisRequestsManager $bulkKeywordAnalysisRequestsManager,
        BulkTransferRequestsManager $bulkTransferRequestsManager,
        BulkGenerateRequestsManager $bulkGenerateRequestsManager,
        FullAutomationRequestsManager $fullAutomationRequestsManager,
        ApiSession $apiSession,
        Data $helper
    ) {
        $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->imageHelper = $imageHelper;
        $this->wtaImageHelper = $wtaImageHelper;
        $this->bulkKeywordAnalysisRequestsManager = $bulkKeywordAnalysisRequestsManager;
        $this->bulkTransferRequestsManager = $bulkTransferRequestsManager;
        $this->bulkGenerateRequestsManager = $bulkGenerateRequestsManager;
        $this->fullAutomationRequestsManager = $fullAutomationRequestsManager;
        $this->apiSession = $apiSession;
        $this->helper = $helper;
        parent::__construct($context);
    }

    /**
     * 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 = $this->getRequest()->getPost('filters', []);
            $storeId = isset($filters['store_id']) ? $filters['store_id'] : Store::DEFAULT_STORE_ID;
            $frontendStoreId = $this->storeHelper->getFrontendStoreId($storeId);
            $language = $this->storeHelper->getFormattedLanguage($storeId);
            $ipAddress = $this->remoteAddress->getRemoteAddress();
            $country =  $this->scopeConfig->getValue(
                'general/country/default',
                ScopeInterface::SCOPE_STORE,
                $storeId
            );
            $collection = $this->filter->getCollection($this->collectionFactory
                    ->create()
                    ->addAttributeToSelect('*'))
                    ->setStoreId($storeId)
                    ->addMediaGalleryData();

            $texts = [];
            foreach ($collection as $product) {
                $_product = $product;
                $textData = [
                    "name" => $this->outputHelper->productAttribute(
                        $product,
                        $product->getName(),
                        'name'
                    ),
                    "recordId" => $product->getId(),
                    "url" => $_product->setStoreId($frontendStoreId)->getUrlInStore()
                ];

                // $images = $this->getImages($product, $storeId, $ipAddress, $language);
                // if (!empty($images)) {
                //     $textData["images"] = $images;
                // }

                $texts[] = $textData;
            }
            $singleRecordId = null;
            if (count($texts) === 1) {
                $singleRecordId = $texts[0]['recordId'];
            }
            $params = [
                "type" => "Product",
                "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' => true,
            ];
            if ($this->helper->getForceQueueSeconds()) {
                $params['developmentQueueWaitTimeInSeconds'] = $this->helper->getForceQueueSeconds();
            }

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

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

            if ($apiResponse['requestId'] === null) {
                $result = [
                    'success' => false,
                    'message' => __('The selected product/s already have completed keyword analysis.')
                ];
            } else {
                $result = [
                    'success' => true,
                    '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) {
            $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 params
     *
     * @param string $country
     * @return array
     */
    protected function getKeywordOptimizationParams($country)
    {
        $searchIntent = $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 = $this->getRequest()->getPost('product_texts');
        
        $action = $this->helper->getKeywordOptimizationSettings(
            'automatic_text_optimization'
        ) ?? AutomaticTextOptimization::FLAG;

        $actionOriginal = $action;

        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(
            'Product',
            $triggerSettings
        );
        // foreach ($triggers as $key => $trigger) {
        //     $triggers[$key]['action'] = $action;
        // }

        $params = [
            "intents" => explode(', ', $searchIntent),
            "countryCode" => $country,
            "clusters" => $clusterCount,
            "triggers" => $triggers,
            "doKeywordOptimizationOnly" => true
        ];
        
        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;
    }

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

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

    /**
     * Get images
     *
     * @param Product $product
     * @param int $storeId
     * @param string $ipAddress
     * @param string $language
     *
     * @return array
     */
    protected function getImages($product, $storeId, $ipAddress, $language)
    {
        $images = [];

        $imageId = $this->wtaImageHelper->getImageValue($product);
        $uploadedImages = $this->getRequest()->getPost('uploaded_images', []);

        if (in_array($imageId, $uploadedImages)) {
            $images[] = $imageId;
        }

        return $images;
    }
}
