<?php /** @noinspection ALL */

namespace MDirectorNewsletter\admin;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use MDirectorNewsletter\includes\Mdirector_Newsletter_Api;
use MDirectorNewsletter\includes\Mdirector_Newsletter_Utils;
use MDirectorNewsletter\includes\Mdirector_Newsletter_Twig;
use EmblueNewsletter\Log\Log;
use Throwable;
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;
use Twig\Error\SyntaxError;
use Twig\TemplateWrapper;

require_once(plugin_dir_path(__FILE__) . '../vendor/autoload.php');

/**
 * The admin-specific functionality of the plugin.
 *
 * @link       http://mdirector.com
 * @since      1.0.0
 *
 * @package    MDirector_Newsletter
 * @subpackage MDirector_Newsletter/admin
 */

/**
 * The admin-specific functionality of the plugin.
 *
 * @package    MDirector_Newsletter
 * @subpackage MDirector_Newsletter/admin
 * @author     MDirector
 */
class MDirector_Newsletter_Admin
{
    const ASSETS_PATH = MDIRECTOR_NEWSLETTER_PLUGIN_URL . 'assets';
    const REQUEST_RESPONSE_SUCCESS = 'ok';
    const NO_VALUE = '---';
    const DEFAULT_SETTINGS_TAB = 'settings';
    const STR_SEPARATOR = ' ';
    const SETTINGS_SEPARATOR = '_';
    const MIDNIGHT = '23:59';
    const TEST_FLAG = 'test';
    const TEMPLATE_PREVIEW = 'template_preview';
    const TEMPLATE_SEND_TEST = 'test_now';
    const TEMPLATE_SEND_FORCE = 'delivery_now';
    //CHANGE: prefix name groups is now the only prefix needed
    const PREFIX_NAME_GROUPS = 'WP';

    protected $frequencyDays;
    protected $dynamicSubjectValues;
    protected $currentLanguages = [];

    /**
     * @var \Twig\TemplateWrapper
     */
    protected $adminTemplate;
    protected $apiKey;
    protected $apiSecret;
    protected $bearerToken;
    /**
     * The ID of this plugin.
     *
     * @since    1.0.0
     * @access   private
     * @var      string $MDirectorNewsletter The ID of this plugin.
     */
    private $MDirectorNewsletter;
    /**
     * @var Mdirector_Newsletter_Twig
     */
    private $twigInstance;

    /**
     * The version of this plugin.
     *
     * @since    1.0.0
     * @access   private
     * @var      string $version The current version of this plugin.
     */
    private $version;

    /**
     * @var Mdirector_Newsletter_Utils
     */
    private $MDirectorUtils;

    /**
     * @var Mdirector_Newsletter_Api
     */
    private $MDirectorNewsletterApi;

    /**
     * MDirector_Newsletter_Admin constructor.
     *
     * @param $mdirectorNewsletter
     * @param $version
     *
     * @throws \Twig\Error\LoaderError
     * @throws \Twig\Error\RuntimeError
     * @throws \Twig\Error\SyntaxError
     */
    public function __construct($mdirectorNewsletter, $version)
    {
        $this->loadDependencies();

        $this->MDirectorNewsletter = $mdirectorNewsletter;
        $this->version = $version;
        $this->MDirectorUtils = new Mdirector_Newsletter_Utils();
        $this->MDirectorNewsletterApi = new Mdirector_Newsletter_Api();
        //CHANGE: bearer token is now the only token needed
        $this->bearerToken = $this->getPluginBearerToken();
        //$this->apiKey = $this->getPluginApiKey();
        //$this->apiSecret = $this->getPluginApiSecret();

        $this->twigInstance = new Mdirector_Newsletter_Twig();

        $this->adminTemplate = $this->twigInstance->initAdminTemplate();

        add_action('admin_menu', [$this, 'mdirectorNewsletterMenu']);
        $this->MDirectorUtils->bootNotices();
    }

    private function loadDependencies()
    {
        require_once MDIRECTOR_NEWSLETTER_PLUGIN_DIR
            . 'includes/class-mdirector-newsletter-utils.php';
        require_once MDIRECTOR_NEWSLETTER_PLUGIN_DIR
            . 'includes/class-mdirector-newsletter-twig.php';
    }

    private function getPluginApiKey()
    {
        return $this->getOption('mdirector_api');
    }

    private function getPluginBearerToken()
    {
        return $this->getOption('mdirector_bearer_token');
    }

    private function getOption($option, $options = null)
    {
        if (empty($options)) {
            $options = $this->MDirectorUtils->getPluginOptions();
        }

        return isset($options[$option])
            ? $options[$option]
            : null;
    }

    private function sanitizeCheckboxValue( $value ) {
        return $value === Mdirector_Newsletter_Utils::SETTINGS_OPTION_ON
            ? Mdirector_Newsletter_Utils::SETTINGS_OPTION_ON
            : Mdirector_Newsletter_Utils::SETTINGS_OPTION_OFF;
    }

    private function sanitizeListValue( $value ) {
        if ( is_array( $value ) ) {
            return array_map( 'absint', $value );
        }
        return $value !== null ? absint( $value ) : null;
    }

    private function getPluginApiSecret()
    {
        return $this->getOption('mdirector_secret');
    }

    /**
     * Adds the plugin admin menu.
     *
     * @since    1.0.0
     */
    public function mdirectorNewsletterMenu()
    {
        $menu = add_menu_page(
            'emBlue', 'emBlue', 'manage_options',
            'mdirector-newsletter', [$this, 'mdirectorNewsletterInit'],
            MDIRECTOR_NEWSLETTER_PLUGIN_URL . '/assets/icon_emblue.png'
        );

        add_action("load-{$menu}", [$this, 'mdirectorNewsletterSave']);
    }

