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

declare(strict_types=1);

namespace WriteTextAI\WriteTextAI\Block\Adminhtml\Setup\Index;

use WriteTextAI\WriteTextAI\Block\Adminhtml\Setup\Index;
use Magento\Backend\Block\Template\Context;
use WriteTextAI\WriteTextAI\Helper\Data;
use WriteTextAI\WriteTextAI\Model\GenerateOptionsManager;
use WriteTextAI\WriteTextAI\Model\ApiManager;
use WriteTextAI\WriteTextAI\Model\SettingManager;
use WriteTextAI\WriteTextAI\Helper\Categories\Fields as CategoryFields;
use WriteTextAI\WriteTextAI\Model\Config\Source\CategoryTexts;
use WriteTextAI\WriteTextAI\Model\Config\Source\ProductTexts;
use WriteTextAI\WriteTextAI\Model\Config\Source\TriggerActions;
use WriteTextAI\WriteTextAI\Model\Config\Source\AutomaticTextOptimization;
use WriteTextAI\WriteTextAI\Model\Config\Source\DefaultValues\CategoryTexts as DefaultCategoryTexts;
use WriteTextAI\WriteTextAI\Model\Config\Source\DefaultValues\ProductTexts as DefaultProductTexts;
use WriteTextAI\WriteTextAI\ViewModel\Premium;
use WriteTextAI\WriteTextAI\Model\Config\Source\PublishedAs;
use WriteTextAI\WriteTextAI\Model\Config\Source\AutoTransferSchedule;
use WriteTextAI\WriteTextAI\Helper\CronStatus;
use Magento\Framework\Stdlib\DateTime\DateTime;
use WriteTextAI\WriteTextAI\Model\Api\CurlBuilder;

class Keywords extends Index
{
    /**
     * @var CategoryTexts
     */
    protected $categoryTexts;

    /**
     * @var ProductTexts
     */
    protected $productTexts;

    /**
     * @var TriggerActions
     */
    protected $triggerActions;

    /**
     * @var DefaultCategoryTexts
     */
    protected $defaultCategoryTexts;

    /**
     * @var DefaultProductTexts
     */
    protected $defaultProductTexts;

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

    /**
     * @var PublishedAs
     */
    protected $publishedAs;

    /**
     * @var AutoTransferSchedule
     */
    protected $autoTransferSchedule;

    /**
     * @var CronStatus
     */
    protected $cronStatus;

    /**
     * @var DateTime
     */
    protected $dateTime;

    /**
     * @var CurlBuilder
     */
    protected $curlBuilder;

    /**
     * Constructor
     *
     * @param \Magento\Backend\Block\Template\Context $context
     * @param \WriteTextAI\WriteTextAI\Helper\Data $helper
     * @param \WriteTextAI\WriteTextAI\Model\GenerateOptionsManager $generateOptionsManager
     * @param \WriteTextAI\WriteTextAI\Model\ApiManager $apiManager
     * @param \WriteTextAI\WriteTextAI\Model\SettingManager $settingManager
     * @param \WriteTextAI\WriteTextAI\Helper\Categories\Fields $categoryFields
     * @param \WriteTextAI\WriteTextAI\Model\Config\Source\CategoryTexts $categoryTexts
     * @param \WriteTextAI\WriteTextAI\Model\Config\Source\ProductTexts $productTexts
     * @param \WriteTextAI\WriteTextAI\Model\Config\Source\TriggerActions $triggerActions
     * @param \WriteTextAI\WriteTextAI\Model\Config\Source\DefaultValues\CategoryTexts $defaultCategoryTexts
     * @param \WriteTextAI\WriteTextAI\Model\Config\Source\DefaultValues\ProductTexts $defaultProductTexts
     * @param \WriteTextAI\WriteTextAI\ViewModel\Premium $premium
     * @param \WriteTextAI\WriteTextAI\Model\Config\Source\PublishedAs $publishedAs
     * @param \WriteTextAI\WriteTextAI\Model\Config\Source\AutoTransferSchedule $autoTransferSchedule
     * @param \WriteTextAI\WriteTextAI\Helper\CronStatus $cronStatus
     * @param \Magento\Framework\Stdlib\DateTime\DateTime $dateTime
     * @param \WriteTextAI\WriteTextAI\Model\Api\CurlBuilder $curlBuilder
     * @param array $data
     */
    public function __construct(
        Context $context,
        Data $helper,
        GenerateOptionsManager $generateOptionsManager,
        ApiManager $apiManager,
        SettingManager $settingManager,
        CategoryFields $categoryFields,
        CategoryTexts $categoryTexts,
        ProductTexts $productTexts,
        TriggerActions $triggerActions,
        DefaultCategoryTexts $defaultCategoryTexts,
        DefaultProductTexts $defaultProductTexts,
        Premium $premium,
        PublishedAs $publishedAs,
        AutoTransferSchedule $autoTransferSchedule,
        CronStatus $cronStatus,
        DateTime $dateTime,
        CurlBuilder $curlBuilder,
        array $data = []
    ) {
        $this->categoryTexts = $categoryTexts;
        $this->productTexts = $productTexts;
        $this->triggerActions = $triggerActions;
        $this->defaultCategoryTexts = $defaultCategoryTexts;
        $this->defaultProductTexts = $defaultProductTexts;
        $this->premium = $premium;
        $this->publishedAs = $publishedAs;
        $this->autoTransferSchedule = $autoTransferSchedule;
        $this->cronStatus = $cronStatus;
        $this->dateTime = $dateTime;
        $this->curlBuilder = $curlBuilder;
        parent::__construct(
            $context,
            $helper,
            $generateOptionsManager,
            $apiManager,
            $settingManager,
            $categoryFields,
            $data
        );
    }

