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

declare(strict_types=1);

namespace WriteTextAI\WriteTextAI\Controller\Adminhtml\Grid;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Controller\ResultFactory;
use WriteTextAI\WriteTextAI\Model\UserFieldsSelectedManager;
use WriteTextAI\WriteTextAI\Helper\Data;
use WriteTextAI\WriteTextAI\Model\Config\Source\AutomaticTextOptimization;
use WriteTextAI\WriteTextAI\Model\GenerateOptionsManager;

class Restore extends Action
{
    /**
     * @var Data
     */
    protected $helper;

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

    /**
     * @var UserFieldsSelectedManager
     */
    protected $userFieldsSelectedManager;

    /**
     * Constructor
     *
     * @param Context $context
     * @param Data $helper
     * @param GenerateOptionsManager $generateOptionsManager
     * @param UserFieldsSelectedManager $userFieldsSelectedManager
     */
    public function __construct(
        Context $context,
        Data $helper,
        GenerateOptionsManager $generateOptionsManager,
        UserFieldsSelectedManager $userFieldsSelectedManager
    ) {
        $this->helper = $helper;
        $this->generateOptionsManager = $generateOptionsManager;
        $this->userFieldsSelectedManager = $userFieldsSelectedManager;
        parent::__construct($context);
    }

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

        try {
            $isKoRequest = filter_var($this->getRequest()->getParam('from_ko'), FILTER_VALIDATE_BOOLEAN);
            $entityType = (string) $this->getRequest()->getParam('entity_type', 'product');
            $entityType = $entityType ?: 'product';

            if ($isKoRequest) {
                $this->resetKeywordOptimizationPreferences($entityType);
                $data = $this->getKeywordOptimizationRestoreData($entityType);
            } else {
                $this->userFieldsSelectedManager->deleteGridSettings('product');
                $this->userFieldsSelectedManager->deleteSpecificSettings('global', 'tones', 'grid');
                $this->userFieldsSelectedManager->deleteSpecificSettings('global', 'style', 'grid');
                $this->userFieldsSelectedManager->deleteSpecificSettings('global', 'audiences', 'grid');
                $this->userFieldsSelectedManager->deleteSpecificSettings('global', 'custom_tone', 'grid');
                $this->userFieldsSelectedManager->deleteSpecificSettings('global', 'custom_style', 'grid');
                $this->userFieldsSelectedManager->deleteSpecificSettings('product', 'search_intent', 'grid');
                $this->userFieldsSelectedManager->deleteSpecificSettings('product', 'search_intent', '');
                $data = [
                    'tones' => $this->getTonesFromGlobalSettings(),
                    'styles' => $this->getStylesFromGlobalSettings(),
                    'custom_tone' => $this->getCustomTones(),
                    'custom_style' => $this->getCustomStyles(),
                    'audience' => $this->getAudienceFromGlobalSettings(),
                    'attributes' => $this->getAttributesSelectedFromGlobalSettings(),
                    'desc_min' => $this->helper->getDescriptionSettings('min'),
                    'desc_max' => $this->helper->getDescriptionSettings('max'),
                    'exc_min' => $this->helper->getExcerptSettings('min'),
                    'exc_max' => $this->helper->getExcerptSettings('max'),
                    'special_instructions' => '',
                    'use_keywords' => true,
                    'fields' => $this->userFieldsSelectedManager->getDefaultSelectedFields(),
                    'auto_optimize_keywords' => false,
                    'automatic_text_optimization' => $this->getKeywordOptimizationSettings(
                        'automatic_text_optimization'
                    ) ?? AutomaticTextOptimization::FLAG,
                    'search_intent' => explode(',', $this->helper->getKeywordOptimizationSettings('search_intent')),
                    'cluster_count' => $this->getKeywordOptimizationSettings('cluster_based_pipelines_count'),
                    'cluster_count_category' => $this->getKeywordOptimizationSettings(
                        'cluster_based_pipelines_count_category'
                    ),
                    'product_fields' => $this->getGlobalProductFields(),
                    'triggerActions' => $this->getTriggerActionsFromGlobalSettings()
                ];
            }
            
            $result = [
                'success' => true,
                'data' => $data
            ];
        } 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 tones
     *
     * @return array
     */
    public function getTones()
    {
        return $this->generateOptionsManager->getOptions('tones');
    }

    /**
     * Get tones from global settings
     *
     * @return array
     */
    private function getTonesFromGlobalSettings()
    {
        $tones = $this->getTones();

        if (!is_array($tones)) {
            return [];
        }

        $tonesSelected = array_filter($tones, function ($tone) {
            return isset($tone['default']) && $tone['default'] === true;
        });

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

        $tonesSelected = array_column($tonesSelected, 'id');

        return $tonesSelected;
    }
    /**
     * Get custom tones
     *
     * @return string
     */
    public function getCustomTones()
    {
        return $this->generateOptionsManager->getCustomTones();
    }