    /**
     * @return bool
     * @throws Throwable
     */
    public function mdirectorNewsletterSave() {
        if ( ! current_user_can( 'manage_options' ) ) {
            return false;
        }

        if (
            ! isset( $_POST['_wpnonce'] ) ||
            ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ), 'mdirector-settings-page' )
        ) {
            return false;
        }

        // Reset user values and restoring all to its default values
        if ( isset( $_POST['cpt_reset'] ) ) {
            $this->resetOptions();
            unset($_REQUEST['tab']);

            $templateData = [
                'message' => 'RESET-SUCCESS'
            ];
            $this->MDirectorUtils->reportNotice('updatedWithDetailsInfoNotice', $templateData);
        }

        // Clean cache
        if ( isset( $_POST['cpt_cleancache'] ) ) {
            $this->cleanCache();

            $templateData = [
                'message' => 'CLEAN-CACHE-SUCCESS',
            ];
            $this->MDirectorUtils->reportNotice( 'updatedWithDetailsInfoNotice', $templateData );
        }

        // Creating MDirector lists on demand
        if ( isset( $_POST['cpt_submit_create_lists'] ) ) {
            $this->createMdirectorLists();
            return true;
        }

        if ( isset( $_POST['cpt_submit_create_campaings'] ) ) {
            $this->createMdirectorCampaigns();
        }

        $submit_main = isset( $_POST['mdirector-newsletter-submit'] )
            ? sanitize_key( wp_unslash( $_POST['mdirector-newsletter-submit'] ) )
            : '';
        $submit_debug = isset( $_POST['save-debug-submit'] )
            ? sanitize_key( wp_unslash( $_POST['save-debug-submit'] ) )
            : '';
        $submit_advance = isset( $_POST['save-advance-submit'] )
            ? sanitize_key( wp_unslash( $_POST['save-advance-submit'] ) )
            : '';

        if ( $submit_main === Mdirector_Newsletter_Utils::SETTINGS_OPTION_ON ) {
            $this->saveSettings( $_POST ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- sanitized inside saveSettings().
        } elseif ( $submit_debug === Mdirector_Newsletter_Utils::SETTINGS_OPTION_ON ) {
            $this->saveDebugSettings( $_POST ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            $templateData = [
                'message' => 'DEBUG-FORM__SAVE-SUCCESS',
            ];
            $this->MDirectorUtils->reportNotice( 'updatedInfoNotice', $templateData );
        } elseif ( $submit_advance === Mdirector_Newsletter_Utils::SETTINGS_OPTION_ON ) {
            $this->saveAdvanceSettings( $_POST ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            $templateData = [
                'message' => 'ADVANCE-FORM__SAVE-SUCCESS',
            ];
            $this->MDirectorUtils->reportNotice( 'updatedInfoNotice', $templateData );
        }

        $this->MDirectorUtils->log( 'Info POST', $this->sanitizeFormFields( (array) wp_unslash( $_POST ) ), $this->MDirectorUtils::LOG_INFO );

        // Sending the campaigns immediately
        if ( isset( $_POST['cpt_submit_test_now'] ) ) {
            $this->MDirectorUtils->log( 'Sending campaigns inmediately...', [], $this->MDirectorUtils::LOG_INFO );
            $this->saveSettings( $_POST ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            $this->saveDebugSettings( $_POST ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            $this->sendingTest();
        }

        // Reset counters
        if (isset($_POST['cpt_submit_reset_now'])) {
            $this->MDirectorUtils->resetDeliveriesSent();
            $templateData = [
                'message' => 'LAST-SENDINGS-RESTARTED'
            ];
            $this->MDirectorUtils->reportNotice('updatedWithDetailsInfoNotice', $templateData);
        }

        return true;
    }

    private function resetOptions()
    {
        $this->MDirectorUtils->updateMDirectorSettingsWithLog([], 'Reset options.');
    }

    private function cleanCache()
    {
        $dir = ( new Mdirector_Newsletter_Twig() )->getCachePath();
        if ( $dir && is_dir( $dir ) ) {
            self::deleteDir($dir);
        }
    }

    public static function deleteDir($dirPath)
    {
        if (!is_dir($dirPath)) {
            throw new InvalidArgumentException( esc_html( $dirPath ) . ' must be a directory' );
        }
        if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
            $dirPath .= '/';
        }

        $files = glob($dirPath . '*', GLOB_MARK);

        foreach ($files as $file) {
            if (is_dir($file)) {
                self::deleteDir($file);
            } else {
                wp_delete_file( $file );
            }
        }
    }

    /**
     * @return bool
     * @throws Throwable
     */
    public function createMdirectorLists()
    {
        if (!$this->isPluginConfigured()) {
            return false;
        }

        $mdirectorUserLists = [];
        //CHANGE: bearer token is now the only token needed
        $token = $this->bearerToken;
        $response = $this->MDirectorNewsletterApi->callAPI(
            $token,
            Mdirector_Newsletter_Utils::MDIRECTOR_API_GROUPS_LIST_ENDPOINT,
             //CHANGE: endpoint groups list is now the only endpoint needed
            'POST',
            ["search" => "WP"]
        );
        if (is_wp_error($response)) {
            $this->MDirectorUtils->log(
                'Error retrieving groups list: ' . $response->get_error_message(),
                [],
                $this->MDirectorUtils::LOG_ERROR
            );
            return false;
        }
        $mdirectorRequest = json_decode($response);

        if (is_array($mdirectorRequest)) {
            $mdirectorUserLists = array_map(function ($e) {
                return $e->name;
            }, $mdirectorRequest);
        }       

        $this->createMdirectorDailyGroups($mdirectorUserLists);
        $this->createMdirectorWeeklyGroups($mdirectorUserLists);

        return true;
    }

    private function isPluginConfigured()
    {
        $options = $this->MDirectorUtils->getPluginOptions();
        
        if (!isset($options['mdirector_bearer_token'])) {
            return false;
        }

        $this->bearerToken || ($this->bearerToken = $options['mdirector_bearer_token']);
        return $this->bearerToken;
    }

    /**
     * @param $array_list_names
     *
     * @throws Throwable
     */
    private function createMdirectorDailyGroups($array_list_names)
    {
        $options = $this->MDirectorUtils->getPluginOptions();
        $newListIds = [];

        foreach ($this->MDirectorUtils->getCurrentLanguages() as $lang => $id) {
            $dailyName = $this->composeListName([$lang => $id],
                Mdirector_Newsletter_Utils::DAILY_FREQUENCY);
           

            if (in_array($dailyName, $array_list_names)) {
                //CHANGE: time is now the only time needed
                //$dailyName .= self::STR_SEPARATOR . time();
                $dailyName = $dailyName . self::STR_SEPARATOR . gmdate( 'YmdHis' );
            }
           
            $mdirectorDailyId = $this->createGroupViaAPI($dailyName);
            
            //CHANGE: group id is now the only id needed
            if ($mdirectorDailyId && is_numeric($mdirectorDailyId) && $mdirectorDailyId > 0) {
                $options['mdirector_daily_list_' . $lang] =
                    $mdirectorDailyId;
                $options['mdirector_daily_list_name_' . $lang] = $dailyName;
                $this->MDirectorUtils->updateMDirectorSettingsWithLog($options, 'Create Mdirector Daily Lists OK');
                $templateData = [
                    'listName' => $dailyName,
                    'listId' => $mdirectorDailyId,
                    'message' => 'DAILY-LISTS__NEW-DAILY-LIST-ADDED'
                ];
                $this->MDirectorUtils->reportNotice('updatedWithDetailsInfoNotice', $templateData);
                $newListIds[] = $mdirectorDailyId;
            } else {
                $templateData = [
                    'message' => 'DAILY-LISTS__NEW-DAILY-LIST-ADDED-ERROR'
                ];
                $this->MDirectorUtils->reportNotice('updatedErrorNotice', $templateData);
                $this->MDirectorUtils->log(
                    'DAILY lists can not be created',
                    [],
                    $this->MDirectorUtils::LOG_ERROR
                );
            }
        }

        if (count($newListIds) > 0) {
            $this->MDirectorUtils->log(
                'New DAILY lists created',
                ['ids' => $newListIds],
                $this->MDirectorUtils::LOG_INFO
            );
        }
    }

    private function composeListName($list, $type)
    {
        //CHANGE: blog name is now the only name needed
        $blog_name = sanitize_text_field(get_bloginfo('name'));
        $blog_name = str_replace('-', ' ', $blog_name);
        $lang = key($list);

        return self::PREFIX_NAME_GROUPS . self::STR_SEPARATOR . $blog_name . self::STR_SEPARATOR .
            ($type === Mdirector_Newsletter_Utils::DAILY_FREQUENCY
                ? Mdirector_Newsletter_Utils::DAILY_FREQUENCY
                : Mdirector_Newsletter_Utils::WEEKLY_FREQUENCY) .
            self::STR_SEPARATOR . $lang;
    }

    /**
     * @param $groupName
     *
     * @return array|mixed|object
     */
    private function createGroupViaAPI($groupName)
    {
        $token = $this->bearerToken;
        $response = $this->MDirectorNewsletterApi->callAPI(
            $token,
            Mdirector_Newsletter_Utils::MDIRECTOR_API_GROUPS_ENDPOINT,
            'POST', 
            ['groupName' => $groupName]
        );
        if (is_wp_error($response)) {
            $this->MDirectorUtils->log(
                'Error creating group: ' . $response->get_error_message(),
                ['groupName' => $groupName],
                $this->MDirectorUtils::LOG_ERROR
            );
            
            return (object) [
                'response' => 'error',
                'message' => $response->get_error_message()
            ];
        }
        $result = json_decode($response);
        
        if (json_last_error() !== JSON_ERROR_NONE) {
            $this->MDirectorUtils->log(
                'JSON decode error: ' . json_last_error_msg(),
                ['groupName' => $groupName],
                $this->MDirectorUtils::LOG_ERROR
            );
            
            return (object) [
                'response' => 'error',
                'message' => 'Invalid JSON response'
            ];
        }
        
        return $result;
    }

    /**
     * @param $array_list_names
     *
     * @throws Throwable
     */
    private function createMdirectorWeeklyGroups($array_list_names)
    {
        $options = $this->MDirectorUtils->getPluginOptions();
        $newListIds = [];

        foreach ($this->MDirectorUtils->getCurrentLanguages() as $lang => $id) {
            $weeklyName = $this->composeListName([$lang => $id],
                Mdirector_Newsletter_Utils::WEEKLY_FREQUENCY);

            if (in_array($weeklyName, $array_list_names)) {
                //CHANGE: time is now the only time needed
                //$weeklyName .= self::STR_SEPARATOR . time();
                $weeklyName = $weeklyName . self::STR_SEPARATOR . gmdate( 'YmdHis' );
            }

            $mdirectorWeeklyId = $this->createGroupViaAPI($weeklyName);
            
            if ($mdirectorWeeklyId && is_numeric($mdirectorWeeklyId) && $mdirectorWeeklyId > 0) {

                $options['mdirector_weekly_list_' . $lang] =
                    $mdirectorWeeklyId;
                $options['mdirector_weekly_list_name_' . $lang] = $weeklyName;
                $this->MDirectorUtils->updateMDirectorSettingsWithLog($options, 'Create Mdirector Weekly Lists OK');
                $templateData = [
                    'listName' => $weeklyName,
                    'listId' => $mdirectorWeeklyId,
                    'message' => 'WEEKLY-LISTS__NEW-WEEKLY-LIST-ADDED'
                ];
                $this->MDirectorUtils->reportNotice('updatedWithDetailsInfoNotice', $templateData);
                $newListIds[] = $mdirectorWeeklyId;
            } else {
                $templateData = [
                    'message' => 'WEEKLY-LISTS__NEW-WEEKLY-LIST-ADDED-ERROR'
                ];
                $this->MDirectorUtils->reportNotice('updatedErrorNotice', $templateData);

                $this->MDirectorUtils->log(
                    'WEEKLY lists can not be created',
                    [],
                    $this->MDirectorUtils::LOG_ERROR
                );
            }
        }

        if (count($newListIds) > 0) {
            $this->MDirectorUtils->log(
                'New WEEKLY lists created',
                ['ids' => $newListIds],
                $this->MDirectorUtils::LOG_INFO
            );
        }
    }

    /**
     * @return bool
     */
    public function createMdirectorCampaigns()
    {
        if (!$this->isPluginConfigured()) {
            return false;
        }

        $MDirectorUserCampaigns = [];
        //CHANGE: bearer token is now the only token needed
        //$token = $this->getPluginApiKey();
        $token = $this->bearerToken;
        $MDirectorRequest =
            json_decode(
                $this->MDirectorNewsletterApi->callAPI(
                    $token,
                    Mdirector_Newsletter_Utils::MDIRECTOR_API_CAMPAIGN_ENDPOINT,
                    'GET'
                )
            );

        if ($MDirectorRequest->response === self::REQUEST_RESPONSE_SUCCESS) {
            $MDirectorUserCampaigns = array_map(function ($e) {
                return $e->campaignName;
            }, $MDirectorRequest->data);
        }

        $this->createMdirectorDailyCampaigns($MDirectorUserCampaigns);
        $this->createMdirectorWeeklyCampaigns($MDirectorUserCampaigns);

        return true;
    }


    /**
     * @param $array_campaign_names
     *
     */
    private function createMdirectorDailyCampaigns($array_campaign_names)
    {
        $options = $this->MDirectorUtils->getPluginOptions();

        foreach ($this->MDirectorUtils->getCurrentLanguages() as $lang => $id) {
            $dailyName = $this->composeListName([$lang => $id],
                Mdirector_Newsletter_Utils::DAILY_FREQUENCY);

            if (in_array($dailyName, $array_campaign_names)) {
                $dailyName .= self::STR_SEPARATOR . time();
            }

            $mdirectorDailyId = $this->createCampaignViaAPI($dailyName);

            if ($mdirectorDailyId->response
                === self::REQUEST_RESPONSE_SUCCESS) {
                $options['mdirector_daily_campaign_' . $lang] =
                    $mdirectorDailyId->data->camId;
                $options['mdirector_daily_campaign_name_' . $lang] = $dailyName;

                $this->MDirectorUtils->updateMDirectorSettingsWithLog($options, 'Create Mdirector Daily Campaigns OK');
            }
        }
    }

    /**
     * @param $campaignName
     *
     * @return mixed
     */
    private function createCampaignViaAPI($campaignName)
    {
        //CHANGE: bearer token is now the only token needed
        //$token = $this->getPluginApiKey();
        $token = $this->bearerToken;
        return json_decode(
            $this->MDirectorNewsletterApi->callAPI(
                $token,
                Mdirector_Newsletter_Utils::MDIRECTOR_API_CAMPAIGN_ENDPOINT,
                'POST', [
                    'name' => $campaignName
                ]
            )
        );
    }

    /**
     * @param $arrayCampaignNames
     *
     */
    private function createMdirectorWeeklyCampaigns($arrayCampaignNames)
    {
        $options = $this->MDirectorUtils->getPluginOptions();

        foreach ($this->MDirectorUtils->getCurrentLanguages() as $lang => $id) {
            $weeklyName = $this->composeListName([$lang => $id],
                Mdirector_Newsletter_Utils::WEEKLY_FREQUENCY);

            if (in_array($weeklyName, $arrayCampaignNames)) {
                $weeklyName .= self::STR_SEPARATOR . time();
            }

            $mdirectorWeeklyId = $this->createCampaignViaAPI($weeklyName);

            if ($mdirectorWeeklyId->response
                === self::REQUEST_RESPONSE_SUCCESS) {
                $options['mdirector_weekly_campaign_' . $lang] =
                    $mdirectorWeeklyId->data->camId;
                $options['mdirector_weekly_campaign_name_' . $lang] =
                    $weeklyName;
                $this->MDirectorUtils->updateMDirectorSettingsWithLog($options, 'Create Mdirector Weekly Campaigns OK');
            }
        }
    }

    /**
     * @param $data
     *
     * @throws Throwable
     */
    private function saveSettings($data)
    {
        if ($this->getCurrentTab() === 'settings') {
            unset($data['mdirector-newsletter-submit']);

            $formFields = $this->sanitizeFormFields( $this->pregGrepKeys('/^mdirector_/', $data) );

            $options = array_merge(
                $this->MDirectorUtils->getPluginOptions(),
                $formFields,
                $this->checkCheckboxesValuesForSave($data)
            );
            $this->MDirectorUtils->updateMDirectorSettingsWithLog($options, 'Saving new options. Save Settings');
            if (isset($_POST['cpt_submit'])) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified in mdirectorNewsletterSave() before this is called.
                $templateData = [
                    'message' => 'MAIN-FORM__SAVE-SUCCESS'
                ];
                $this->MDirectorUtils->reportNotice('updatedInfoNotice', $templateData);
            }
        }
    }

    private function getCurrentTab() {
        return isset( $_REQUEST['tab'] ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- tab is a display-only parameter, not a data mutation.
            ? sanitize_key( wp_unslash( $_REQUEST['tab'] ) ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
            : self::DEFAULT_SETTINGS_TAB;
    }

    private function pregGrepKeys($pattern, $input, $flags = 0)
    {
        return array_intersect_key(
            $input,
            array_flip(preg_grep($pattern, array_keys($input), $flags))
        );
    }

    private function sanitizeFormFields( array $data ): array {
        $sanitized = [];
        foreach ( $data as $key => $value ) {
            if ( is_array( $value ) ) {
                $sanitized[ $key ] = array_map( 'sanitize_text_field', array_map( 'wp_unslash', $value ) );
            } elseif ( false !== strpos( $key, '_url' ) ) {
                $sanitized[ $key ] = esc_url_raw( wp_unslash( (string) $value ) );
            } else {
                $sanitized[ $key ] = sanitize_text_field( wp_unslash( (string) $value ) );
            }
        }
        return $sanitized;
    }

    private function checkCheckboxesValuesForSave($data)
    {
        $options = [];
        $options['mdirector_frequency_weekly'] = $this->sanitizeCheckboxValue( $this->getOption('mdirector_frequency_weekly', $data) );
        $options['mdirector_frequency_daily'] = $this->sanitizeCheckboxValue( $this->getOption('mdirector_frequency_daily', $data) );

        // Asegurar que los senders se guarden correctamente
        $options['mdirector_sender_weekly'] = sanitize_text_field( wp_unslash( (string) $this->getOption('mdirector_sender_weekly', $data) ) );
        $options['mdirector_sender_daily'] = sanitize_text_field( wp_unslash( (string) $this->getOption('mdirector_sender_daily', $data) ) );

        $options['mdirector_exclude_cats'] =
            ((isset($data['mdirector_exclude_cats'])
                && count($data['mdirector_exclude_cats']) > 0)
                ? serialize( array_map( 'absint', $data['mdirector_exclude_cats'] ) )
                : []);

        foreach ($this->getWeekdaySelectorArray() as $dayWeek => $dayWeekLong) {
            $fieldName = Mdirector_Newsletter_Utils::DAILY_WEEKS_ALLOWED_PREFIX
                . $dayWeek;
            $options[$fieldName] = $this->sanitizeCheckboxValue(
                $data[$fieldName] ?? Mdirector_Newsletter_Utils::SETTINGS_OPTION_OFF
            );
        }

        foreach ($this->MDirectorUtils->getCurrentLanguages() as $language) {
            $lang = $language['code'];
            $prefix = 'mdirector_';
            $active_policy = $prefix . 'policy_' . $lang . '_active';
            $options[$active_policy] = $this->sanitizeCheckboxValue( $this->getOption($active_policy, $data) );

            $lists = [
                $prefix . Mdirector_Newsletter_Utils::DAILY_FREQUENCY . '_list_' . $lang,
                $prefix . Mdirector_Newsletter_Utils::DAILY_FREQUENCY . '_list_group_' . $lang,
                $prefix . Mdirector_Newsletter_Utils::DAILY_FREQUENCY . '_list_segment_' . $lang,
                $prefix . Mdirector_Newsletter_Utils::WEEKLY_FREQUENCY . '_list_' . $lang,
                $prefix . Mdirector_Newsletter_Utils::WEEKLY_FREQUENCY . '_list_group_' . $lang,
                $prefix . Mdirector_Newsletter_Utils::WEEKLY_FREQUENCY . '_list_segment_' . $lang,
            ];

            foreach ($lists as $list) {
                $options[$list] = $this->sanitizeListValue( $this->getOption($list, $data) );
            }
        }

        return $options;
    }

    private function getWeekdaySelectorArray()
    {
        return [
            'mon' => 'MONDAY',
            'tue' => 'TUESDAY',
            'wed' => 'WEDNESDAY',
            'thu' => 'THURSDAY',
            'fri' => 'FRIDAY',
            'sat' => 'SATURDAY',
            'sun' => 'SUNDAY'
        ];
    }

    private function saveDebugSettings($data)
    {
        if ($this->getCurrentTab() === 'debug') {
            $debugOptions = $this->sanitizeFormFields( $this->pregGrepKeys('/^mdirector_/', $data) );
            $options = array_merge($this->MDirectorUtils->getPluginOptions(), $debugOptions);

            foreach ($this->MDirectorUtils->getCurrentLanguages() as $language) {
                $lang = $language['code'];
                $prefix = 'mdirector_';
                $debugOptionsCheckboxes = [
                    $prefix . Mdirector_Newsletter_Utils::DAILY_FREQUENCY . '_list_test_' . $lang,
                    $prefix . Mdirector_Newsletter_Utils::DAILY_FREQUENCY . '_list_test_group_' . $lang,
                    $prefix . Mdirector_Newsletter_Utils::DAILY_FREQUENCY . '_list_test_segment_' . $lang,
                    $prefix . Mdirector_Newsletter_Utils::WEEKLY_FREQUENCY . '_list_test_' . $lang,
                    $prefix . Mdirector_Newsletter_Utils::WEEKLY_FREQUENCY . '_list_test_group_' . $lang,
                    $prefix . Mdirector_Newsletter_Utils::WEEKLY_FREQUENCY . '_list_test_segment_' . $lang,
                    'mdirector_use_test_lists'
                ];

                foreach ($debugOptionsCheckboxes as $option) {
                    $options[$option] = $this->sanitizeCheckboxValue( $this->getOption($option, $data) );
                }
            }
            
            $options['mdirector_test_groups'] = isset( $data['mdirector_test_groups'] )
                ? sanitize_text_field( wp_unslash( (string) $data['mdirector_test_groups'] ) )
                : '';
            
            $this->MDirectorUtils->updateMDirectorSettingsWithLog($options, 'Saving new options. Save Debug Settings');
        }
    }

    private function saveAdvanceSettings($data)
    {
        $advanceOptions = $this->sanitizeFormFields( $this->pregGrepKeys('/^mdirector_/', $data) );
        $options = array_merge($this->MDirectorUtils->getPluginOptions(), $advanceOptions);

        $advanceOptionsCheckboxes = [
            'mdirector_hide_sample_templates',
            'mdirector_scheduler_posts',
            'mdirector_logs_deactivated'
        ];

        foreach ($advanceOptionsCheckboxes as $option) {
            $options[$option] = $this->sanitizeCheckboxValue( $this->getOption($option, $data) );
        }

        $this->MDirectorUtils->updateMDirectorSettingsWithLog($options, 'Saving new options. Advance Settings');
    }

    /**
     * @throws Throwable
     * @throws \Twig\Error\LoaderError
     * @throws \Twig\Error\RuntimeError
     * @throws \Twig\Error\SyntaxError
     */
    private function sendingTest()
    {
        $options = $this->MDirectorUtils->getPluginOptions();

        if ($options['mdirector_frequency_daily'] === Mdirector_Newsletter_Utils::SETTINGS_OPTION_ON) {
            $this->sendDailyTest();
        } else {
            $templateData = [
                'message' => 'SENDING-TEST__DAILY-DEACTIVATED'
            ];
            $this->MDirectorUtils->reportNotice('updatedErrorNotice', $templateData);
        }

        if ($options['mdirector_frequency_weekly'] === Mdirector_Newsletter_Utils::SETTINGS_OPTION_ON) {
            $this->sendWeeklyTest();
        } else {
            $templateData = [
                'message' => 'SENDING-TEST__WEEKLY-DEACTIVATED'
            ];
            $this->MDirectorUtils->reportNotice('updatedErrorNotice', $templateData);
        }
    }

    /**
     * @throws Throwable
     * @throws \Twig\Error\LoaderError
     * @throws \Twig\Error\RuntimeError
     * @throws \Twig\Error\SyntaxError
     */
    private function sendDailyTest() {
        $options = $this->MDirectorUtils->getPluginOptions();
        $options['mdirector_hour_daily'] = self::MIDNIGHT;
        // Nonce verified in mdirectorNewsletterSave() before this is called.
        $deliveryMode = isset( $_POST['cpt_submit_test_now'] ) // phpcs:ignore WordPress.Security.NonceVerification.Missing
            ? sanitize_key( wp_unslash( $_POST['cpt_submit_test_now'] ) ) // phpcs:ignore WordPress.Security.NonceVerification.Missing
            : '';
        $isTestMode = $this->isTestMode();

        $responseDailies = $this->MDirectorUtils->buildDailyMails(
            $deliveryMode === self::TEMPLATE_PREVIEW,
            $isTestMode,
            $deliveryMode === self::TEMPLATE_SEND_FORCE
        );

        if (!empty($responseDailies)) {
            foreach ($responseDailies as $lang => $result) {
                $listsID = $this->MDirectorUtils->prettyPrintMultiArray(
                    $this->MDirectorUtils->getDefaultUserLists(
                        Mdirector_Newsletter_Utils::DAILY_FREQUENCY, $lang, $isTestMode
                    )
                );

                if ($result) {
                    $templateData = [
                        'message' => 'SENDING-TEST__DAILY-SENDING',
                        'listName' => $listsID
                    ];

                    $this->MDirectorUtils->reportNotice('updatedWithDetailsInfoNotice', $templateData);
                } else {
                    $templateData = [
                        'message' => 'SENDING-TEST__DAILY-SENDING-ERROR',
                        'details' => ': ' . $listsID . ' '
                            . __( 'NO-ENTRIES-IN-BLOG', 'emblue-newsletter' ),
                        'listName' => $listsID
                    ];

                    $this->MDirectorUtils->reportNotice('updatedErrorNotice', $templateData);
                }
            }
        } else {
            $templateData = [
                'message' => 'SENDING-TEST__DAILY-GENERAL-SENDING-ERROR-NO-ACTIVES'
            ];
            $this->MDirectorUtils->reportNotice('updatedErrorNotice', $templateData);
        }
    }

    private function isTestMode() {
        // Nonce verified upstream in mdirectorNewsletterSave() before this is called.
        $mode = isset( $_POST['cpt_submit_test_now'] ) // phpcs:ignore WordPress.Security.NonceVerification.Missing
            ? sanitize_key( wp_unslash( $_POST['cpt_submit_test_now'] ) ) // phpcs:ignore WordPress.Security.NonceVerification.Missing
            : '';
        return $mode === self::TEMPLATE_SEND_TEST;
    }

    /**
     * @throws Throwable
     * @throws \Twig\Error\LoaderError
     * @throws \Twig\Error\RuntimeError
     * @throws \Twig\Error\SyntaxError
     */
    private function sendWeeklyTest()
    {
        $options = $this->MDirectorUtils->getPluginOptions();
        $options['mdirector_hour_weekly'] = self::MIDNIGHT;
        // Nonce verified upstream in mdirectorNewsletterSave().
        $deliveryMode = isset( $_POST['cpt_submit_test_now'] ) // phpcs:ignore WordPress.Security.NonceVerification.Missing
            ? sanitize_key( wp_unslash( $_POST['cpt_submit_test_now'] ) ) // phpcs:ignore WordPress.Security.NonceVerification.Missing
            : '';
        $isTestMode = $this->isTestMode();

        $responseWeeklies = $this->MDirectorUtils->buildWeeklyMails(
            $deliveryMode === self::TEMPLATE_PREVIEW,
            $isTestMode,
            $deliveryMode === self::TEMPLATE_SEND_FORCE
        );
        if (!empty($responseWeeklies)) {
            foreach ($responseWeeklies as $lang => $result) {
                $listsID = $this->MDirectorUtils->prettyPrintMultiArray(
                    $this->MDirectorUtils->getDefaultUserLists(
                        Mdirector_Newsletter_Utils::WEEKLY_FREQUENCY, $lang, $isTestMode
                    )
                );

                if ($result) {
                    $templateData = [
                        'message' => 'SENDING-TEST__WEEKLY-SENDING',
                        'listName' => $listsID
                    ];
                    $this->MDirectorUtils->reportNotice('updatedWithDetailsInfoNotice', $templateData);
                } else {
                    $templateData = [
                        'message' => 'SENDING-TEST__WEEKLY-SENDING-ERROR',
                        'details' => ': ' . $listsID . ' '
                            . __( 'NO-ENTRIES-IN-BLOG', 'emblue-newsletter' ),
                        'listName' => $listsID
                    ];
                    $this->MDirectorUtils->reportNotice('updatedErrorNotice', $templateData);
                }
            }
        } else {
            $templateData = [
                'message' => 'SENDING-TEST__WEEKLY-GENERAL-SENDING-ERROR-NO-ACTIVES'
            ];
            $this->MDirectorUtils->reportNotice('updatedErrorNotice', $templateData);
        }
    }

    /**
     * @throws Throwable
     */
    public function mdirectorNewsletterInit()
    {
        $this->mdirectorChecks();
        $this->setCurrentLanguages();
        $this->setTranslationsStrings();

        //$this->createMdirectorCampaigns();

        $tabs = [
            'settings' => __( 'CONFIGURATION', 'emblue-newsletter' )
        ];

        if ($this->isPluginConfigured()) {
            $tabs = array_merge($tabs, [
                'advance' => __( 'ADVANCE', 'emblue-newsletter' ),
                'logs' => 'Logs'
            ]);
        } else {
            $tabs = array_merge(['welcome' => __( 'WELCOME', 'emblue-newsletter' )], $tabs);
        }

        $tabs = array_merge($tabs, ['help' => __( 'HELP', 'emblue-newsletter' )]);
        $currentTab = $this->getCurrentTab();

        //$this->MdirectorUtils->printNotices();

        echo '<div id="mdirector-newsletter">';
        echo wp_kses( $this->adminTemplate->renderBlock(
            'header',
            ['tabs' => $tabs, 'currentTab' => $currentTab]
        ), Mdirector_Newsletter_Utils::allowedHtml() );

        echo '<form method="post" action="'
            . esc_url( admin_url( 'admin.php?page=mdirector-newsletter' ) )
            . '" class="form-table form-md">';
        wp_nonce_field('mdirector-settings-page');

        switch ($currentTab) {
            case 'settings':
                $this->mdTabContentSettings();
                break;
            case 'logs':
                $this->mdTabContentLogs();
                break;
            case 'help':
                $this->mdTabContentHelp();
                break;
            case 'welcome':
                $this->mdTabContentWelcome();
                break;
            case 'advance':
                $this->mdTabContentAdvance();
                break;
            case 'debug':
                $this->mdTabContentTests();
                break;
            default:
                ($this->isPluginConfigured())
                    ? $this->mdTabContentSettings()
                    : $this->mdTabContentWelcome();
                break;
        }
        echo '</form>';
        echo '</div>';
    }

    /**
     * @throws Throwable
     */
    public function mdirectorChecks()
    {
        if ($this->checkVersion() && $this->check_curl()
            && $this->checkApi()) {
            update_option(
                'mdirector_active',
                Mdirector_Newsletter_Utils::SETTINGS_OPTION_ON
            );
        } else {
            update_option(
                'mdirector_active',
                Mdirector_Newsletter_Utils::SETTINGS_OPTION_OFF
            );
        }
    }

    /**
     * @return bool
     * @throws Throwable
     */
    public function checkVersion()
    {
        if (version_compare(
            MDIRECTOR_CURRENT_WP_VERSION,
            MDIRECTOR_MIN_WP_VERSION, '<='
        )) {
            unset($_GET['activate']);

            $templateData = [
                'message' => 'CHECK-WP-VERSION',
                'details' => MDIRECTOR_MIN_WP_VERSION
            ];

            echo wp_kses( $this->adminTemplate->renderBlock(
                'errorGeneralNotice',
                $templateData
            ), Mdirector_Newsletter_Utils::allowedHtml() );

            return false;
        }

        return true;
    }

    /**
     * @return bool
     * @throws Throwable
     */
    public function check_curl()
    {
        if (!(function_exists('curl_exec'))) {
            $templateData = [
                'message' => 'CHECK-CURL'
            ];

            echo wp_kses( $this->adminTemplate->renderBlock(
                'errorGeneralNotice',
                $templateData
            ), Mdirector_Newsletter_Utils::allowedHtml() );

            return false;
        }

        return true;
    }

    /**
     * @return bool
     * @throws Throwable
     */
    public function checkApi()
    {
        $params = [
            "search" => "WP",
          ];
        $options = $this->MDirectorUtils->getPluginOptions();        
        if ($this->isPluginConfigured()) {
            $token = $options['mdirector_bearer_token'];
            $data= $this->MDirectorNewsletterApi->callAPI(
                $token,
                Mdirector_Newsletter_Utils::MDIRECTOR_API_GROUPS_LIST_ENDPOINT,
                'POST',
                $params
            );            
            if(is_wp_error($data)) {                
                $templateData = ['message' => 'CHECK-API-ERROR-GENERAL'];
                echo wp_kses( $this->adminTemplate->renderBlock( 'errorGeneralNotice', $templateData ), Mdirector_Newsletter_Utils::allowedHtml() );
                return false;
            }
            $response = json_decode($data);
        } else {
            $templateData = [
                'message' => 'CHECK-API'
            ];

            echo wp_kses( $this->adminTemplate->renderBlock(
                'errorGeneralNotice',
                $templateData
            ), Mdirector_Newsletter_Utils::allowedHtml() );

            return false;
        }

        if (is_null($response) || (isset($response->code) && $response->code === 401)) {
            $options['mdirector_api'] = '';
            $options['mdirector_secret'] = '';

            $this->MDirectorUtils->updateMDirectorSettingsWithLog($options, 'Check Api');

            $templateData = [
                'message' => 'CHECK-API-ERROR'
            ];

            echo wp_kses( $this->adminTemplate->renderBlock(
                'errorGeneralNotice',
                $templateData
            ), Mdirector_Newsletter_Utils::allowedHtml() );

            return false;
        }

        return true;
    }

    private function setCurrentLanguages()
    {
        $this->currentLanguages = $this->MDirectorUtils->getCurrentLanguages();
    }

    private function setTranslationsStrings()
    {
        $this->frequencyDays = [
            '1' => __( 'WEEKDAY__MONDAY', 'emblue-newsletter' ),
            '2' => __( 'WEEKDAY__TUESDAY', 'emblue-newsletter' ),
            '3' => __( 'WEEKDAY__WEDNESDAY', 'emblue-newsletter' ),
            '4' => __( 'WEEKDAY__THURSDAY', 'emblue-newsletter' ),
            '5' => __( 'WEEKDAY__FRIDAY', 'emblue-newsletter' ),
            '6' => __( 'WEEKDAY__SATURDAY', 'emblue-newsletter' ),
            '7' => __( 'WEEKDAY__SUNDAY', 'emblue-newsletter' ),
        ];

        $this->dynamicSubjectValues = [
            Mdirector_Newsletter_Utils::DYNAMIC_CRITERIA_FIRST_POST =>
                __( 'SUBJECT-VALUES__FIRST-POST-TITLE', 'emblue-newsletter' ),
            Mdirector_Newsletter_Utils::DYNAMIC_CRITERIA_LAST_POST =>
                __( 'SUBJECT-VALUES__LAST-POST-TITLE', 'emblue-newsletter' )
        ];
    }

    /**
     * @throws Throwable
     */
    public function mdTabContentSettings()
    {
        $options = $this->MDirectorUtils->getPluginOptions();
        update_option('mdirector-notice', 'true', true);

        $test_lists = $this->getOption('mdirector_use_test_lists');

        if ($this->isPluginConfigured()) {
            if (empty($options['mdirector_subject_type_daily'])) {
                $options['mdirector_subject_type_daily'] =
                    Mdirector_Newsletter_Utils::DEFAULT_DAILY_MAIL_SUBJECT;
            }

            if (empty($options['mdirector_subject_type_weekly'])) {
                $options['mdirector_subject_type_weekly'] =
                    Mdirector_Newsletter_Utils::DEFAULT_WEEKLY_MAIL_SUBJECT;
            }
        }

        // ── Calcular qué pasos tienen valor configurado ──────────────────
        $on = Mdirector_Newsletter_Utils::SETTINGS_OPTION_ON;

        $configured = [
            1 => !empty($this->bearerToken),
            2 => $this->mdStepHasCampaigns($options),
            3 => (($options['mdirector_frequency_weekly'] ?? '') === $on
                || ($options['mdirector_frequency_daily'] ?? '') === $on),
            4 => true,
            5 => true,
            6 => !empty($options['mdirector_template_general']),
            7 => true,
        ];

        // Primer paso sin configurar → se abre; si todos OK → abre el 1
        $openStep = 1;
        foreach ($configured as $num => $ok) {
            if (!$ok) {
                $openStep = $num;
                break;
            }
        }
        // ─────────────────────────────────────────────────────────────────

        if ($this->MDirectorUtils->isWPML()) {
            echo wp_kses( $this->getWPMLCompatibilityTemplate(), Mdirector_Newsletter_Utils::allowedHtml() );
        }

        echo wp_kses( $this->getHTMLStep1( $openStep === 1, $configured[1] ), Mdirector_Newsletter_Utils::allowedHtml() );

        if ( $this->isPluginConfigured() ) {
            echo wp_kses( $this->getHTMLStep2( $openStep === 2, $configured[2] ), Mdirector_Newsletter_Utils::allowedHtml() );

            $deliveriesTitle = __( 'STEP-4-5__TITLE', 'emblue-newsletter' );
            if ($deliveriesTitle === 'STEP-4-5__TITLE') {
                $deliveriesTitle = 'Programación de envíos';
            }
            $step3Class = $configured[3]
                ? 'mdirector-accordion__step--ok'
                : 'mdirector-accordion__step--todo';
            $step3Open  = $openStep === 3 ? ' open' : '';
            echo '<details class="mdirector-settings-box"' . esc_attr( $step3Open ) . '>'
                . '<summary class="mdirector-accordion__header">'
                . '<span class="mdirector-accordion__step ' . esc_attr( $step3Class ) . '">3</span>'
                . '<h4>' . esc_html( $deliveriesTitle ) . '</h4>'
                . '<span class="mdirector-accordion__arrow"></span>'
                . '</summary>'
                . '<div class="mdirector-accordion__body mdirector-delivery-body">';
            echo wp_kses( $this->getHTMLStep4(), Mdirector_Newsletter_Utils::allowedHtml() );
            echo '<div class="mdirector-delivery-divider"></div>';
            echo wp_kses( $this->getHTMLStep5(), Mdirector_Newsletter_Utils::allowedHtml() );
            echo '</div></details>';

            echo wp_kses( $this->getHTMLStep6( $openStep === 4, $configured[4] ), Mdirector_Newsletter_Utils::allowedHtml() );
            echo wp_kses( $this->getHTMLStep7( $openStep === 5, $configured[5] ), Mdirector_Newsletter_Utils::allowedHtml() );
            echo wp_kses( $this->getHTMLStep8( $openStep === 6, $configured[6] ), Mdirector_Newsletter_Utils::allowedHtml() );
            echo wp_kses( $this->getHTMLStep9( $openStep === 7, $configured[7] ), Mdirector_Newsletter_Utils::allowedHtml() );
        }

        $templateData = [
            'on' => $on,
            'isPluginConfigured' => $this->isPluginConfigured(),
            'isEmptyTestLists' => empty($test_lists)
        ];

        echo wp_kses( $this->adminTemplate->renderBlock( 'submitForm', $templateData ), Mdirector_Newsletter_Utils::allowedHtml() );
    }

    /**
     * Verifica si hay al menos una campaña (semanal o diaria) configurada.
     */
    private function mdStepHasCampaigns(array $options): bool
    {
        $prefixes = [
            Mdirector_Newsletter_Utils::MDIRECTOR_WEEKLY_CAMPAIGN,
            Mdirector_Newsletter_Utils::MDIRECTOR_DAILY_CAMPAIGN,
        ];
        foreach ($options as $key => $value) {
            foreach ($prefixes as $prefix) {
                if (strpos($key, $prefix) === 0 && !empty($value)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * @return string
     * @throws Throwable
     */
    private function getWPMLCompatibilityTemplate()
    {
        return $this->adminTemplate->renderBlock(
            'wpmlCompatibility',
            ['assets' => self::ASSETS_PATH]
        );
    }

    /**
     * @return string
     * @throws Throwable
     */
    private function getHTMLStep1(bool $isOpen = true, bool $isConfigured = false)
    {
        $templateData = [
            'bearerToken'    => $this->bearerToken,
            'stepOpen'       => $isOpen,
            'stepConfigured' => $isConfigured,
        ];

        return $this->adminTemplate->renderBlock('firstStep', $templateData);
    }

    /**
     * @return string
     * @throws Throwable
     */
    private function getHTMLStep2(bool $isOpen = false, bool $isConfigured = false)
    {
        $headerCampaignsTable = $this->adminTemplate->renderBlock('headerListsCampaignsTable', [
            'elementTitle' => 'STEP-2__CAMPAIGNS'
        ]);

        $headerListsTable = $this->adminTemplate->renderBlock('headerListsCampaignsTable', [
            'elementTitle' => 'STEP-2__LISTS'
        ]);

        $selectedDailyLists = $this->MDirectorUtils->getSelectedUserListsByLanguageHTML(
            Mdirector_Newsletter_Utils::DAILY_FREQUENCY
        );
        $selectedWeeklyLists = $this->MDirectorUtils->getSelectedUserListsByLanguageHTML(
            Mdirector_Newsletter_Utils::WEEKLY_FREQUENCY
        );

        $weeklyCampaigns = $this->MDirectorUtils->getWeeklyCampaignsByLanguageHTML();
        $dailyCampaigns = $this->MDirectorUtils->getDailyCampaignsByLanguageHTML();

        $templateCampaignsData = [
            'headerCampaignsTable' => $headerCampaignsTable,
            'weeklyCampaigns' => $weeklyCampaigns,
            'dailyCampaigns' => $dailyCampaigns,
        ];

        $campaignsBlock = $this->adminTemplate->renderBlock('campaignsBlock', $templateCampaignsData);

        $templateData = [
            'on' => Mdirector_Newsletter_Utils:: SETTINGS_OPTION_ON,
            'headerListsTable' => $headerListsTable,
            'selectedDailyLists' => $selectedDailyLists,
            'selectedWeeklyLists' => $selectedWeeklyLists,
            'campaignsBlock' => $campaignsBlock,
            'stepOpen'       => $isOpen,
            'stepConfigured' => $isConfigured,
        ];

        return $this->adminTemplate->renderBlock('secondStep', $templateData);
    }

    /**
     * @return string
     * @throws Throwable
     */
    private function getHTMLStep4()
    {
        $options = $this->MDirectorUtils->getPluginOptions();
        $optionsSubjectWeeklyDynamic = $this->buildSubjectWeeklyDynamic();
        $typeWeekly = $this->getOption('mdirector_subject_type_weekly');

        $templateData = [
            'on' => Mdirector_Newsletter_Utils::SETTINGS_OPTION_ON,
            'typeWeekly' => $typeWeekly,
            'fixedSubject' => Mdirector_Newsletter_Utils::FIXED_SUBJECT,
            'blogName' => get_bloginfo('name'),
            'frequencyWeeklyChecked' => ($options['mdirector_frequency_weekly']
                ===
                Mdirector_Newsletter_Utils::SETTINGS_OPTION_ON) ? 'checked'
                : '',
            'fixedSubjects' => $this->getHTMLFixedSubjects(Mdirector_Newsletter_Utils::WEEKLY_FREQUENCY),
            'dynamicSubject' => Mdirector_Newsletter_Utils::DYNAMIC_SUBJECT,
            'isSubjectDynamic' => $typeWeekly
                === Mdirector_Newsletter_Utils::DYNAMIC_SUBJECT,
            'dynamicSubjects' => $this->getHTMLDynamicSubjects(Mdirector_Newsletter_Utils::WEEKLY_FREQUENCY),
            'optionsSubjectWeeklyDynamic' => $optionsSubjectWeeklyDynamic,
            'optionsDays' => $this->buildOptionsForDays(),
            'hourWeekly' => $this->getOption('mdirector_hour_weekly'),
            'sendersDropdownWeekly' => $this->MDirectorUtils->getSendersDropdownHTML('weekly')
        ];

        return $this->adminTemplate->renderBlock('fourthStep', $templateData);
    }

    /**
     * @return string
     * @throws Throwable
     */
    private function buildSubjectWeeklyDynamic()
    {
        $optionsSubjectWeeklyDynamic = '';
        $subjectWeekly = $this->getOption('mdirector_subject_dynamic_value_weekly');

        foreach ($this->dynamicSubjectValues as $key => $value) {
            $templateData = [
                'key' => $key,
                'value' => $value,
                'isSelected' => $subjectWeekly === strval($key)
            ];
            $optionsSubjectWeeklyDynamic .= $this->adminTemplate->renderBlock(
                'buildOption',
                $templateData
            );
        }

        return $optionsSubjectWeeklyDynamic;
    }

    /**
     * @param $frequency
     *
     * @return string
     * @throws Throwable
     */
    private function getHTMLFixedSubjects($frequency)
    {
        $output = '';

        foreach ($this->currentLanguages as $lang => $data) {
            $input_name = 'mdirector_subject_' . $frequency . '_' . $lang;
            $subject = $this->getOption('mdirector_subject_type_' . $frequency);

            $templateData = [
                'langName' => $data['translated_name'],
                'inputName' => $input_name,
                'subject' => $subject,
                'subjectValue' => $this->getOption($input_name),
                'readOnly' => $subject
                    !== Mdirector_Newsletter_Utils::FIXED_SUBJECT
            ];

            $output .= $this->adminTemplate->renderBlock(
                'fixedSubjects',
                $templateData
            );
        }

        return $output;
    }

    /**
     * @param $frequency
     *
     * @return string
     * @throws Throwable
     */
    private function getHTMLDynamicSubjects($frequency)
    {
        $output = '';

        foreach ($this->currentLanguages as $lang => $data) {
            $inputName =
                'mdirector_subject_dynamic_prefix_' . $frequency . '_' . $lang;
            $subjectType = $this->getOption('mdirector_subject_type_' . $frequency);

            $templateData = [
                'langName' => $data['translated_name'],
                'inputName' => $inputName,
                'subjectType' => $subjectType,
                'subjectValue' => $this->getOption($inputName),
                'readonly' => $subjectType
                    === Mdirector_Newsletter_Utils::FIXED_SUBJECT
            ];

            $output .= $this->adminTemplate->renderBlock(
                'dynamicSubjects',
                $templateData
            );
        }

        return $output;
    }

    /**
     * @return string
     * @throws Throwable
     */
    private function buildOptionsForDays()
    {
        $optionsDays = '';
        $day = $this->getOption('mdirector_frequency_day');

        foreach ($this->frequencyDays as $key => $value) {
            $templateData = [
                'key' => $key,
                'value' => $value,
                'isSelected' => $day === strval($key)
            ];
            $optionsDays .= $this->adminTemplate->renderBlock(
                'buildOption',
                $templateData
            );
        }

        return $optionsDays;
    }

    /**
     * @return string
     * @throws Throwable
     */
    private function getHTMLStep5()
    {
        $options = $this->MDirectorUtils->getPluginOptions();

        $subjectType = $this->getOption('mdirector_subject_type_daily');

        $templateData = [
            'on' => Mdirector_Newsletter_Utils::SETTINGS_OPTION_ON,
            'mdirectorFrequencyDaily' => $options['mdirector_frequency_daily'],
            'subjectType' => $subjectType,
            'fixedSubject' => Mdirector_Newsletter_Utils::FIXED_SUBJECT,
            'dynamicSubject' => Mdirector_Newsletter_Utils::DYNAMIC_SUBJECT,
            'fixedDailySubjects' => $this->getHTMLFixedSubjects(Mdirector_Newsletter_Utils::DAILY_FREQUENCY),
            'blogName' => get_bloginfo('name'),
            'isSubjectDynamic' => $subjectType
                === Mdirector_Newsletter_Utils::DYNAMIC_SUBJECT,
            'dynamicDailySubjects' => $this->getHTMLDynamicSubjects(Mdirector_Newsletter_Utils::DAILY_FREQUENCY),
            'optionsSubjectDailyDynamic' => $this->buildSubjectDailyDynamic(),
            'weekdaySelectorHTML' => $this->buildWeekdaySelectorHTML(),
            'hour' => $this->getOption('mdirector_hour_daily'),
            'sendersDropdownDaily' => $this->MDirectorUtils->getSendersDropdownHTML('daily')
        ];

        return $this->adminTemplate->renderBlock('fifthStep', $templateData);
    }

    /**
     * @return string
     * @throws Throwable
     */
    private function buildSubjectDailyDynamic()
    {
        $optionsSubjectDailyDynamic = '';
        $subjectValue = $this->getOption('mdirector_subject_dynamic_value_daily');

        foreach ($this->dynamicSubjectValues as $key => $value) {
            $templateData = [
                'key' => $key,
                'value' => $value,
                'isSelected' => $subjectValue === strval($key)
            ];
            $optionsSubjectDailyDynamic .= $this->adminTemplate->renderBlock(
                'buildOption',
                $templateData
            );
        }

        return $optionsSubjectDailyDynamic;
    }

    /**
     * @return string
     * @throws Throwable
     */
    private function buildWeekdaySelectorHTML()
    {
        $options = $this->MDirectorUtils->getPluginOptions();
        $weekDays = $this->getWeekdaySelectorArray();

        $html = '';

        foreach ($weekDays as $day => $longName) {
            $fieldName =
                Mdirector_Newsletter_Utils::DAILY_WEEKS_ALLOWED_PREFIX . $day;
            $templateData = [
                'on' => Mdirector_Newsletter_Utils::SETTINGS_OPTION_ON,
                'fieldName' => $fieldName,
                'longNameLabel' => 'WEEKDAY__' . $longName,
                'longNameShortcutLabel' => 'WEEKDAY__' . $longName . '-SHORT',
                'isChecked' => $options[$fieldName]
                    == Mdirector_Newsletter_Utils::SETTINGS_OPTION_ON
            ];

            $html .= $this->adminTemplate->renderBlock(
                'weekDaySelector',
                $templateData
            );
        }

        return $html;
    }

    /**
     * @return string
     * @throws Throwable
     */
    private function getHTMLStep6(bool $isOpen = false, bool $isConfigured = true)
    {
        $options = $this->MDirectorUtils->getPluginOptions();
        $excludeCategories = isset($options['exclude_categories'])
            && $options['exclude_categories']
            === Mdirector_Newsletter_Utils::SETTINGS_OPTION_ON;

        $templateData = [
            'excludeCategories' => $excludeCategories,
            'categories'        => $this->mdirectorGetCategories($options['mdirector_exclude_cats']),
            'stepOpen'          => $isOpen,
            'stepConfigured'    => $isConfigured,
        ];

        return $this->adminTemplate->renderBlock('sixthStep', $templateData);
    }

    /**
     * @param null $selected
     *
     * @return string
     * @throws Throwable
     */
    public function mdirectorGetCategories($selected = null)
    {
        $selected = $selected ? unserialize($selected) : [];

        $cat_args = ['parent' => 0, 'hide_empty' => false];
        $parentCategories = get_categories($cat_args);

        if (empty(count($parentCategories))) {
            return false;
        }

        $categories = '';

        foreach ($parentCategories as $parentCategory) {
            $categories .= $this->buildCategoriesHTML(
                $parentCategory,
                $selected
            );
            $categories .= $this->buildSubcategoriesHTML(
                $parentCategory,
                $selected
            );
        }

        return $categories;
    }

    /**
     * @param $parentCategory
     * @param $selected
     *
     * @return string
     * @throws Throwable
     */
    private function buildCategoriesHTML($parentCategory, $selected)
    {
        $templateData = [
            'parentCategory' => $parentCategory,
            'isSelected' => in_array($parentCategory->term_id, $selected)
        ];

        return $this->adminTemplate->renderBlock(
            'categoryOption',
            $templateData
        );
    }

    /**
     * @param $parentCategory
     * @param $selected
     *
     * @return string
     * @throws Throwable
     */
    private function buildSubcategoriesHTML($parentCategory, $selected)
    {
        $subcategories = '';
        $terms = get_categories([
            'child_of' => $parentCategory->term_id,
            'hide_empty' => false
        ]);

        foreach ($terms as $term) {
            $templateData = [
                'extraIndent' => ($term->parent != $parentCategory->term_id),
                'term' => $term,
                'isChecked' => in_array($term->term_id, $selected)
            ];

            $subcategories .= $this->adminTemplate->renderBlock(
                'subcategoryOption',
                $templateData
            );
        }

        return $subcategories;
    }

    /**
     * @return string
     * @throws Throwable
     */
    private function getHTMLStep7(bool $isOpen = false, bool $isConfigured = true)
    {
        $templateData = [
            'privacyPolicy'  => $this->getHTMLForPrivacyPolicy(),
            'stepOpen'       => $isOpen,
            'stepConfigured' => $isConfigured,
        ];

        return $this->adminTemplate->renderBlock('seventhBlock', $templateData);
    }

    /**
     * @return string
     * @throws Throwable
     */
    private function getHTMLForPrivacyPolicy()
    {
        $output = '';
        $type = 'policy';

        foreach ($this->currentLanguages as $lang => $data) {
            $field_name = 'mdirector_' . $type . '_';
            $active_field = $field_name . $lang . '_active';
            $current_text = $field_name . 'text_' . $lang;
            $current_url = $field_name . 'url_' . $lang;
            $active_field_value = $this->getOption($active_field);

            $templateData = [
                'langName' => $data['translated_name'],
                'fieldName' => $field_name,
                'activeField' => $active_field,
                'currentText' => $current_text,
                'currentUrl' => $current_url,
                'currentTextValue' => $this->getOption($current_text),
                'currentUrlValue' => $this->getOption($current_url),
                'activeFieldValue' => $active_field_value,
                'on' => Mdirector_Newsletter_Utils:: SETTINGS_OPTION_ON,
                'checked' => $active_field_value ===
                    Mdirector_Newsletter_Utils::SETTINGS_OPTION_ON
            ];

            $output .= $this->adminTemplate->renderBlock(
                'privacyPolicy',
                $templateData
            );
        }

        return $output;
    }

    /**
     * @return string
     * @throws Throwable
     */
    private function getHTMLStep8(bool $isOpen = false, bool $isConfigured = true)
    {
        $minimumEntries = $this->getOption('mdirector_minimum_entries');

        $output = $this->adminTemplate->renderBlock('eighthStep', [
            'stepOpen'       => $isOpen,
            'stepConfigured' => $isConfigured,
        ]);

        if ($this->MDirectorUtils->isWPML()) {
            $templateData = [
                'currentLanguages' => $this->currentLanguages,
                'templateOptions' => $this->generateAllTemplateOptions()
            ];

            $output .= $this->adminTemplate->renderBlock(
                'templatesForWPML',
                $templateData
            );

        } else {
            $templateData = [
                'templateOptions' => $this->generateTemplateOptions()
            ];

            $output .= $this->adminTemplate->renderBlock(
                'templatesWithoutWPML',
                $templateData
            );
        }

        $output .= $this->adminTemplate->renderBlock(
            'eighthStepBottom',
            [
                'minimumEntries' => $minimumEntries,
                'templatePreview' => self::TEMPLATE_PREVIEW
            ]
        );

        return $output;
    }

    private function generateAllTemplateOptions()
    {
        $output = [];

        foreach ($this->currentLanguages as $lang) {
            $output[$lang['code']] = $this->generateTemplateOptions($lang);
        }

        return $output;
    }

    private function generateTemplateOptions($lang = null)
    {
        $availableTemplates = $this->MDirectorUtils->getPluginTemplates();

        $currentTemplateSelected =
            $this->MDirectorUtils->getCurrentTemplate(
                $availableTemplates,
                $lang
            );

        return $this->MDirectorUtils->getTemplateOptionsHTML($availableTemplates, $currentTemplateSelected);
    }

    /**
     * @return string
     * @throws Throwable
     */
    private function getHTMLStep9(bool $isOpen = false, bool $isConfigured = true)
    {
        $templateData = [
            'lastDailySendRaw'  => $this->getOption('mdirector_daily_sent'),
            'lastWeeklySendRaw' => $this->getOption('mdirector_weekly_sent'),
            'lastDailySend'     => $this->getLastDateSend(Mdirector_Newsletter_Utils::DAILY_FREQUENCY),
            'lastWeeklySend'    => $this->getLastDateSend(Mdirector_Newsletter_Utils::WEEKLY_FREQUENCY),
            'stepOpen'          => $isOpen,
            'stepConfigured'    => $isConfigured,
        ];

        return $this->adminTemplate->renderBlock('ninethStep', $templateData);
    }

    private function getLastDateSend($frequency)
    {
        $dateSent = $this->getOption('mdirector_' . $frequency . '_sent');

        if ($lastDate = $dateSent) {
            return gmdate( 'd-m-Y, H:i', strtotime( $lastDate ) );
        }

        return self::NO_VALUE;
    }

    /**
     * @throws Throwable
     */
    public function mdTabContentLogs()
    {
        $options = $this->MDirectorUtils->getPluginOptions();
        $logs = '';

        foreach (glob(MDIRECTOR_LOGS_PATH . '*') as $file) {
            $logs .= basename($file) . "\n";
            $logs .= "---------------------------\n";
            $logs .= file_get_contents($file);
            $logs .= "\n\n\n";
        }

        $templateData = [
            'logsContent' => $logs,
            'on' => Mdirector_Newsletter_Utils::SETTINGS_OPTION_ON,
            'mdirectorLogsDeactivated' => isset($options['mdirector_logs_deactivated'])
                ? $options['mdirector_logs_deactivated']
                : false,
        ];

        echo wp_kses( $this->adminTemplate->renderBlock( 'logsTab', $templateData ), Mdirector_Newsletter_Utils::allowedHtml() );
    }

    /**
     * @throws Throwable
     */
    public function mdTabContentHelp()
    {
        echo wp_kses( $this->adminTemplate->renderBlock(
            'help',
            ['assets' => self::ASSETS_PATH]
        ), Mdirector_Newsletter_Utils::allowedHtml() );
    }

    /**
     * @throws Throwable
     */
    public function mdTabContentWelcome()
    {
        echo wp_kses( $this->adminTemplate->renderBlock(
            'welcome',
            ['assets' => self::ASSETS_PATH]
        ), Mdirector_Newsletter_Utils::allowedHtml() );
    }

    /**
     * @throws Throwable
     */
    public function mdTabContentAdvance()
    {
        $options = $this->MDirectorUtils->getPluginOptions();

        $templateData = [
            'on' => Mdirector_Newsletter_Utils::SETTINGS_OPTION_ON,
            'mdirectorHideSampleTemplates' => isset($options['mdirector_hide_sample_templates'])
                ? $options['mdirector_hide_sample_templates']
                : false,
            'mdirectorSchedulerTaxonomies' => isset($options['mdirector_scheduler_taxonomies'])
                ? $options['mdirector_scheduler_taxonomies']
                : '',
            'mdirectorSchedulerPosts' => isset($options['mdirector_scheduler_posts'])
                ? $options['mdirector_scheduler_posts']
                : '',
            'mdirectorSchedulerDefaultFromName' => isset($options['mdirector_scheduler_default_from_name'])
                ? $options['mdirector_scheduler_default_from_name']
                : '',
            'mdirectorLogsDeactivated' => isset($options['mdirector_logs_deactivated'])
                ? $options['mdirector_logs_deactivated']
                : false,
            'mdirectorVersion' => MDIRECTOR_NEWSLETTER_VERSION
        ];

        echo wp_kses( $this->adminTemplate->renderBlock( 'advanceTab', $templateData ), Mdirector_Newsletter_Utils::allowedHtml() );
    }

    /**
     * @throws Throwable
     */
    public function mdTabContentTests()
    {
        $options = $this->MDirectorUtils->getPluginOptions();

        $headerCampaignsTable = $this->adminTemplate->renderBlock('headerListsCampaignsTable', [
            'elementTitle' => 'STEP-2__CAMPAIGNS'
        ]);

        $headerListsTable = $this->adminTemplate->renderBlock('headerListsCampaignsTable', [
            'elementTitle' => 'STEP-2__LISTS'
        ]);

        $selectedDailyLists = $this->MDirectorUtils->getSelectedUserListsByLanguageHTML(
            Mdirector_Newsletter_Utils::DAILY_FREQUENCY, self::TEST_FLAG
        );
        $selectedWeeklyLists = $this->MDirectorUtils->getSelectedUserListsByLanguageHTML(
            Mdirector_Newsletter_Utils::WEEKLY_FREQUENCY, self::TEST_FLAG
        );

        $weeklyCampaigns = $this->MDirectorUtils->getWeeklyCampaignsTestsHTML();
        $dailyCampaigns = $this->MDirectorUtils->getDailyCampaignsTestsHTML();

        if ($this->MDirectorUtils->isWPML()) {
            echo wp_kses( $this->getWPMLCompatibilityTemplate(), Mdirector_Newsletter_Utils::allowedHtml() );
        }

        $templateCampaignsData = [
            'headerCampaignsTable' => $headerCampaignsTable,
            'weeklyCampaigns' => $weeklyCampaigns,
            'dailyCampaigns' => $dailyCampaigns,
        ];

        $campaignsBlock = $this->adminTemplate->renderBlock('campaignsBlock', $templateCampaignsData);

        $templateData = [
            'on' => Mdirector_Newsletter_Utils:: SETTINGS_OPTION_ON,
            'mdirectorUseTestLists' => isset($options['mdirector_use_test_lists'])
                ? $options['mdirector_use_test_lists']
                : false,
            'headerListsTable' => $headerListsTable,
            'selectedDailyLists' => $selectedDailyLists,
            'selectedWeeklyLists' => $selectedWeeklyLists,
            'campaignsBlock' => $campaignsBlock,
            'testGroupsDropdown' => $this->MDirectorUtils->getTestGroupsDropdownHTML()
        ];

        echo wp_kses( $this->adminTemplate->renderBlock( 'testsTab', $templateData ), Mdirector_Newsletter_Utils::allowedHtml() );
    }

    /**
     * Register the stylesheets for the admin area.
     *
     * @since    1.0.0
     */
    public function enqueueStyles()
    {
        wp_enqueue_style(
            $this->MDirectorNewsletter,
            MDIRECTOR_NEWSLETTER_PLUGIN_URL
            . 'admin/css/mdirector-newsletter-admin.css?v=' . time(), [],
            $this->version, 'all'
        );
    }

    /**
     * Register the JavaScript for the admin area.
     *
     * @since    1.0.0
     */
    public function enqueueScripts()
    {
        wp_register_style(
            'mdirector-select2',
            MDIRECTOR_NEWSLETTER_PLUGIN_URL . 'admin/css/select2.min.css',
            [],
            '4.1.0-rc.0'
        );
        wp_enqueue_style('mdirector-select2');

        wp_register_script(
            'mdirector-select2',
            MDIRECTOR_NEWSLETTER_PLUGIN_URL . 'admin/js/select2.min.js',
            ['jquery'],
            '4.1.0-rc.0',
            true
        );
        wp_enqueue_script('mdirector-select2');

        wp_register_script(
            'timepicker', MDIRECTOR_NEWSLETTER_PLUGIN_URL .
            'admin/js/timepicker.js', ['jquery'],
            MDIRECTOR_NEWSLETTER_VERSION, true
        );
        wp_enqueue_script('timepicker');
        wp_register_script(
            'mdirector-admin', MDIRECTOR_NEWSLETTER_PLUGIN_URL .
            'admin/js/mdirector-newsletter-admin.js', ['jquery', 'mdirector-select2'],
            MDIRECTOR_NEWSLETTER_VERSION, true
        );

        wp_enqueue_script('mdirector-admin');
    }

    private function getListsIds($type, $suffix = '')
    {
        $options = $this->MDirectorUtils->getPluginOptions();

        $target_list = 'mdirector' . self::SETTINGS_SEPARATOR .
            $type . self::SETTINGS_SEPARATOR;

        $prefix = $target_list .
            ($suffix ? $suffix . self::SETTINGS_SEPARATOR : '') . 'list' .
            self::SETTINGS_SEPARATOR;

        $lists = [];

        foreach ($this->currentLanguages as $language) {
            $lang = $language['code'];

            $lists[$lang] = [
                'origin' => $prefix . $lang,
                'campaign_id_string' => $campaignId,
                'translated_name' => $language['translated_name'],
                'value' => $options[$prefix . $lang] ?? null
            ];
        }

        return $lists;
    }

    /**
     * @param $lists
     * @param $default_lists
     * @param $type
     *
     * @return string
     * @throws Throwable
     */
    private function getHTMLUsedLists($lists, $default_lists, $type)
    {
        $output = '';

        foreach ($lists as $lang => $data) {
            $id = $data['value'];
            $inputName = 'mdirector_' . $type . '_list_' . $lang;
            $activeField = $inputName . '_active';

            $templateData = [
                'on' => Mdirector_Newsletter_Utils::SETTINGS_OPTION_ON,
                'langName' => $data['translated_name'],
                'defaultList' => $default_lists[$lang]['value'],
                'selectedId' => $id ? $id : $default_lists[$lang]['value'],
                'inputName' => $inputName,
                'activeField' => $activeField,
                'activeFieldValue' => $this->getOption($activeField),
                'placeholder' => 'ID'
            ];

            $output .= $this->adminTemplate->renderBlock(
                'htmlUsedLists',
                $templateData
            );
        }

        return $output;
    }
}