    /**
     * Get has pro access
     *
     * @return bool
     */
    public function getHasProAccess()
    {
        return $this->premium->getHasProAccess();
    }

    /**
     * Get category fields
     *
     * @return array
     */
    public function getCategoryFields()
    {
        return $this->categoryTexts->toOptionArray();
    }

    /**
     * Get product fields
     *
     * @return array
     */
    public function getProductFields()
    {
        return $this->productTexts->toOptionArray();
    }

    /**
     * Get automatic text optimization
     *
     * @return array
     */
    public function getAutomaticTextOptimization()
    {
        return $this->helper->getAutomaticTextOptimizationOptions();
    }

    /**
     * Get trigger actions
     *
     * @return array
     */
    public function getTriggerActions()
    {
        return $this->triggerActions->toOptionArray();
    }

    /**
     * Get default cluster count
     *
     * @return int
     */
    public function getDefaultClusterCount()
    {
        $defaultCount = $this->helper->getKeywordOptimizationSettings('cluster_based_pipelines_count');
        if ($defaultCount !== null) {
            return (int) $defaultCount;
        }
        $rules = $this->getRules();
        return $rules['minClusterBasedPipelinesCount'] ?? 3;
    }

    /**
     * Get default cluster count category
     *
     * @return int
     */
    public function getDefaultClusterCountCategory()
    {
        $defaultCount = $this->helper->getKeywordOptimizationSettings('cluster_based_pipelines_count_category');
        if ($defaultCount !== null) {
            return (int) $defaultCount;
        }
        $rules = $this->getRules();
        return $rules['minClusterBasedPipelinesCountCategory'] ?? 4;
    }

    /**
     * Get default category texts
     *
     * @return array
     */
    public function getDefaultCategoryTexts()
    {
        $selected = $this->helper->getKeywordOptimizationSettings('categories');
        if ($selected) {
            return explode(',', $selected);
        }

        $defaultCategoryTexts = $this->defaultCategoryTexts->getDefaultValues();

        return explode(',', $defaultCategoryTexts);
    }

    /**
     * Get default product texts
     *
     * @return array
     */
    public function getDefaultProductTexts()
    {
        $selected = $this->helper->getKeywordOptimizationSettings('products');
        if ($selected) {
            $selected = explode(',', $selected);
            if (!$this->helper->getCustomOpenGraph()) {
                $noOpenGraph = array_diff($selected, ['open_graph']);
                return $noOpenGraph;
            } else {
                return $selected;
            }
        }

        $defaultProductTexts = $this->defaultProductTexts->getDefaultValues();

        return explode(',', $defaultProductTexts);
    }

    /**
     * Get default trigger action
     *
     * @return string
     */
    public function getDefaultTriggerAction()
    {
        $selected = $this->helper->getKeywordOptimizationSettings('pipeline_keyword/low/trigger_action');
        if ($selected) {
            return $selected;
        }
        return TriggerActions::WHEN_PAGE_IS_RANKING;
    }

    /**
     * Get default automatic text optimization
     *
     * @return string
     */
    public function getDefaultAutomaticTextOptimization()
    {
        $selected = $this->helper->getKeywordOptimizationSettings('automatic_text_optimization');
        if ($selected) {
            return $selected;
        }
        return AutomaticTextOptimization::AUTO_REWRITE_AND_QUEUE;
    }