     /**
      * Get custom tones from global settings
      *
      * @return string
      */
    private function getCustomTonesFromGlobalSettings()
    {
        $customTones = $this->getCustomTones();

        if (empty($customTones)) {
            return '';
        }

        return $customTones;
    }
    /**
     * Get styles
     *
     * @return array
     */
    public function getStyles()
    {
        return $this->generateOptionsManager->getOptions('styles');
    }
    /**
     * Get custom styles
     *
     * @return array
     */
    public function getCustomStyles()
    {
        return $this->generateOptionsManager->getCustomStyles();
    }
   /**
    * Get custom tones from global settings
    *
    * @return string
    */
    private function getCustomStylesFromGlobalSettings()
    {
        $customStyles = $this->getCustomStyles();

        if (empty($customStyles)) {
            return '';
        }

        return $customStyles;
    }
    /**
     * Get styles from global settings
     *
     * @return string
     */
    private function getStylesFromGlobalSettings()
    {
        $styles = $this->getStyles();

        if (!is_array($styles)) {
            return [];
        }

        $stylesSelected = array_filter($styles, function ($style) {
            return isset($style['default']) && $style['default'] === true;
        });

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

        $stylesSelected = array_column($stylesSelected, 'id');

        return array_shift($stylesSelected);
    }

    /**
     * Get audience
     *
     * @return array
     */
    public function getAudience()
    {
        return $this->generateOptionsManager->getOptions('audience');
    }

    /**
     * Get audience selected from global settings
     *
     * @return array
     */
    private function getAudienceFromGlobalSettings()
    {
        $audience = $this->getAudience();

        if (!is_array($audience)) {
            return [];
        }

        $audienceSelected = array_filter($audience, function ($audience) {
            return isset($audience['default']) && $audience['default'] === true;
        });

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

        $audienceSelected = array_column($audienceSelected, 'id');

        return $audienceSelected;
    }

    /**
     * Get attributes
     *
     * @return array
     */
    public function getAttributes()
    {
        return $this->generateOptionsManager->getOptions('attributes');
    }

    /**
     * Get attributes selected from global settings
     *
     * @return array
     */
    private function getAttributesSelectedFromGlobalSettings()
    {
        $attributes = $this->getAttributes();

        $defaultAttributes = array_filter($attributes, function ($attribute) {
            return $attribute['default'];
        });
        $attributesSelected = array_map(function ($attribute) {
            return $attribute['value'];
        }, $defaultAttributes);

        return array_values($attributesSelected);
    }

    /**
     * Get global settings for keyword optimization
     *
     * @param string $path
     * @return string
     */
    public function getKeywordOptimizationSettings($path)
    {
        return $this->helper->getKeywordOptimizationSettings($path);
    }

    /**
     * Get global keyword pipeline trigger actions
     *
     * @return array
     */
    private function getTriggerActionsFromGlobalSettings(): array
    {
        return [
            'low' => $this->getKeywordOptimizationSettings('pipeline_keyword/low'),
            'low_mid' => $this->getKeywordOptimizationSettings('pipeline_keyword/low_mid'),
            'mid' => $this->getKeywordOptimizationSettings('pipeline_keyword/mid'),
            'mid_high' => $this->getKeywordOptimizationSettings('pipeline_keyword/mid_high')
        ];
    }

    /**
     * Get global product fields
     *
     * @return array
     */
    public function getGlobalProductFields()
    {
        $selected = $this->helper->getKeywordOptimizationSettings('products');
        if ($selected) {
            return explode(',', $selected);
        }

        return [];
    }

    /**
     * Reset keyword-optimization related user preferences only.
     *
     * @param string $entityType
     * @return void
     */
    private function resetKeywordOptimizationPreferences(string $entityType): void
    {
        $this->userFieldsSelectedManager->deleteSpecificSettings($entityType, 'search_intent', 'grid');
        $this->userFieldsSelectedManager->deleteSpecificSettings($entityType, 'cluster_count', 'grid');
        $this->userFieldsSelectedManager->deleteSpecificSettings($entityType, 'cluster_count_category', 'grid');
        $this->userFieldsSelectedManager->deleteSpecificSettings($entityType, 'automatic_text_optimization', 'grid');
        $this->userFieldsSelectedManager->deleteSpecificSettings($entityType, 'auto_optimize_keywords', 'grid');
        $this->userFieldsSelectedManager->deleteSpecificSettings($entityType, 'auto_generate_after_ko', 'grid');
    }

    /**
     * Get KO restore payload.
     *
     * This is consumed by the KO (keyword-analysis) modal.
     *
     * @param string $entityType
     * @return array
     */
    private function getKeywordOptimizationRestoreData(string $entityType = 'product'): array
    {
        $searchIntent = (string) $this->helper->getKeywordOptimizationSettings('search_intent');
        $searchIntent = $searchIntent ? explode(',', $searchIntent) : [];

        $clusterCountConfigKey = $entityType === 'category'
            ? 'cluster_based_pipelines_count_category'
            : 'cluster_based_pipelines_count';

        return [
            'automatic_text_optimization' => $this->getKeywordOptimizationSettings(
                'automatic_text_optimization'
            ) ?? AutomaticTextOptimization::FLAG,
            'search_intent' => $searchIntent,
            'cluster_count' => $this->getKeywordOptimizationSettings($clusterCountConfigKey),
            'product_fields' => $this->getGlobalProductFields(),
            'triggerActions' => $this->getTriggerActionsFromGlobalSettings()
        ];
    }
}