    /**
     * Get trigger action n position default value
     *
     * @return string
     */
    public function getTriggerActionNPositionDefaultValue()
    {
        $defaultVal = $this->helper->getKeywordOptimizationSettings('pipeline_keyword/low/trigger_action_n_position');
        if ($defaultVal !== null) {
            return $defaultVal;
        }
        $rules = $this->getRules();
        return $rules['minTriggerActionNPosition'] ?? 2;
    }

    /**
     * Get trigger action n position default value per difficulty
     *
     * @param string $difficulty
     *
     * @return string
     */
    public function getTriggerActionNPositionDefaultValuePerDifficulty($difficulty)
    {
        $settingDifficulty = $difficultySettingsEquivalent[$difficulty] ?? 'low';
        $defaultVal = $this->helper->getKeywordOptimizationSettings('pipeline_keyword');
        if (isset($defaultVal[$difficulty]['trigger_action_n_position'])) {
            return $defaultVal[$difficulty]['trigger_action_n_position'];
        }
        $rules = $this->getRules();
        return $rules['minTriggerActionNPositionPerDifficulty'] ?? 2;
    }

    /**
     * Get trigger action after n days default value
     *
     * @return string
     */
    public function getTriggerActionNDaysDefaultValue()
    {
        $defaultVal = $this->helper->getKeywordOptimizationSettings('pipeline_keyword/low/trigger_action_n_days');
        if ($defaultVal !== null) {
            return $defaultVal;
        }
        $rules = $this->getRules();
        return $rules['minTriggerActionNDays'] ?? 1;
    }

    /**
     * Get trigger action after n days default value per difficulty
     *
     * @param string $difficulty
     *
     * @return string
     */
    public function getTriggerActionNDaysDefaultValuePerDifficulty($difficulty)
    {
        $settingDifficulty = $difficultySettingsEquivalent[$difficulty] ?? 'low';
        $defaultVal = $this->helper->getKeywordOptimizationSettings('pipeline_keyword');
        if (isset($defaultVal[$difficulty]['trigger_action_n_days'])) {
            return $defaultVal[$difficulty]['trigger_action_n_days'];
        }
        $rules = $this->getRules();
        return $rules['minTriggerActionNDaysPerDifficulty'] ?? 30;
    }

    /**
     * Get trigger action page is ranking value string
     *
     * @return string
     */
    public function getTriggerActionPageIsRankingValue()
    {
        return TriggerActions::WHEN_PAGE_IS_RANKING;
    }

    /**
     * Get trigger action after N days value string
     *
     * @return string
     */
    public function getTriggerActionAfterNDaysValue()
    {
        return TriggerActions::AFTER_N_DAYS;
    }

    /**
     * Get published as
     *
     * @return array
     */
    public function getPublishedAs()
    {
        return $this->publishedAs->toOptionArray();
    }

    /**
     * Get auto transfer schedule
     *
     * @return array
     */
    public function getAutoTransferSchedule()
    {
        return $this->autoTransferSchedule->toOptionArray();
    }

    /**
     * Is cron job enabled
     *
     * @return bool
     */
    public function isCronRunning()
    {
        return $this->cronStatus->isCronRunning(CronStatus::DEFAULT_CRON_MINUTES_CHECK);
    }

    /**
     * Get cron job disabled message
     *
     * @return string
     */
    public function getCronJobDisabledMessage()
    {
        return __('Website cron jobs have been disabled.'
            . ' This setting requires a cron job to function properly.'
            . ' Please enable it to ensure proper operation.'
            . ' You may need to contact your hosting provider or developer regarding this.');
    }

    /**
     * Get cron job disabled message
     *
     * @return string
     */
    public function getCronJobDisabledAutoTransferMessage()
    {
        return __('Website cron jobs are currently disabled.'
            . ' The auto-transfer option requires a cron job to function properly.'
            . ' You can still view products with re-generated text and queued for transfer'
            . ' by filtering them in the grid. Please enable cron jobs to ensure proper operation.'
            . ' You may need to contact your hosting provider or developer regarding this.');
    }

    /**
     * Get autotransfer settings
     *
     * @param string $setting
     * @return array
     */
    public function getAutotransferSettings($setting)
    {
        $tokenTime = $this->curlBuilder->getTokenTime();
        if ($tokenTime) {
            $tokenTime = $this->helper->convertToStoreTimezone($tokenTime);
            $autotransferSettings = $this->helper->convertToCronSchedule($tokenTime);
        } else {
            $autotransferSettings = $this->helper->getAutotransferSettings($setting);
        }
        return $autotransferSettings;
    }

    /**
     * Get current date and time
     *
     * @return string
     */
    public function getTimezone()
    {
        return $this->helper->getFormattedTimezone();
    }
}
