<?php

namespace SEOAIC;

use DateTime;
use DateTimeZone;
use Exception;
use SEOAIC\last_used_prompts\PostsMassGenerateLastUsedPrompts;
use SEOAIC\loaders\PostsEditLoader;
use SEOAIC\loaders\PostsGenerationLoader;
use SEOAIC\loaders\PostsReviewLoader;
use SEOAIC\posts_mass_actions\PostsMassEdit;
use SEOAIC\posts_mass_actions\PostsMassReview;
use SEOAIC\posts_mass_actions\PostsMassTranslate;
use SEOAIC\relations\KeywordsPostsRelation;
use SEOAIC\SEOAIC;
use SEOAIC\SEOAICAjaxResponse;
use SEOAIC\SEOAIC_IDEAS;
use SEOAIC\content_editor_blocks\providers\SEOAICBlocks;
use SEOAIC\helpers\FormHelpers;
use SEOAIC\helpers\SEOPluginsHelper;
use SEOAIC\helpers\Utils;
use SEOAIC\patterns\LeadsFormPattern;
use SEOAIC\posts_mass_actions\FAQGenerate;
use SEOAIC\posts_mass_actions\LeadsFormGenerate;
use SEOAIC\posts_mass_actions\ThumbnailsGenerate;
use SEOAIC\pruning_integration\GoogleSearchConsole;
use SEOAIC\repositories\InteractiveArticleAddonRepository;
use SEOAIC\repositories\PostRepository;
use SEOAIC\repositories\PostRevisionRepository;
use SeoaicAjaxValidation;
use WP_Query;

class SEOAIC_POSTS
{
    public const DEBUG_CLASS = true;
    public const SUBTITLES_MIN = 0;
    public const SUBTITLES_MAX = 6;
    public const WORDS_MIN = 0;
    public const WORDS_MAX = 1000;
    public const PER_REQUEST__GENERATE = 10;
    public const PER_REQUEST__GENERATE_CONTENT = 5;
    public const GENERATE_MODE = 'generate';
    public const EDIT_MODE = 'edit';
    public const POLL_MODES = [self::GENERATE_MODE, self::EDIT_MODE];
    public const WORDS_COUNT_FIELD = 'words_count';
    public const EDIT_STATUS_FIELD = 'seoaic_update_status';
    public const EDIT_STATUS_TIME_FIELD = 'seoaic_update_status_time';
    public const ANY_STATUS = ['publish', 'draft', 'future'];
    public const GENERATE_THUMBNAIL_FIELD = 'generate_thumbnail';
    public const GENERATE_THUMBNAIL_STYLE_FIELD = 'generate_thumbnail_style';
    public const GENERATE_THUMBNAIL_PROMPT_FIELD = 'thumbnail_generation_prompt';
    public const GENERATE_THUMBNAIL_WIDTH = 'thumbnail_generation_width';
    public const GENERATE_THUMBNAIL_HEIGHT = 'thumbnail_generation_height';

    public const MASS_GENERATION_DATA = 'mass_generation_data';

    public const REVISION_POST_TYPE = 'seoaic-post-revision';
    public const REVISION_STATUS = 'draft';
    public const IS_INTERACTIVE_KEY = 'seoaic_interactive';

    private $seoaic;
    protected $postRevisionRepository;

    public function __construct($_seoaic)
    {
        $this->seoaic = $_seoaic;
        $this->postRevisionRepository = new PostRevisionRepository();

        add_action('admin_head', [$this, 'seoaic_admin_head'], 10);
        add_action('init', [$this, 'seoaic_register_post_meta']);
        add_action('init', [new PostsMassEdit($this->seoaic), 'init']);
        add_action('init', [new PostsMassReview($this->seoaic), 'init']);
        add_action('init', [new PostsMassTranslate($this->seoaic), 'init']);
        add_action('init', [new ThumbnailsGenerate($this->seoaic), 'init']);
        add_action('after_delete_post', [$this, 'removeKeywordPostRelation'], 10, 2);
        add_action('after_delete_post', [$this, 'removeInteractiveArticleStats'], 10, 2);

        add_filter('posts_where', [$this, 'title_like_posts_where'], 10, 2);
        add_filter('posts_where', [$this, 'contentLikePostsWhere'], 10, 2);
        add_filter('posts_where', [$this, 'contentNotLikePostsWhere'], 10, 2);
        add_filter('posts_clauses', [$this, 'wpmlParseQueryConditions'], 99, 2);
        add_filter('get_pagenum_link', [$this, 'seoaicWorkaroundGetPagenumLink']);

        add_action('save_post', [$this, 'resetReviewResults'], 10, 2);
        add_action('save_post', [$this, 'resetOnboardingPostData'], 10, 2);
        add_action('save_post', [$this, 'countContentWords'], 10, 2);
        add_action('wp_insert_post', [$this, 'setCreatedDate'], 10, 2);

        // ajax
        add_action('wp_ajax_seoaic_reschedule_posts', [$this, 'reschedule_posts']);
        add_action('wp_ajax_seoaic_schedule_posts', [$this, 'schedule_posts']);
        add_action('wp_ajax_seoaic_regenerate_image', [$this, 'regenerate_image']);
        add_action('wp_ajax_seoaic_publish_post', [$this, 'publish_post']);
        add_action('wp_ajax_seoaic_posts_set_mass_thumbnail', [$this, 'setMassThumbnail']);
        add_action('wp_ajax_seoaic_posts_mass_thumbnails_generate_stop', [$this, 'generateThumbnailStopAjax']);

        add_action('wp_ajax_seoaic_posts_mass_create', [$this, 'postsMassGenerateAjax']);
        add_action('wp_ajax_seoaic_posts_mass_generate_check_status', [$this, 'postsMassGenerateCheckStatusAjax']);
        add_action('wp_ajax_seoaic_posts_mass_generate_check_status_manually', [$this, 'postsMassGenerateCheckStatusManually']);
        add_action('wp_ajax_seoaic_posts_mass_generate_stop', [$this, 'postsMassGenerateStop']);
        add_action('wp_ajax_seoaic_clear_background_option', [$this, 'clearGenerationBackgroundOptionAjax']);

        add_action('wp_ajax_seoaic_posts_mass_edit', [$this, 'postsMassEditAjax']);
        add_action('wp_ajax_seoaic_posts_mass_edit_check_status', [$this, 'postsMassEditCheckStatusAjax']);
        add_action('wp_ajax_seoaic_posts_mass_stop_edit', [$this, 'postsMassEditStopAjax']);
        add_action('wp_ajax_seoaic_clear_edit_background_option', [$this, 'postsMassEditClearBackgroundOption']);

        add_action('wp_ajax_seoaic_posts_mass_review', [$this, 'postsMassReviewAjax']);
        add_action('wp_ajax_seoaic_posts_mass_review_check_status', [$this, 'postsMassReviewCheckStatusAjax']);
        add_action('wp_ajax_seoaic_posts_mass_stop_review', [$this, 'postsMassReviewStopAjax']);
        add_action('wp_ajax_seoaic_clear_review_background_option', [$this, 'postsMassReviewClearBackgroundOption']);

        add_action('wp_ajax_seoaic_posts_mass_translate', [$this, 'postsMassTranslateAjax']);
        add_action('wp_ajax_seoaic_posts_mass_translate_check_status', [$this, 'postsMassTranslateCheckStatusAjax']);
        add_action('wp_ajax_seoaic_posts_mass_translate_stop', [$this, 'postsMassTranslateStopAjax']);

        add_action('wp_ajax_seoaic_mass_posts_edit_undo', [$this, 'postsMassEditUndoAjax']);

        add_action('wp_ajax_seoaic_getCategoriesOfPosttype', [$this, 'getCategoriesOfPosttype']);
        add_action('wp_ajax_seoaic_selectCategoriesIdea', [$this, 'selectCategoriesIdea']);

        add_action('wp_ajax_seoaic_transform_idea', [$this, 'transform_idea']);

        // cron
        add_filter('cron_schedules', [$this, 'add_cron_interval']);
        add_action('seoaic_posts_generate_check_status_cron_hook', [$this, 'cronPostsGenerateCheckStatus']);
        add_action('seoaic_posts_edit_check_status_cron_hook', [$this, 'cronPostsEditCheckStatus']);

        add_action('wp_ajax_seoaic_posts_mass_thumbnails_generate_check_status', [$this, 'postsMassThumbnailsGenerateCheckStatusAjax']);

        add_action('wp_ajax_seoaic_remove_post_to_trash', [$this, 'setPostToTrash']);
        add_action('wp_ajax_seoaic_set_posts_status', [$this, 'setPostsStatusAjax']);
        add_action('wp_ajax_seoaic_update_post_visibility', [$this, 'updatePostsVisibility']);

        add_action('wp_ajax_seoaic_generate_lead_form', [$this, 'generateLeadFormAjax']);
        add_action('wp_ajax_seoaic_generate_lead_form_check_status', [$this, 'generateLeadFormCheckStatusAjax']);
        add_action('wp_ajax_seoaic_generate_lead_form_stop', [$this, 'generateLeadFormStopAjax']);

        add_action('wp_ajax_seoaic_generate_faq', [$this, 'generateFAQAjax']);
        add_action('wp_ajax_seoaic_generate_faq_check_status', [$this, 'generateFAQAjaxCheckStatus']);
        add_action('wp_ajax_seoaic_generate_faq_stop', [$this, 'generateFAQAjaxStop']);
    }

    public function wpmlParseQueryConditions($clauses, $query) {
        $args = $query->query;
        // Ensure wpml_translations is included in the query
        if (strpos($clauses['where'], 'wpml_translations.language_code') !== false
            && !empty($args['seoai_lang']) && $args['seoai_lang'] === 'all') {
            // Modify condition to exclude empty language codes
            $clauses['where'] = preg_replace(
                "/wpml_translations\.language_code\s*=\s*['\"]\w+['\"]/",
                "wpml_translations.language_code != ''",
                $clauses['where']
            );
        }

        return $clauses;
    }

    /**
     * Writes logs with details like class name and caller function. Uses print_r function for parameters. Keeps the last N lines.
     */
    public function debugLog(...$args)
    {
        if (self::DEBUG_CLASS) {
            $argsString = '';
            $maxLines = 3000;
            $fileName = SEOAIC_LOG . 'mass_posts_debug.txt';

            $argsPrintedArray = array_map(function ($item) {
                return print_r($item, true);
            }, $args);
            $argsString = implode(' -- ', $argsPrintedArray);

            $func_name = debug_backtrace()[1]['function'];
            $str = '[' . wp_date('Y-m-d H:i:s') . '] ' . __CLASS__ . ' -> ' . $func_name . '(): ' . $argsString . "\r\n";

            // remove old lines, and write a new one to the end
            if (!file_exists($fileName)) {
                $file = [];
            } else {
                $file = file($fileName);
                $file = array_slice($file, count($file) - $maxLines);
            }
            array_push($file, $str);
            @file_put_contents($fileName, implode('', $file));
        }
    }

    public function removeKeywordPostRelation($post_id, $post)
    {
        if (SEOAIC_SETTINGS::getSEOAICPostType() !== $post->post_type) {
            return;
        }

        KeywordsPostsRelation::deleteByPostID($post_id);
    }

    public function removeInteractiveArticleStats($postId, $post)
    {
        if (SEOAIC_SETTINGS::getSEOAICPostType() !== $post->post_type) {
            return;
        }

        $interactiveArticleAddonRepository = new InteractiveArticleAddonRepository();
        $interactiveArticleAddonRepository->deleteByPostId(intval($postId));
    }

    private function unregisterPostsCheckStatusCron($mode = '')
    {
        if (
            !empty($mode)
            && in_array($mode, self::POLL_MODES)
        ) {
            $methodName = 'unregisterPosts' . ucfirst($mode) . 'CheckStatusCron';
            if (method_exists($this, $methodName)) {
                $this->$methodName();
            }
        }
    }

    private function startBackendPolling($mode = '')
    {
        $startPollingMethod = 'start' . ucfirst($mode) . 'Progress';
        if (
            in_array($mode, self::POLL_MODES)
            && method_exists($this, $startPollingMethod)
        ) {
            $this->$startPollingMethod();
        } else {
            $this->debugLog('method not found: ' . $startPollingMethod);
        }

        $cronMethod = 'registerPosts' . ucfirst($mode)  . 'CheckStatusCron';
        if (method_exists($this, $cronMethod)) {
            $this->$cronMethod();
        }
    }

    public function isProcessingInProgress($mode = '')
    {
        $isInProgressMethod = 'is' . ucfirst($mode) . 'InProgress';
        if (
            in_array($mode, self::POLL_MODES)
            && method_exists($this, $isInProgressMethod)
        ) {
            return $this->$isInProgressMethod();
        }

        return false;
    }


    private function startGenerateProgress()
    {
        update_option('seoaic_mass_content_generate', '1');
    }

    private function stopGenerateProgress()
    {
        update_option('seoaic_mass_content_generate', '0');
        $this->unregisterPostsCheckStatusCron(self::GENERATE_MODE);
    }

    public function isGenerateInProgress()
    {
        return '1' == get_option('seoaic_mass_content_generate');
    }

    private function massGenerateCheckingStatusLock()
    {
        $this->debugLog('lock');
        update_option('seoaic_mass_generate_checking_lock', '1');
    }

    private function massGenerateCheckingStatusUnLock()
    {
        $this->debugLog('unlock');
        update_option('seoaic_mass_generate_checking_lock', '0');
    }

    private function isMassGenerateCheckingStatusLocked()
    {
        return '1' == get_option('seoaic_mass_generate_checking_lock');
    }

    public function transform_idea()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        ini_set('display_errors', 1);
        ini_set('display_startup_errors', 1);
        error_reporting(E_ALL);

        $id = intval($_REQUEST['item_id']);

        $post_data = [
            'ID' => $id,
            'post_type' => 'post',
            'post_date' => date('Y-m-d H:i:s'),
            'post_date_gmt' => gmdate('Y-m-d H:i:s'),
            'post_status' => 'publish'
        ];

        $wpml_idea_settings = $this->seoaic->multilang->get_wpml_idea_settings($id, 'post');

        wp_update_post($post_data);

        if (false !== $wpml_idea_settings) {
            $this->seoaic->multilang->set_wpml_idea_settings($id, $wpml_idea_settings);
        }

        SEOAICAjaxResponse::alert('Idea transformed!')->wpSend();
    }

    /**
     * Add post ID to editor
     */
    public function seoaic_admin_head()
    {
        if (isset($_GET['post'])) {
            echo '<link class="seoaic-home-url" href="' . esc_url(get_bloginfo('url')) . '"/>';

            $P = $_GET['post'];
            $SGD = $P ? get_post_meta($P, 'seoaic_generate_description', true) : '';
            $post = $SGD ?? '';
            echo $post ? '<link id="seoaic-promt-key" href="#" data-key="' . esc_attr($post) . '">' : '';
        }
    }

    /**
     * @return void
     */
    public function reschedule_posts($selected_posts = null, $reschedule_date = null, $status = null) {
        $post = wp_unslash($_POST);
        $raw_selected_posts = $post['selected_posts'] ?? $selected_posts ?? '';

        if (empty($raw_selected_posts)) {
            return;
        }
        $auto_schedule = !empty($post['seoai_auto_schedule']);
        $post_ids = array_map('intval', explode(',', sanitize_text_field($raw_selected_posts)));
        $new_status = $status ?? ($auto_schedule ? 'draft' : sanitize_text_field($post['new_status'] ?? 'draft'));
        $reschedule_posting_date_raw = sanitize_text_field($post['reschedule_posting_date_UTC'] ?? $reschedule_date ?? '');
        $current_time = current_time('mysql');
        $current_time_gmt = current_time('mysql', 1);
        $skipped_posts_count = 0;
        $success_posts_count = 0;

        $reschedule_posting_date_local = null;
        $reschedule_posting_date_gmt = null;

        if (!empty($reschedule_posting_date_raw)) {
            try {
                $datetime_utc = new DateTime($reschedule_posting_date_raw, new DateTimeZone('UTC'));
                $datetime_local = clone $datetime_utc;
                $datetime_local->setTimezone(wp_timezone());
                $reschedule_posting_date_local = $datetime_local->format('Y-m-d H:i:s');
                $reschedule_posting_date_gmt = $datetime_utc->format('Y-m-d H:i:s');
            } catch (Exception $e) {
                error_log("Reschedule error Invalid date provided: $reschedule_posting_date_raw");
            }
        }

        if ($auto_schedule) {
            SEOAIC_SETTINGS::setup_auto_publish_cron();
        }

        foreach ($post_ids as $post_id) {
            $current_post = get_post($post_id);
            if (!$current_post) {
                continue;
            }

            $current_status = $current_post->post_status;

            if ($auto_schedule) {
                if ($current_status !== 'publish') {
                    wp_update_post([
                        'ID' => $post_id,
                        'post_status' => 'draft',
                        'post_date' => $current_time,
                        'post_date_gmt' => $current_time_gmt,
                        'post_modified' => $current_time,
                        'post_modified_gmt' => $current_time_gmt,
                        'edit_date' => true,
                    ]);
                    update_post_meta($post_id, 'seoaic_auto_scheduled', '1');
                    $success_posts_count++;
                } else {
                    $skipped_posts_count++;
                }
                continue;
            }

            if ($new_status === 'future' && $current_status === 'publish' && empty($post['no_confirm'])) {
                $skipped_posts_count++;
                continue;
            }

            $post_data = [
                'ID' => $post_id,
                'post_status' => $new_status,
                'post_modified' => $current_time,
                'post_modified_gmt' => $current_time_gmt,
                'post_date' => $reschedule_posting_date_local,
                'post_date_gmt' => $reschedule_posting_date_gmt,
                'edit_date' => true,
            ];

            wp_update_post($post_data);
            delete_post_meta($post_id, 'seoaic_auto_scheduled');
            delete_post_meta($post_id, 'seoaic_ob_needs_review');
            delete_post_meta($post_id, 'seoaic_ob_posting_date');

            $success_posts_count++;
        }

        if (!empty($post['no_confirm'])) {
            return;
        }

        $messages = [];
        if ($success_posts_count) {
            $messages[] = sprintf(esc_html__('%d posts successfully updated.', 'seoaic'), $success_posts_count);
        }
        if ($skipped_posts_count) {
            $messages[] = sprintf(esc_html__('%d posts cannot be scheduled as they have already been published. Make it draft first.', 'seoaic'), $skipped_posts_count);
        }

        if ($messages) {
            SEOAICAjaxResponse::alert(implode('<br><br>', $messages))->wpSend();
        }
    }

    /**
     * Schedule posts generating and publishing
     */
    public function schedule_posts()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        global $SEOAIC_OPTIONS;

        if (empty($SEOAIC_OPTIONS['seoaic_schedule_days'])) {
            SEOAICAjaxResponse::error('Set posting schedule in the Settings page first!')->wpSend();
        }

        $days = $SEOAIC_OPTIONS['seoaic_schedule_days'];
        $date = !empty($_REQUEST['posting_date']) ? sanitize_text_field($_REQUEST['posting_date']) : date('Y-m-d');

        if (empty($_REQUEST['idea-mass-create'])) {
            SEOAICAjaxResponse::error('Nothing to schedule!')->wpSend();
        }

        $ideas = is_array($_REQUEST['idea-mass-create']) ? $_REQUEST['idea-mass-create'] : [$_REQUEST['idea-mass-create']];

        foreach ($ideas as $idea_id) {

            $idea_id = intval($idea_id);

            delete_post_meta($idea_id, 'seoaic_idea_postdate');

            $days_loop = true;
            $datetime = time();

            while ($days_loop) {

                $_day = strtolower(date('l', $datetime));
                $_posts = $days[$_day]['posts'];

                if (isset($days[$_day])) {

                    $_have_posted_idea = get_posts([
                        'numberposts' => 99,
                        'fields' => 'ids',
                        'post_type' => 'seoaic-post',
                        'post_status' => 'seoaic-idea',
                        'meta_query' => [
                            [
                                'key' => 'seoaic_idea_postdate',
                                'value' => $date,
                                'compare' => 'LIKE'
                            ]
                        ]
                    ]);

                    if (count($_have_posted_idea) < $_posts) {
                        if (false === $this->seoaic->ideas->update_ideas_post_date($idea_id, $date . ' ' . date('H:i:s', strtotime($days[$_day]['time'])))) {

                            $datetime = strtotime($date . ' +1 day');
                            $date = date('Y-m-d', $datetime);
                        } else {
                            $days_loop = false;
                        }
                    } else {

                        $datetime = strtotime($date . ' +1 day');
                        $date = date('Y-m-d', $datetime);
                    }
                } else {

                    $datetime = strtotime($date . ' +1 day');
                    $date = date('Y-m-d', $datetime);
                }

            }
        }

        SEOAICAjaxResponse::alert('Posting schedule saved!')->wpSend();
    }

    public function prepare_item_data($request_data = [])
    {
        global $SEOAIC_OPTIONS;

        if (empty($request_data['item_id'])) {
            wp_die();
        }

        $id = intval($request_data['item_id']);
        $editor = $request_data['data_editor'] ?? false;
        $mass_prompt = !empty($request_data['mass_prompt']) ? stripslashes(sanitize_textarea_field($request_data['mass_prompt'])) : '';
        $mass_service = !empty($request_data['mass_service']) ? trim($request_data['mass_service']) : '';

        $idea_prompt = get_post_meta($id, '_idea_prompt_data', true);
        $name = !empty($SEOAIC_OPTIONS['seoaic_business_name']) ? $SEOAIC_OPTIONS['seoaic_business_name'] : get_option('blogname', true);
        $industry = !empty($SEOAIC_OPTIONS['seoaic_industry']) ? " on the industry of " . $SEOAIC_OPTIONS['seoaic_industry'] : '';
        $desc = !empty($SEOAIC_OPTIONS['seoaic_business_description']) ? $SEOAIC_OPTIONS['seoaic_business_description'] : get_option('blogdescription', true);
        $content_guidelines = !empty($SEOAIC_OPTIONS['seoaic_content_guidelines']) ? $SEOAIC_OPTIONS['seoaic_content_guidelines'] : '';

        if (!empty($request_data['seoaic_subtitles_min'])) {
            $subtitles_min = intval($request_data['seoaic_subtitles_min']);
        } elseif (!empty($SEOAIC_OPTIONS['seoaic_subtitles_range_min'])) {
            $subtitles_min = intval($SEOAIC_OPTIONS['seoaic_subtitles_range_min']);
        } else {
            $subtitles_min = 0;
        }

        if (!empty($request_data['seoaic_subtitles_max'])) {
            $subtitles_max = intval($request_data['seoaic_subtitles_max']);
        } elseif (!empty($SEOAIC_OPTIONS['seoaic_subtitles_range_max'])) {
            $subtitles_max = intval($SEOAIC_OPTIONS['seoaic_subtitles_range_max']);
        } else {
            $subtitles_max = 6;
        }

        if (!empty($request_data['seoaic_words_min'])) {
            $words_min = intval($request_data['seoaic_words_min']);
        } elseif (!empty($SEOAIC_OPTIONS['seoaic_words_range_min'])) {
            $words_min = intval($SEOAIC_OPTIONS['seoaic_words_range_min']);
        } else {
            $words_min = 0;
        }

        if (!empty($request_data['seoaic_words_max'])) {
            $words_max = intval($request_data['seoaic_words_max']);
        } elseif (!empty($SEOAIC_OPTIONS['seoaic_words_range_max'])) {
            $words_max = intval($SEOAIC_OPTIONS['seoaic_words_range_max']);
        } else {
            $words_max = 1000;
        }

        $idea_content = get_post_meta($id, 'seoaic_idea_content', true);
        $idea_content = !empty($idea_content) ? json_decode($idea_content, true) : '';

        $idea_generator = !empty($idea_content['idea_thumbnail_generator']) ? $idea_content['idea_thumbnail_generator'] : seoaic_get_default_image_generator();
        $idea_type = get_post_meta($id, '_idea_type', true);
        $internalLinksMeta = get_post_meta($id, 'seoaic_internal_links', true);
        $internalLinksString = !empty($internalLinksMeta) ? SeoaicInternalLinks::convertFromMetaDataToString($internalLinksMeta) : '';

        if ($editor) {
            $subtitles = get_post_meta($id, 'seoaic_article_subtitles', true) ?? [];
            $keywords = get_post_meta($id, 'seoaic_article_keywords', true) ?? [];
            $thumb = get_post_meta($id, '_thumb_yes_seoaic', true);
            $thumbGen = get_post_meta($id, 'seoaic_idea_thumbnail_generator', true) ? get_post_meta($id, 'seoaic_idea_thumbnail_generator', true) : 'gpt';
            $thumbGen = $thumb ? $thumbGen : 'no_image';
            $thumbDesc = get_post_meta($id, 'seoaic_generate_description', true) ?? [];

        } else {
            $subtitles = !empty($idea_content['idea_skeleton']) ? $idea_content['idea_skeleton'] : [];
            $keywords = !empty($idea_content['idea_keywords']) ? $idea_content['idea_keywords'] : [];
            $thumbGen = !empty($idea_generator) ? $idea_generator : 'gpt';
            $thumbDesc = !empty($idea_content['idea_thumbnail']) ? $idea_content['idea_thumbnail'] : '';
        }

        $postLang = $this->seoaic->multilang->get_post_language($id);

        $pillarLinksMeta = get_post_meta($id, 'seoaic_pillar_links', true);
        $pillarLinksString = !empty($pillarLinksMeta) ? SeoaicPillarLinks::convertFromMetaDataToString($pillarLinksMeta) : '';

        $data_raw = [
            'idea' => get_the_title($id),
            'idea_type' => !empty($idea_type) ? $idea_type : 'default',
            'subtitles' => $subtitles,
            'keywords' => $keywords,
            'thumbnail' => $thumbDesc,
            'thumbnail_generator' => $thumbGen,
            'language' => $postLang,
            'writing_style' => !empty($SEOAIC_OPTIONS['seoaic_writing_style']) ? $SEOAIC_OPTIONS['seoaic_writing_style'] : '',
            'prompt' => !empty($mass_prompt) ? $mass_prompt : $idea_prompt,
            'mass_service' => $mass_service,
            'name' => !empty($name) ? $name : '',
            'industry' => !empty($industry) ? $industry : '',
            'desc' => !empty($desc) ? $desc : '',
            'words_min' => $words_min,
            'words_max' => $words_max,
            'subtitles_min' => $subtitles_min,
            'subtitles_max' => $subtitles_max,
            'internal_links' => $internalLinksString,
            'pillar_links' => $pillarLinksString,
            'content_guidelines' => $content_guidelines,
        ];

        $original_id = get_post_meta($id, 'seoaic_ml_original_post', true);

        if (!empty($original_id)) {
            $post = get_post($original_id);
            $data_raw['original_title'] = $post->post_title;
            $data_raw['original_post'] = $post->post_content;
        }

        return [
            'data' => $this->formatItemFields($data_raw), // formatted
            'data_raw' => $data_raw,
        ];
    }

    public function getItemDataById($id = '')
    {
        global $SEOAIC_OPTIONS;

        if (empty($id)) {
            wp_die();
        }

        $editor = $request_data['data_editor'] ?? false;
        $mass_service = !empty($request_data['mass_service']) ? trim($request_data['mass_service']) : '';

        $idea_prompt = get_post_meta($id, '_idea_prompt_data', true);
        $name = !empty($SEOAIC_OPTIONS['seoaic_business_name']) ? $SEOAIC_OPTIONS['seoaic_business_name'] : get_option('blogname', true);
        $industry = !empty($SEOAIC_OPTIONS['seoaic_industry']) ? " on the industry of " . $SEOAIC_OPTIONS['seoaic_industry'] : '';
        $desc = !empty($SEOAIC_OPTIONS['seoaic_business_description']) ? $SEOAIC_OPTIONS['seoaic_business_description'] : get_option('blogdescription', true);
        $content_guidelines = !empty($SEOAIC_OPTIONS['seoaic_content_guidelines']) ? $SEOAIC_OPTIONS['seoaic_content_guidelines'] : '';

        $idea_content = get_post_meta($id, 'seoaic_idea_content', true);
        $idea_content = !empty($idea_content) ? json_decode($idea_content, true) : '';

        $idea_generator = !empty($idea_content['idea_thumbnail_generator']) ? $idea_content['idea_thumbnail_generator'] : seoaic_get_default_image_generator();
        $idea_type = get_post_meta($id, '_idea_type', true);
        $internalLinksMeta = get_post_meta($id, 'seoaic_internal_links', true);
        $internalLinksString = !empty($internalLinksMeta) ? SeoaicInternalLinks::convertFromMetaDataToString($internalLinksMeta) : '';

        $postLang = $this->seoaic->multilang->get_post_language($id);

        $pillarLinksMeta = get_post_meta($id, 'seoaic_pillar_links', true);
        $pillarLinksString = !empty($pillarLinksMeta) ? SeoaicPillarLinks::convertFromMetaDataToString($pillarLinksMeta) : '';

        if ($editor) {
            $subtitles = get_post_meta($id, 'seoaic_article_subtitles', true) ?? [];
            $keywords = get_post_meta($id, 'seoaic_article_keywords', true) ?? [];
            $thumb = get_post_meta($id, '_thumb_yes_seoaic', true);
            $thumbGen = get_post_meta($id, 'seoaic_idea_thumbnail_generator', true) ? get_post_meta($id, 'seoaic_idea_thumbnail_generator', true) : 'gpt';
            $thumbGen = $thumb ? $thumbGen : 'no_image';
            $thumbDesc = get_post_meta($id, 'seoaic_generate_description', true) ?? [];

        } else {
            $subtitles = !empty($idea_content['idea_skeleton']) ? $idea_content['idea_skeleton'] : [];
            $keywords = !empty($idea_content['idea_keywords']) ? $idea_content['idea_keywords'] : [];
            $thumbGen = !empty($idea_generator) ? $idea_generator : 'gpt';
            $thumbDesc = !empty($idea_content['idea_thumbnail']) ? $idea_content['idea_thumbnail'] : '';
            $ideaMetaDescription = !empty($idea_content['idea_description']) ? $idea_content['idea_description'] : '';
        }

        $services = !empty($_POST['seoaic_services']) ? $_POST['seoaic_services'] : [];
        $target_audience = !empty($_POST['seoaic_target_audience']) ? $_POST['seoaic_target_audience'] : [];

        $data_raw = [
            'idea' => get_the_title($id),
            'idea_type' => !empty($idea_type) ? $idea_type : 'default',
            'subtitles' => $subtitles,
            'keywords' => $keywords,
            'thumbnail' => $thumbDesc,
            'thumbnail_generator' => $thumbGen,
            'language' => $postLang,
            'prompt' => !empty($mass_prompt) ? $mass_prompt : $idea_prompt,
            //'mass_service' => $mass_service ?? '',
            'mass_service' => SEOAIC_SETTINGS::getSelectedRepeaterValues('seoaic_services', $services, true),
            'target_audience' => SEOAIC_SETTINGS::getSelectedRepeaterValues('seoaic_target_audience', $target_audience, true),
            'internal_links' => $internalLinksString,
            'pillar_links' => $pillarLinksString,
            'meta_description' => $ideaMetaDescription,
        ];

        $original_id = get_post_meta($id, 'seoaic_ml_original_post', true);

        if (!empty($original_id)) {
            $post = get_post($original_id);
            $data_raw['original_title'] = $post->post_title;
            $data_raw['original_post'] = $post->post_content;
        }

        return [
            'data' => $this->formatItemFields($data_raw), // formatted
            'data_raw' => $data_raw,
        ];
    }

    private function formatItemFields($data = [])
    {
        array_walk($data, function (&$item, $key) {
            if (
                "keywords" == $key
                && is_array($item)
            ) {
                $item = implode(',', $item);
            }
        });

        return $data;
    }

    /**
     * Generate and save post via openai
     * @param bool $mass_create
     */
    // public function generate_post($mass_create = false, $only_settings = false)
    // {
    //     global $SEOAIC_OPTIONS;

    //     if (empty($_REQUEST['item_id'])) {
    //         wp_die();
    //     }

    //     $request_data = $_REQUEST;
    //     list('data' => $data, 'data_raw' => $data_raw) = $this->prepare_item_data($request_data);

    //     if ($only_settings) {
    //         return $data;
    //     }

    //     $id = intval($_REQUEST['item_id']);
    //     $post_data = [
    //         'ID' => $id,
    //         'post_type' => 'post',
    //         'post_date' => date('Y-m-d H:i:s'),
    //         'post_date_gmt' => gmdate('Y-m-d H:i:s'),
    //         'post_status' => 'draft'
    //     ];
    //     $mass_set_thumbnail = isset($_REQUEST['mass_set_thumbnail']) ? $_REQUEST['mass_set_thumbnail'] : '';

    //     if (isset($_REQUEST['seoaic_post_status'])) {
    //         switch ($_REQUEST['seoaic_post_status']) {
    //             case 'publish':
    //                 $post_data['post_status'] = 'publish';
    //                 break;
    //             case 'delay':
    //                 $publish_delay = !empty($SEOAIC_OPTIONS['seoaic_publish_delay']) ? intval($SEOAIC_OPTIONS['seoaic_publish_delay']) : 0;
    //                 if ($publish_delay > 0) {
    //                     $publish_time = time() + (3600 * $publish_delay);
    //                     $post_data['post_status'] = 'future';
    //                     $post_data['post_date'] = date('Y-m-d H:i:s', $publish_time);
    //                     $post_data['post_date_gmt'] = gmdate('Y-m-d H:i:s', $publish_time);
    //                 }
    //                 break;
    //             case 'schedule':
    //                 $schedule_start_date = (!empty($_REQUEST['seoaic-mass-idea-date']) && $_REQUEST['seoaic-mass-idea-date'] >= date('Y-m-d')) ? $_REQUEST['seoaic-mass-idea-date'] : date('Y-m-d');

    //                 $post_data['post_status'] = 'future';
    //                 $posting_date = $this->get_schedule_posting_date($schedule_start_date);

    //                 if (false !== $posting_date) {
    //                     $post_data['post_date'] = $posting_date;
    //                     $post_data['post_date_gmt'] = gmdate('Y-m-d H:i:s', strtotime($posting_date));
    //                     update_post_meta($id, 'seoaic_idea_postdate', $posting_date);
    //                     wp_update_post(['ID' => $id, 'post_status' => 'future', 'post_date' => '3000-01-01 00:00:00', 'post_date_gmt' => '3000-01-01 00:00:00']);
    //                 }
    //                 break;
    //         }
    //     }

    //     $idea_content = get_post_meta($id, 'seoaic_idea_content', true);
    //     $idea_content = !empty($idea_content) ? json_decode($idea_content, true) : '';

    //     $post_data['post_type'] = !empty($idea_content['idea_post_type']) ? $idea_content['idea_post_type'] : SEOAIC_SETTINGS::getSEOAICPostType();

    //     $result = $this->seoaic->curl->init('api/ai/post', $data, true, true, true);

    //     $content = !empty($result['content']) ? $result['content'] : '';
    //     $post_content = !empty($content['content']) ? $content['content'] : '';

    //     $post_content = stripslashes($post_content);
    //     $post_data['post_content'] = $this->prepareGeneratedContent($post_content);

    //     $wpml_idea_settings = $this->seoaic->multilang->get_wpml_idea_settings($id, $post_data['post_type']);

    //     wp_update_post($post_data);

    //     if (false !== $wpml_idea_settings) {
    //         $this->seoaic->multilang->set_wpml_idea_settings($id, $wpml_idea_settings);
    //     }

    //     if (!empty($result['frame'])) {
    //         $post_desc = !empty($result['frame']['description']) ? $result['frame']['description'] : '';
    //         $post_keywords = !empty($result['frame']['keywords']) ? array_shift($result['frame']['keywords']) : [];
    //     } else {
    //         $post_desc = !empty($idea_content['idea_description']) ? $idea_content['idea_description'] : '';
    //         $post_keywords = !empty($idea_content['idea_keywords']) ? array_shift($idea_content['idea_keywords']) : [];
    //     }

    //     update_post_meta($id, 'seoaic_posted', 1);
    //     update_post_meta($id, '_yoast_wpseo_metadesc', $post_desc);
    //     update_post_meta($id, '_yoast_wpseo_focuskw', $post_keywords);
    //     update_post_meta($id, 'seoaic_generate_description', $data_raw['thumbnail']);
    //     update_post_meta($id, 'seoaic_article_subtitles', $data_raw['subtitles']);
    //     update_post_meta($id, 'seoaic_article_keywords', $data_raw['keywords']);

    //     $language_code = $this->seoaic->multilang->get_post_language($id, 'code');

    //     $categories = false;
    //     if (!empty($idea_content['idea_category'])) {

    //         $categories = is_array($idea_content['idea_category']) ? $idea_content['idea_category'] : [$idea_content['idea_category']];

    //     } elseif (!empty($SEOAIC_OPTIONS['seoaic_default_category'])) {

    //         $categories = is_array($SEOAIC_OPTIONS['seoaic_default_category']) ? $SEOAIC_OPTIONS['seoaic_default_category'] : [$SEOAIC_OPTIONS['seoaic_default_category']];

    //     }

    //     if (!empty($categories)) {
    //         foreach ($categories as $key => $category) {
    //             $append = $key === 0 ? false : true;
    //             wp_set_post_terms($id, [
    //                 $this->seoaic->multilang->get_term_translation($category, $language_code)
    //             ], get_term($category)->taxonomy, $append);
    //         }
    //     }

    //     // Clickdrop image generate
    //     if ($mass_set_thumbnail) {

    //         $attachment_id = $mass_set_thumbnail;
    //         set_post_thumbnail($id, $attachment_id);

    //     } elseif (!empty($content['image'])) {

    //         $url = $content['image'];
    //         $attachment_id = SEOAIC::seoaicUploadFile($url, $data['idea']);
    //         set_post_thumbnail($id, $attachment_id);

    //     }


    //     if (!$mass_create) {

    //         $image_generator_box = '';

    //         if ($data['thumbnail_generator'] !== 'no_image') {
    //             $image_generators = seoaic_get_image_generators();

    //             $image_generator_box .= '<div class="generated-post-thumbnail">
    //                                 <div class="holder">
    //                                     ' . get_the_post_thumbnail($id) . '
    //                                 </div>

    //                                 <div class="seoaic-module">
    //                                 <input type="checkbox" name="regenerate_image" id="regenerate_image">
    //                                 <label for="regenerate_image">' . esc_html__('Don\'t like the image?', 'seoaic') . ' <span>' .__('Generate a new!', 'seoaic') . '</span>
    //                                 <div class="info">
    //                                     <span class="info-btn">?</span>
    //                                         <div class="info-content">
    //                                             <h4>' . esc_html__('Generate new image', 'seoaic') . '</h4>
    //                                             <p>' . esc_html__('You can try regenerating image with another service if you are not satisfied with it.', 'seoaic') . '
    //                                         </p>
    //                                     </div>
    //                                 </div>
    //                                 </label>
    //                                 <div class="selections">
    //                                 <textarea class="promt-key">' . esc_textarea($data['thumbnail']) . '</textarea>
    //                                 <select class="seoaic-form-item form-select regenerate-select-modal" name="seoaic_regenerate-select-modal" required="">';

    //             foreach ($image_generators as $key => $image_generator) {
    //                 if ($key === 'no_image') {
    //                     continue;
    //                 }

    //                 $image_generator_box .= '<option value="' . esc_attr($key) . '"';
    //                 if ($key === $data['thumbnail_generator']) {
    //                     $image_generator_box .= 'selected';
    //                 }
    //                 $image_generator_box .= '>' . esc_html($image_generator) . '</option>';
    //             }

    //             $image_generator_box .= '</select>
    //                                 <div class="btn-sc">
    //                                     <div class="info">
    //                                         <span class="info-btn">?</span>
    //                                         <div class="info-content">
    //                                             <h4>' . esc_html__('Generate new image', 'seoaic') . '</h4>
    //                                             <p>' . esc_html__('You can try regenerating image with another service if you are not satisfied with it.', 'seoaic') . '
    //                                             </p>
    //                                         </div>
    //                                     </div>
    //                                     <button data-callback="regenerate_image_modal" data-desc="' . esc_attr($data['thumbnail']) . '" data-action="seoaic_regenerate_image" data-type="modal" data-post="' . esc_attr($id) . '" title="' . esc_html__('Regenerate image', 'seoaic') . '" type="button" class="button-primary seoaic-generate-image-button" data-action="seoaic_generate_ideas">' . esc_html__('New image', 'seoaic') . '
    //                                     </button>
    //                                 </div>
    //                                 </div>
    //                                 </div>
    //                             </div>';

    //         }

    //         wp_send_json([
    //             'status' => 'success',
    //             'content' => [
    //                 'post_id' => $id,
    //                 'content' => '<div class="generated-post-box">
    //                                     ' . $image_generator_box . '
    //                                     <div class="generated-post-content">
    //                                         ' . $post_data['post_content'] . '
    //                                     </div>
    //                                 </div>'
    //             ],
    //             'editor_content' => $post_data['post_content'],
    //             'thumbnail' => get_post_thumbnail_id($id)
    //         ]);
    //     } else {
    //         wp_send_json([
    //             'status' => 'generating',
    //             'content' => [
    //                 'post_id' => $id,
    //             ],
    //             'editor_content' => $post_data['post_content'],
    //             'thumbnail' => get_post_thumbnail_id($id)
    //         ]);
    //     }
    // }

    /**
     * Regenerate image
     */
    public function regenerate_image()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        global $SEOAIC_OPTIONS;

        $id = intval($_REQUEST['post']);
        $data = [
            'prompt' => stripslashes(sanitize_text_field($_REQUEST['promt'])),
            'thumbnail_generator' => sanitize_text_field($_REQUEST['gen']),
        ];

        $result = $this->seoaic->curl->init('api/ai/images', $data, true, true, true);


        $image_url = $result['image_url'];

        $attachment_id = SEOAIC::seoaicUploadFile($image_url, get_the_title($id));

        set_post_thumbnail($id, $attachment_id);

        $idea_content = get_post_meta($id, 'seoaic_idea_content', true);

        $idea_content = !empty($idea_content) ? json_decode($idea_content, true) : [
            'idea_thumbnail' => '',
            'idea_thumbnail_generator' => '',
            'idea_skeleton' => [],
            'idea_keywords' => '',
            'idea_description' => '',
        ];

        $idea_content['idea_thumbnail'] = $data['prompt'];
        $idea_content['idea_thumbnail_generator'] = $data['thumbnail_generator'];

        update_post_meta($id, 'seoaic_idea_content', json_encode($idea_content));
        update_post_meta($id, 'seoaic_generate_description', $data['prompt']);

        SEOAICAjaxResponse::success()->addFields([
            'content' => [
                'post_id' => $id,
                'content' => get_the_post_thumbnail($id),
                'featured_media' => get_post_thumbnail_id($id)
            ]
        ])->wpSend();
    }

    /**
     * Posts mass create in background
     */
    public function background_generation($ideas_from_source)
    {
        global $SEOAIC_OPTIONS;

        // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.NonceVerification.Missing
        $__REQUEST = wp_unslash($_REQUEST);
        $ideas = [];
        $thumbId = isset($__REQUEST['seoaic_mass_set_thumbnail']) ? (int)$__REQUEST['seoaic_mass_set_thumbnail'] : 0;
        $idea_id = 0;
        $is_experimental_generation = !empty($__REQUEST['seoaic_experimental_generation_post']);
        $isGenerateThumbnail = FormHelpers::isCheckboxChecked('seoaic_generate_thumbnail');

        if (
            $is_experimental_generation
            && empty($SEOAIC_OPTIONS['language_locations'])
            && $this->seoaic->multilang->is_multilang()
        ) {
            $pageUrl = SEOAIC::getAdminUrl('admin.php') . '?page=seoaic-settings';
            SEOAICAjaxResponse::error('To use the new content generation flow you need to visit <a href="' . esc_url($pageUrl) . '" target="_blank">Settings</a> page and select proper locations for languages of your website, then click "Save All"')->wpSend();
        }

        $ideas = [];
        $thumbId = isset($__REQUEST['seoaic_mass_set_thumbnail']) ? (int)$__REQUEST['seoaic_mass_set_thumbnail'] : 0;
        $idea_id = 0;
        $optimize_post = !empty($__REQUEST['seoaic_optimize_post']);
        $isGenerateThumbnail = FormHelpers::isCheckboxChecked('seoaic_generate_thumbnail');
        $isGenerateLeadsForm = FormHelpers::isCheckboxChecked('generate_leads_form');
        $isArticleInteractive = FormHelpers::isCheckboxChecked('interactive_article');
        $leadsFormGoal = !empty($__REQUEST['leads_form_goal']) ? sanitize_text_field($__REQUEST['leads_form_goal']) : 'lead_qualification';
        $leadsFormPrompt = !empty($__REQUEST['leads_form_prompt']) ? sanitize_textarea_field($__REQUEST['leads_form_prompt']) : '';
        $stepsRangeMin = !empty($__REQUEST['leads_form_steps_range_min']) ? intval($__REQUEST['leads_form_steps_range_min']) : 5;
        $stepsRangeMax = !empty($__REQUEST['leads_form_steps_range_max']) ? intval($__REQUEST['leads_form_steps_range_max']) : 9;

        if ($ideas_from_source) {
            $__REQUEST['idea-mass-create'] = $ideas_from_source;
        }

        if (
            isset($__REQUEST['idea-mass-create'])
            && $__REQUEST['idea-mass-create']
        ) {
            if (is_array($__REQUEST['idea-mass-create'])) {
                foreach ($__REQUEST['idea-mass-create'] as $item) {
                    $ideas[] = intval($item);
                }
            } else {
                $item = intval($__REQUEST['idea-mass-create']);
                $ideas[] = $item;
            }
        } else {
            $item = intval($__REQUEST['item_id']);
            $ideas[] = $item;
            $idea_id = $item;
        }

        // generate thumb
        if ($isGenerateThumbnail) {
            // generation will be run after the post is generated (received from backend)
            $generateThumbnailStyle = !empty($__REQUEST['generate_thumbnail_style']) ? $__REQUEST['generate_thumbnail_style'] : SEOAIC_SETTINGS::getImageGenerateStyle();
            $generateThumbnailPrompt = !empty($__REQUEST['thumbnail_generation_prompt']) ? stripslashes(sanitize_textarea_field($__REQUEST['thumbnail_generation_prompt'])) : '';

            $width = !empty($__REQUEST['thumbnail_generation_width']) ?
                stripslashes(sanitize_textarea_field($__REQUEST['thumbnail_generation_width'])) :
                SEOAIC_SETTINGS::getImageGenerateWidthDefault();

            $height = !empty($__REQUEST['thumbnail_generation_height']) ?
                stripslashes(sanitize_textarea_field($__REQUEST['thumbnail_generation_height'])) :
                SEOAIC_SETTINGS::getImageGenerateHeightDefault();

            foreach ($ideas as $ideaId) {
                update_post_meta(intval($ideaId), self::GENERATE_THUMBNAIL_FIELD, 1);
                update_post_meta(intval($ideaId), self::GENERATE_THUMBNAIL_STYLE_FIELD, $generateThumbnailStyle);
                update_post_meta(intval($ideaId), self::GENERATE_THUMBNAIL_PROMPT_FIELD, $generateThumbnailPrompt);
                update_post_meta(intval($ideaId), self::GENERATE_THUMBNAIL_WIDTH, $width);
                update_post_meta(intval($ideaId), self::GENERATE_THUMBNAIL_HEIGHT, $height);

                $postItem = [
                    self::GENERATE_THUMBNAIL_FIELD => 1,
                    self::GENERATE_THUMBNAIL_STYLE_FIELD => $generateThumbnailStyle,
                    self::GENERATE_THUMBNAIL_PROMPT_FIELD => $generateThumbnailPrompt,
                    self::GENERATE_THUMBNAIL_WIDTH => $width,
                    self::GENERATE_THUMBNAIL_HEIGHT => $height
                ];

                update_post_meta(intval($ideaId), self::MASS_GENERATION_DATA, $postItem);
            }
        } else { // set thumb from gallery
            if (!empty($thumbId)) {
                foreach ($ideas as $ideaId) {
                    set_post_thumbnail(intval($ideaId), $thumbId);
                }
            }
        }

        // Validate location code if we use experemental generation
        if (
            $is_experimental_generation
            && $this->seoaic->multilang->is_multilang()
        ) {
            $ideaVithoutLangCode = [];

            foreach($ideas as $idea) {
                $locationCode = get_post_meta($idea, '_idea_language_location_code', true);

                if (empty($locationCode)) {
                    $ideaVithoutLangCode[] = [
                        'id' => $idea,
                        'title' => get_the_title($idea),
                        'language' => $this->seoaic->multilang->get_post_language($idea)
                    ];
                }
            }

            if (!empty($ideaVithoutLangCode)) {
                $string = array_map(function ($item) {
                    return '<div class="mb-10 alert-added-ideas"><b class="num-col">#' . esc_html($item['id']) . '</b><dic class="title-col"><span class="idea-orig-title">' . esc_html($item['title']) . '<br> Choose location for this language: <b class="num-col">' . esc_html($item['language']) . '</b></span></div>';
                }, $ideaVithoutLangCode);

                SEOAICAjaxResponse::error('<div class="mb-19">' . esc_html__("Can't generate posts because these ideas have no location code:", 'seoaic') . '</div>' . implode('', $string))->wpSend();
            }
        }

        $prev_option = PostsGenerationLoader::getPostsOption();

        if (
            isset($prev_option['total'])
            && isset($prev_option['done'])
            && count($prev_option['total']) > count($prev_option['done'])
        ) {
            $option_ideas = array_merge($ideas, $prev_option['total'] ?? []);
            $option_posts = $prev_option['done'];
        } else {
            $option_ideas = $ideas;
            $option_posts = [];
        }

        $option = [
            'total' => $option_ideas,
            'done' => $option_posts,
        ];

        $post_status = !empty($__REQUEST['seoaic_post_status']) ? $__REQUEST['seoaic_post_status'] : '';
        if (isset($__REQUEST['set_post_status'])) {
            $post_status = $__REQUEST['set_post_status'];
        }

        if (
            !empty($__REQUEST['seoaic-mass-idea-date'])
            && $__REQUEST['seoaic-mass-idea-date'] >= date('Y-m-d')
        ) {
            $schedule_start_date = $__REQUEST['seoaic-mass-idea-date'];
            $post_author_id = !empty($SEOAIC_OPTIONS['seoaic_post_author']) ? (int)$SEOAIC_OPTIONS['seoaic_post_author'] : get_current_user_id();

            foreach ($ideas as $idea) {
                $posting_date = $this->get_schedule_posting_date($schedule_start_date);

                if (isset($__REQUEST['set_post_date'])) {
                    $posting_date = $__REQUEST['set_post_date'];
                }

                if ($post_status === 'publish' || $post_status === 'draft') {
                    $posting_date = date("Y-m-d H:i:s");
                }

                if($post_status === 'schedule' && !empty($schedule_start_date)) {
                    $posting_date = $this->get_valid_post_datetime($schedule_start_date);
                }

                update_post_meta($idea, 'seoaic_idea_postdate', $posting_date);
                update_post_meta($idea, 'seoaic_idea_poststatus', $post_status);
                wp_update_post([
                    'ID' => $idea,
                    'post_status' => 'future',
                    'post_date' => '3000-01-01 00:00:00',
                    'post_date_gmt' => '3000-01-01 00:00:00',
                    'post_author'  => $post_author_id,
                ]);
            }
        }

        PostsGenerationLoader::setPostsOption($option);
        $httpHost = !empty($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ''; // phpsc:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

        $formData = [
            'prompt' => '',
            'words_min' => self::WORDS_MIN,
            'words_max' => self::WORDS_MAX,
            'subtitles_min' => self::SUBTITLES_MIN,
            'subtitles_max' => self::SUBTITLES_MAX,
            'domain' => $httpHost,
            'posting_date' => null,
            'manual_mass_thumb' => $thumbId,
            'type' => 'post',
            'categories' => [],
        ];

        if (isset($__REQUEST['mass_prompt'])) {
            $formData['prompt'] = stripslashes(sanitize_textarea_field($__REQUEST['mass_prompt']));

            (new PostsMassGenerateLastUsedPrompts())->store($formData['prompt']);
        }

        if (isset($__REQUEST['seoaic_knowledge_base'])) {
            $formData['knowledge_ids'] = $__REQUEST['seoaic_knowledge_base'];
        }

        if (!empty($__REQUEST['seoaic_default_category'])) {
            $formData['categories'] = $__REQUEST['seoaic_default_category'];
        }

        $intFields = [
            'seoaic_words_range_min' => 'words_min',
            'seoaic_words_range_max' => 'words_max',
            'seoaic_subtitles_range_min' => 'subtitles_min',
            'seoaic_subtitles_range_max' => 'subtitles_max',
        ];

        foreach ($intFields as $requestField => $resultField) {
            if (isset($__REQUEST[$requestField])) {
                $formData[$resultField] = intval($__REQUEST[$requestField]);
            }
        }

        if (
            !empty($__REQUEST['seoaic-translate-from-origin'])
            && $__REQUEST['seoaic-translate-from-origin'] === 'yes'
        ) {
            $basket = [];
            foreach ($ideas as $idea) {
                if (in_array($idea, $basket)) {
                    continue;
                }

                $linked_ideas = $this->seoaic->multilang->get_post_translations($idea);
                update_post_meta($idea, 'seoaic_ml_generated_data', $formData);

                if ($linked_ideas) {
                    foreach ($linked_ideas as $linked_idea) {
                        if (
                            $linked_idea == $idea
                            || !array_search($linked_idea, $ideas)
                        ) {
                            continue;
                        }

                        $basket[] = $linked_idea;
                        update_post_meta($linked_idea, 'seoaic_ml_original_post', $idea);
                    }
                }
            }

            foreach ($basket as $removed_idea) {
                $key = array_search($removed_idea, $ideas);
                unset($ideas[$key]);
            }
            $ideas = array_values($ideas);
        }

        $seoaicData = SEOAIC::getSEOAICData();

        $requestData = [
            'knowledge_ids'     => !empty($formData['knowledge_ids']) ? [$formData['knowledge_ids']] : [],
            'prompt'            => $formData['prompt'],
            'domain'            => $formData['domain'],
            'name'              => $seoaicData['name'],
            'industry'          => $seoaicData['industry'],
            'desc'              => $seoaicData['desc'],
            'content_guidelines' => $seoaicData['content_guidelines'],
            'words_min'         => $formData['words_min'],
            'words_max'         => $formData['words_max'],
            'subtitles_min'     => $formData['subtitles_min'],
            'subtitles_max'     => $formData['subtitles_max'],
            'writing_style'     => $seoaicData['writing_style'],
            'manual_mass_thumb' => $thumbId,
            'experimental_generation' => $is_experimental_generation,
            'with_outlines'     => true,
            'ideas'             => [],
            'custom_faq_prompt' => SEOAIC_SETTINGS::getCustomFaqPrompt()
        ];


        $location = SEOAIC_SETTINGS::getLocation();
        $locationCode = $this->seoaic->multilang->get_location_code_by_name($location);
        $ideasDataArray = [];

        foreach ($ideas as $i => $idea) {
            delete_post_meta($idea, 'seoaic_generate_status');
            list('data' => $idea_data, 'data_raw' => $data_raw) = $this->getItemDataById($idea);

            $language = $this->seoaic->multilang->get_post_language($idea);
            if (empty($language)) {
                $language = $SEOAIC_OPTIONS['seoaic_language'];
            }
            $langCode = $this->seoaic->multilang->get_language_code_by_name($language);

            if ($this->seoaic->multilang->is_multilang()) {
                $languageArgs = $this->seoaic->multilang->get_language_by($language);
                $locationCode = $this->seoaic->multilang->get_selected_location($idea, $languageArgs['code']);
                $langCode = $languageArgs['code'];
            }

            if (!empty($__REQUEST['seoaic_default_category'])) {
                $this->seoaic->ideas->updateCategory((int)$idea, $__REQUEST['seoaic_default_category']);
            }

            $ideasDataArray[] = [
                'idea_id'           => $idea,
                'idea'              => $idea_data['idea'],
                'idea_type'         => $idea_data['idea_type'],
                'subtitles'         => array_map(function ($item) {
                    if (is_string($item)) {
                        return [
                            'title'     => $item,
                            'outline'   => '',
                        ];
                    }
                    return [
                        'title'     => $item['title'],
                        'outline'   => $item['outline'],
                    ];
                }, $idea_data['subtitles']),
                'keywords'          => $idea_data['keywords'],
                'thumbnail'         => $idea_data['thumbnail'],
                'thumbnail_generator' => 'no_image',
                'language'          => $language,
                'language_code'     => $langCode,
                'location_code'     => $locationCode,
                'internal_links'    => $idea_data['internal_links'],
                'pillar_links'      => $idea_data['pillar_links'],
                'generate_takeaways' => FormHelpers::isCheckboxChecked('seoaic_add_takeaways'),
                'generate_faq'      => FormHelpers::isCheckboxChecked('seoaic_add_faq'),
                'optimize_post'     => FormHelpers::isCheckboxChecked('seoaic_optimize_post'),
                'optimize_post_type' => !empty($__REQUEST['seoaic_optimize_post_type']) ? $__REQUEST['seoaic_optimize_post_type'] : 'base',
                'meta_description'  => $idea_data['meta_description'],
                'mass_service'      => $idea_data['mass_service'],
                'target_audience'   => $idea_data['target_audience'],
                'generate_form'     => $isGenerateLeadsForm,
                'form_primary_goal' => $leadsFormGoal,
                'custom_form_prompt' => $leadsFormPrompt,
                'form_steps_number_min' => $stepsRangeMin,
                'form_steps_number_max' => $stepsRangeMax,
                'post_type'         => $isArticleInteractive ? 'interactive' : 'simple',
            ];

            if ($ideas_from_source) {
                $ideasDataArray[$i]['manual_mass_thumb'] = $thumbId;
                $ideasDataArray[$i]['idea_type'] = 'content';
            }

            if ($isArticleInteractive) {
                update_post_meta($idea, self::IS_INTERACTIVE_KEY, 1);
            }
        }

        $ideasChunks = array_chunk($ideasDataArray, self::PER_REQUEST__GENERATE);
        foreach ($ideasChunks as $ideasChunk) {
            $requestData['ideas'] = $ideasChunk;

            $this->debugLog('Mass Generate; Request:', json_encode($requestData));

            $result = $this->seoaic->curl->init('api/ai/posts/generate', $requestData, true, false, true);

            $this->debugLog('Mass Generate; Response:', json_encode($result));
        }

        SEOAICAjaxResponse::success()->addFields([
            'content' => [
                'post_id' => $idea_id,
                'loader'  => $this->seoaic->get_background_process_loader(true),
            ]
        ])->wpSend();
    }

    /**
     * Posts mass create
     */
    public function postsMassGenerateAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $this->background_generation([]);

        SEOAICAjaxResponse::waiting()->wpSend();
    }

    public function postsMassGenerate($ideas_from_source = [])
    {
        $this->background_generation($ideas_from_source);

        SEOAICAjaxResponse::waiting()->wpSend();
    }

    public function postsMassReviewClearBackgroundOption()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        PostsReviewLoader::deletePostsOption();
        SEOAICAjaxResponse::success()->wpSend();
    }

    public function postsMassEditClearBackgroundOption()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        PostsEditLoader::deletePostsOption();
        SEOAICAjaxResponse::success()->wpSend();
    }

    /**
     * Publish post
     */
    public function publish_post()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        global $SEOAIC_OPTIONS;

        if (empty($_REQUEST['item_id'])) {
            wp_die();
        }

        $id = intval($_REQUEST['item_id']);

        $post_data = [
            'ID' => $id,
            'post_date' => date('Y-m-d H:i:s'),
            'post_date_gmt' => gmdate('Y-m-d H:i:s'),
            'post_status' => 'draft'
        ];

        $message = 'Post saved as draft!';
        switch ($_REQUEST['seoaic_post_status']) {
            case 'publish':
                $post_data['post_status'] = 'publish';
                $message = 'Post published!';
                break;
            case 'delay':
                $publish_delay = !empty($SEOAIC_OPTIONS['seoaic_publish_delay']) ? intval($SEOAIC_OPTIONS['seoaic_publish_delay']) : 0;

                if ($publish_delay > 0) {
                    $publish_time = time() + (3600 * $publish_delay);
                    $post_data['post_status'] = 'future';
                    $post_data['post_date'] = date('Y-m-d H:i:s', $publish_time);
                    $post_data['post_date_gmt'] = gmdate('Y-m-d H:i:s', $publish_time);
                    $message = 'Post scheduled!';
                }
                break;
        }

        wp_update_post($post_data);

        SEOAICAjaxResponse::alert($message)->wpSend();
    }

    private function generateFromInteractiveContent(int $postId, array $data): string
    {
        $content = '';

        if (
            empty($data['interactivePost'])
            || empty($data['interactivePost']['blocks'])
            || !is_array($data['interactivePost']['blocks'])
        ) {
            return $content;
        }

        $blocks = $data['interactivePost']['blocks'];
        $setIds = function (&$array) {
            if (
                empty($array)
                || !is_array($array)
            ) {
                return;
            }

            foreach ($array as &$arrayItem) {
                if (!isset($arrayItem['id'])) {
                    $arrayItem['id'] = Utils::guidv4();
                }
            }
        };

        foreach ($blocks as $i => $block) {
            if (!empty($block['content'])) {
                $content .= $block['content'];
            }

            if (!empty($block['question'])) {
                $interactiveBlock = $block['question'];
                $interactiveBlock['id'] = !empty($block['block_id']) ? $block['block_id'] : $i;
                $interactiveBlock['post_id'] = $postId;

                $setIds($interactiveBlock['answers']);
                $setIds($interactiveBlock['buttons']);

                $content .= "\r\n\r\n<!-- wp:seoaic/interactive-article-block " . json_encode($interactiveBlock, JSON_UNESCAPED_UNICODE) . " /-->\r\n\r\n";
            }
        }

        return $content;
    }

    /**
     * Save generated post
     */
    public function save_generated_post($request_data)
    {
        global $SEOAIC_OPTIONS;
        if (
            empty($request_data['ideaId'])
            || intval($request_data['ideaId']) != $request_data['ideaId']
        ) {
            //TODO: refactor
            echo 'error';
            wp_die();
        }

        $id = intval($request_data['ideaId']);
        $content = $request_data['content'];

        $post_data = [
            'ID' => $id,
            'post_type' => 'post',
            'post_date' => date('Y-m-d H:i:s'),
            'post_date_gmt' => gmdate('Y-m-d H:i:s'),
            'post_status' => 'publish'
        ];
        $post_content = '';

        $isInteractive = get_post_meta($id, self::IS_INTERACTIVE_KEY, true);

        if (!empty($content['content'])) {
            if ($isInteractive) {
                $post_content = $this->generateFromInteractiveContent($id, $content['content']);
                delete_post_meta($id, self::IS_INTERACTIVE_KEY);

            } else if (is_string($content['content'])) {
                $post_content = stripslashes($content['content']);

            } else { // is case if something went wrong
                $post_content = print_r($content['content'], true);
            }
        }

        $publish_date = get_post_meta($id, 'seoaic_idea_postdate', true);
        if (!empty($publish_date)) {
            $post_data['post_status'] = 'future';
            $post_data['post_date'] = $publish_date;
            $post_data['post_date_gmt'] = gmdate('Y-m-d H:i:s', strtotime($publish_date));
        } else {
            $publish_delay = !empty($SEOAIC_OPTIONS['seoaic_publish_delay']) ? intval($SEOAIC_OPTIONS['seoaic_publish_delay']) : 0;

            if ($publish_delay > 0) {
                $publish_time = time() + (3600 * $publish_delay);
                $post_data['post_status'] = 'future';
                $post_data['post_date'] = date('Y-m-d H:i:s', $publish_time);
                $post_data['post_date_gmt'] = gmdate('Y-m-d H:i:s', $publish_time);
            }
        }

        $post_status = get_post_meta($id, 'seoaic_idea_poststatus', true);

        if ($post_status === 'draft') {
            $post_data['post_status'] = $post_status;
        }

        $title = '';
        if (preg_match('|<h1[^>]*?>(.*?)</h1>|si', $post_content, $arr)) {
            $title = $arr[1];
        }
        if ($title) {
            $slug = sanitize_title($title);
            $post_data['post_title'] = $title;
            $post_data['post_name'] = $slug;
        }

        $post_content = $this->prepareGeneratedContent($post_content);
        $post_content = preg_replace('#<h1(.*?)>(.*?)</h1>#is', '', $post_content);

        if (
            !empty($content['takeaways'])
            && is_array($content['takeaways'])
        ) {
            $this->addTakeawaysToContent($post_content, $content['takeaways']);
        }

        if (
            !empty($content['faq'])
            && is_array($content['faq'])
        ) {
            $filteredFAQ = array_filter($content['faq'], function ($item) {
                return !empty($item['question']) && !empty($item['answer']);
            });

            $html = (new SEOAICBlocks())->faq($filteredFAQ);

            $post_content .= "\n" . $html;
        }

        if (
            !empty($content['form'])
            && is_array($content['form'])
        ) {
            try {
                $shortcode = $this->seoaic->leadsAddon->makeShortcodeFromAIResponse($content['form']);
                $post_content .= "\n" . $shortcode;

                $name = $content['form'][0]['question'];
                (new LeadsFormPattern($name, $shortcode))->save();
            } catch (Exception $e) {

            }
        }

        $post_data['post_content'] = $post_content;
        // $post_data['post_excerpt'] = $this->makeExcerptFromText($post_content);

        $idea_content = get_post_meta($id, 'seoaic_idea_content', true);
        $idea_content = !empty($idea_content) ? json_decode($idea_content, true) : '';

        $post_data['post_type'] = !empty($idea_content['idea_post_type']) ? $idea_content['idea_post_type'] : SEOAIC_SETTINGS::getSEOAICPostType();

        if (!empty($content['frame'])) {
            $idea_frame = json_decode($content['frame'], true);
            $post_desc = !empty($idea_frame['description']) ? $idea_frame['description'] : '';
            $post_keywords = !empty($idea_frame['keywords']) ? array_shift($idea_frame['keywords']) : '';

            if (!empty($idea_frame['excerpt'])) {
                $post_data['post_excerpt'] = strip_tags($idea_frame['excerpt']);
            }
        } else {
            $post_desc = !empty($idea_content['idea_description']) ? $idea_content['idea_description'] : '';
            $post_keywords = !empty($idea_content['idea_keywords']) ? array_shift($idea_content['idea_keywords']) : '';
        }

        $wpml_idea_settings = $this->seoaic->multilang->get_wpml_idea_settings($id, $post_data['post_type']);

        wp_update_post($post_data);

        $this->saveWordsCountMeta(get_post($id));

        if (false !== $wpml_idea_settings) {
            $this->seoaic->multilang->set_wpml_idea_settings($id, $wpml_idea_settings);
        }

        $this->debugLog('Meta Description: ', $post_desc);
        $this->debugLog('Focus Keyword: ', $post_keywords);

        update_post_meta($id, 'seoaic_posted', 1);
        update_post_meta($id, 'post_created_date', time());
        // update_post_meta($id, '_yoast_wpseo_metadesc', $post_desc);
        // update_post_meta($id, '_yoast_wpseo_focuskw', $post_keywords);
        // update_post_meta($id, 'rank_math_description', $post_desc);
        // update_post_meta($id, 'rank_math_focus_keyword', $post_keywords);
        $metaPluginsInstances = SEOPluginsHelper::getAllSEOPlugins();

        foreach ($metaPluginsInstances as $metaPluginInstance) {
            $metaPluginInstance->setKeyword($id, $post_keywords);
            $metaPluginInstance->setDescription($id, $post_desc);
        }

        $postTemplate = !empty($SEOAIC_OPTIONS['seoaic_post_template']) ? $SEOAIC_OPTIONS['seoaic_post_template'] : '';
        if (!empty($postTemplate)) {
            update_post_meta($id, '_wp_page_template', $postTemplate);
        }

        $language_code = $this->seoaic->multilang->get_post_language($id, 'code');
        $formData = get_post_meta($id, 'seoaic_ml_generated_data', true);

        $categories = false;
        if (!empty($idea_content['idea_category'])) {
            $categories = is_array($idea_content['idea_category']) ? $idea_content['idea_category'] : [$idea_content['idea_category']];

        } else {
            if (!empty($formData['categories'])) { // set selected categories -- POSSIBLY OUTDATED
                $categories = is_array($formData['categories']) ? $formData['categories'] : [$formData['categories']];

            } else { // set default
                $defaultCategories = SEOAIC_SETTINGS::getPostsDefaultCategories();
                if (!empty($defaultCategories)) {
                    $categories = is_array($defaultCategories) ? $defaultCategories : [$defaultCategories];
                }
            }
        }

        if (!empty($categories)) {
            foreach ($categories as $key => $category) {
                $append = $key === 0 ? false : true;
                wp_set_post_terms($id, [
                    $this->seoaic->multilang->get_term_translation($category, $language_code)
                ], get_term($category)->taxonomy, $append);
            }
        }

        $option = PostsGenerationLoader::getPostsOption();

        if (
            in_array($id, $option['total'])
            && !in_array($id, $option['done'])
        ) {
            $option['done'][] = $id;

            PostsGenerationLoader::setPostsOption($option);
        }

        if ($this->seoaic->multilang->is_multilang()) {
            $multilang_ideas = get_posts([
                'numberposts' => -1,
                'post_type' => 'seoaic-post',
                'post_status' => 'seoaic-idea',
                'fields' => 'ids',
                'meta_query' => [
                    'relation' => 'AND',
                    [
                        'key' => 'seoaic_ml_original_post',
                        'value' => $id,
                        'compare' => '='
                    ]
                ],
            ]);

            $option = PostsGenerationLoader::getPostsOption();
            $ideas_to_generate = [];

            foreach ($multilang_ideas as $idea) {
                if (in_array($idea, $option['total'])) {
                    $ideas_to_generate[] = $idea;
                }
            }


            if (!empty($ideas_to_generate)) {
                $seoaicData = SEOAIC::getSEOAICData();
                $requestData = [
                    'knowledge_ids' => $formData['knowledge_ids'] ? [$formData['knowledge_ids']] : [],
                    'prompt'    => $formData['prompt'],
                    'domain'    => $formData['domain'],
                    'name'      => $seoaicData['name'],
                    'industry'  => $seoaicData['industry'],
                    'desc'      => $seoaicData['desc'],
                    'content_guidelines'    => $seoaicData['content_guidelines'],
                    //'pillar_links'  => $formData['pillar_links'],
                    'words_min'     => $formData['words_min'],
                    'words_max'     => $formData['words_max'],
                    'subtitles_min' => $formData['subtitles_min'],
                    'subtitles_max' => $formData['subtitles_max'],
                    'writing_style' => $seoaicData['writing_style'],
                    // 'manual_mass_thumb' => $thumb,
                    'ideas' => [],
                ];

                $ideasDataArray = [];
                foreach ($ideas_to_generate as $idea) {
                    delete_post_meta($idea, 'seoaic_generate_status');
                    list('data' => $idea_data, 'data_raw' => $data_raw) = $this->getItemDataById($idea);

                    $ideasDataArray[] = [
                        'idea_id'           => $idea,
                        'idea'              => $idea_data['idea'],
                        'idea_type'         => $idea_data['idea_type'],
                        'subtitles'         => $idea_data['subtitles'],
                        'keywords'          => $idea_data['keywords'],
                        'thumbnail'         => $idea_data['thumbnail'],
                        'thumbnail_generator' => $idea_data['thumbnail_generator'],
                        'language'          => $idea_data['language'],
                        'internal_links'    => $idea_data['internal_links'],
                        'pillar_links'      => $idea_data['pillar_links'],
                    ];
                }
                $requestData['ideas'] = $ideasDataArray;

                $this->debugLog('Mass Generate (multilang); Request:', json_encode($requestData));

                $result = $this->seoaic->curl->init('api/ai/posts/generate', $requestData, true, false, true);
            }
        }
    }

    /**
     * For compatibility with versions less than 8.3.0
     */
    private function excerptRemoveFootnotes($content)
    {
        if (!str_contains($content, 'data-fn=')) {
            return $content;
        }

        return preg_replace(
            '_<sup data-fn="[^"]+" class="[^"]+">\s*<a href="[^"]+" id="[^"]+">\d+</a>\s*</sup>_',
            '',
            $content
        );
    }

    // private function makeExcerptFromText(string $text = '')
    // {
    //     $raw_excerpt = $text;

    //     $regex = '#(<h([1-6])[^>]*>)\s?(.*)?\s?(<\/h\2>)#';
    //     $text = preg_replace($regex,'', $text); // remove H<1-6> tags
    //     $text = strip_shortcodes($text);
    //     $text = excerpt_remove_blocks($text);
    //     if (function_exists('excerpt_remove_footnotes')) {
    //         $text = excerpt_remove_footnotes($text);
    //     } else {
    //         $text = $this->excerptRemoveFootnotes($text);
    //     }

    //     $filter_image_removed = remove_filter('the_content', 'wp_filter_content_tags', 12);
    //     $filter_block_removed = remove_filter('the_content', 'do_blocks', 9);

    //     $text = apply_filters('the_content', $text);
    //     $text = str_replace(']]>', ']]&gt;', $text);

    //     // Restore the original filter if removed.
    //     if ($filter_block_removed) {
    //         add_filter('the_content', 'do_blocks', 9);
    //     }

    //     if ($filter_image_removed) {
    //         add_filter('the_content', 'wp_filter_content_tags', 12);
    //     }

    //     /* translators: Maximum number of words used in a post excerpt. */
    //     $excerpt_length = (int) _x('55', 'excerpt_length');

    //     $excerpt_length = (int) apply_filters('excerpt_length', $excerpt_length);
    //     $excerpt_more = apply_filters('excerpt_more', ' ' . '[&hellip;]');
    //     $text         = wp_trim_words($text, $excerpt_length, $excerpt_more);

    //     return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
    // }

    private function prepareGeneratedContent($content = '')
    {
        // Sometimes AI sends unnecessary notifications in to the content separated with "```" OR "---", so we cut them off with explode
        $content = explode("```", $content);
        $content = count($content) > 1 ? $content[1] : $content[0];
        // OR "---"
        $content = explode("---", $content);
        $content = count($content) > 1 ? $content[1] : $content[0];
        //Replacement of possible unnecessary parts from content
        //$content = preg_replace("/<([a-z][a-z0-9]*)[^>]*?(\/?)>/si", '<$1$2>', $content);
        $content = preg_replace('/^[^,]*<h1>\s*/', '<h1>', $content);
        $content = preg_replace("/<h(.+?)>subtitle:(.+?)/i", '<h$1>$2', $content);
        $content = preg_replace("/<h(.+?)>subtitle(.+?)/i", '<h$1>$2', $content);
        $content = preg_replace("/html$/i", "", $content);
        $content = preg_replace("/html$/i", "", $content);
        $content = preg_replace("/html\\\\n$/i", "", $content);
        $content = preg_replace("/html\\\\n/i", "", $content);
        $content = preg_replace("/plaintext\\\\n/i", "", $content);
        $content = str_replace("html", '', $content);
        $content = str_replace("html\n", '', $content);
        $content = str_replace("html\\n", '', $content);
        $content = str_replace("plaintext\n", '', $content);
        $content = preg_replace('#<meta(.*?)>#is', '', $content);
        $content = preg_replace('#<title(.*?)>(.*?)</title>#is', '', $content);
        $content = preg_replace('#<br>(.*?)<br>#is', '', $content);
        $content = preg_replace('#<br>#is', '', $content);
        $content = preg_replace('#<br>(.*?)lang="(.*?)"<br>#is', '', $content);
        $content = preg_replace('#</>#is', '', $content);

        return $content;
    }

    private function addTakeawaysToContent(&$content, $items=[])
    {
        if (
            empty($items)
            || !is_array($items)
        ) {
            return;
        }

        $itemsArray = array_map('trim', $items);
        $itemsArray = array_filter($itemsArray);

        if (empty($itemsArray)) {
            return;
        }


        $takeawaysHTML = '<h3>' . esc_html__('Key takeaways - What you will learn from this read', 'seoaic') . '</h3>';
        $takeawaysHTML .= '<ul>';

        foreach ($itemsArray as $item) {
            $takeawaysHTML .= '<li>' . esc_html($item) . '</li>';
        }

        $takeawaysHTML .= '</ul>';

        $content = $takeawaysHTML . $content;
    }

    public function seoaic_filter_content($content)
    {
        return $this->prepareGeneratedContent($content);
    }

    public function postsMassGenerateCheckStatusManually()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $this->postsMassGenerateCheckStatus(true);
    }

    public function postsMassGenerateCheckStatusAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $this->postsMassGenerateCheckStatus();
    }

    public function postsMassGenerateCheckStatus($manually = false)
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        try {
            $this->debugLog($manually ? 'run manually' : 'run auto');

            $status_result = $this->seoaic->curl->init('api/ai/posts/generate/status', [], true, false, true);
            $this->debugLog('Mass Generate status; ', json_encode($status_result));

            if (
                !empty($status_result['failed'])
                && is_array($status_result['failed'])
            ) {
                $this->massGenerateProccessFailedPosts($status_result['failed']);
            }

            if (
                !empty($status_result['completed'])
                && is_array($status_result['completed'])
            ) {
                $this->massGenerateProccessCompletedPosts($status_result['completed']);
            }

            if ( // all posts were obtained - stop proccess
                isset($status_result['pending'])
                && empty($status_result['pending'])
                && isset($status_result['completed'])
                && empty($status_result['completed'])
            ) {
                $clear_result = $this->seoaic->curl->init('/api/ai/posts/generate/clear', ['full' => false], true, true, true);

                $this->stopGenerateProgress(); // stops backend polling
            }

            $option = PostsGenerationLoader::getPostsOption();
            $data = [
                'status' => 'progress',
                'width' => 0,
                'posts' => $option['done'],
            ];

            if (!empty($option)) {
                $doneCount = !empty($option['done']) ? count($option['done']) : 0;
                $totalCount = !empty($option['total']) ? count(array_unique($option['total'])) : 0;
                $data['width'] = !empty($totalCount) ? $doneCount / $totalCount * 100 : 0;

                // update_option('seoaic_background_post_generation', $option);
                if ($doneCount == $totalCount) {
                    $data['status'] = 'complete';
                }
            }

            $msg = '';

            if ('complete' === $data['status']) {
                if (
                    empty($_REQUEST['simple_post'])
                    || empty(intval($_REQUEST['simple_post']))
                ) {
                    $msg = 'Posts generated successfully!';

                } else {
                    $data['post_content'] = $this->makePostContentField($data);
                }
            }
        } catch (Exception $e) {
            $this->debugLog('Catch error: ', $e->getMessage());
        }

        $this->massGenerateCheckingStatusUnLock(); // IMPORTANT: don't forget to unlock before any response

        SEOAICAjaxResponse::complete($msg)->addFields($data)->wpSend();
    }

    private function makePostContentField($data)
    {
        global $SEOAIC_OPTIONS;

        $idea_id = intval($_REQUEST['simple_post']);
        $post_content = get_post_field('post_content', $idea_id);

        $image_generator_box = '';
        $idea_content = get_post_meta($idea_id, 'seoaic_idea_content', true);
        if (!empty($idea_content)) {
            $idea_content = json_decode($idea_content, true);
        }

        $default_thumbnail_generator = !empty($SEOAIC_OPTIONS['seoaic_image_generator']) ? $SEOAIC_OPTIONS['seoaic_image_generator'] : 'no_image';
        $thumbnail_generator = !empty($idea_content['idea_thumbnail_generator']) ? $idea_content['idea_thumbnail_generator'] : $default_thumbnail_generator;
        $idea_thumb = !empty($idea_content['idea_thumbnail']) ? $idea_content['idea_thumbnail'] : '';

        if ($thumbnail_generator !== 'no_image') {
            $image_generators = seoaic_get_image_generators();

            $image_generator_box .= '
                <div class="generated-post-thumbnail">
                    <div class="holder">
                        ' . get_the_post_thumbnail($idea_id) . '
                    </div>

                    <div class="seoaic-module">
                    <input type="checkbox" name="regenerate_image" id="regenerate_image">
                    <label for="regenerate_image">' . esc_html__('Don\'t like the image?', 'seoaic') . '<span>' . esc_html__('Generate a new!', 'seoaic') . '</span>
                    <div class="info">
                        <span class="info-btn">?</span>
                            <div class="info-content">
                                <h4>' . esc_html__('Generate new image', 'seoaic') . '</h4>
                                <p>' . esc_html__('You can try regenerating image with another service if you are not satisfied with it.', 'seoaic') . '
                            </p>
                        </div>
                    </div>
                    </label>
                    <div class="selections">
                    <textarea class="promt-key">' . esc_textarea($idea_thumb) . '</textarea>
                    <select class="seoaic-form-item form-select regenerate-select-modal" name="seoaic_regenerate-select-modal" required="">';

            foreach ($image_generators as $key => $image_generator) {
                if ($key === 'no_image') {
                    continue;
                }

                $selected = !empty($data['thumbnail_generator']) && $key === $data['thumbnail_generator'] ? ' selected' : '';
                $image_generator_box .= '<option value="' . esc_attr($key) . '"' . esc_attr($selected) . '>';
                $image_generator_box .=     $image_generator;
                $image_generator_box .= '</option>';
            }

            $image_generator_box .= '
                </select>
                    <div class="btn-sc">
                        <div class="info">
                            <span class="info-btn">?</span>
                            <div class="info-content">
                                <h4>' . esc_html__('Generate new image', 'seoaic') . '</h4>
                                <p>' . esc_html__('You can try regenerating image with another service if you are not satisfied with it.', 'seoaic') . '
                                </p>
                            </div>
                        </div>
                        <button data-callback="regenerate_image_modal" data-desc="' . esc_attr($idea_thumb) . '" data-action="seoaic_regenerate_image" data-type="modal" data-post="' . esc_attr($idea_id) . '" title="' . esc_html__('Regenerate image', 'seoaic') . '" type="button" class="button-primary seoaic-generate-image-button" data-action="seoaic_generate_ideas">' . esc_html__('New image', 'seoaic') . '
                        </button>
                    </div>
                    </div>
                    </div>
                </div>';
        }

        return '
            <div class="generated-post-box">
            ' . $image_generator_box . '
                <div class="generated-post-content">
                    ' . $post_content . '
                </div>
            </div>';
    }

    private function massGenerateProccessFailedPosts($ids = [])
    {
        if (empty($ids)) {
            return;
        }

        // make sure posts with obtained IDs exist
        $failed_post_ids = get_posts([
            'fields' => 'ids',
            'post_type' => 'seoaic-post',
            'post_status' => 'seoaic-idea',
            'include' => $ids,
            'numberposts' => -1,
        ]);

        if (!empty($failed_post_ids)) {
            $option = PostsGenerationLoader::getPostsOption();
            foreach ($failed_post_ids as $failed_post_id) {
                update_post_meta($failed_post_id, 'seoaic_generate_status', 'failed');
                $option['done'][] = $failed_post_id;
            }

            PostsGenerationLoader::setPostsOption($option);
        }
    }

    private function massGenerateProccessCompletedPosts($ids = [])
    {
        if (empty($ids)) {
            return;
        }

        // make sure ideas with obtained IDs exist
        $completed_ideas_ids = get_posts([
            'fields' => 'ids',
            'post_type' => 'seoaic-post',
            'post_status' => 'seoaic-idea',
            'include' => $ids,
            'numberposts' => self::PER_REQUEST__GENERATE_CONTENT,
        ]);


        if (empty($completed_ideas_ids)) {
            return;
        }

        $data = [
            'idea_ids' => $completed_ideas_ids
        ];

        $content_result = $this->seoaic->curl->init('/api/ai/posts/generate/content', $data, true, true, true);
        $generatedPostsIDs = [];

        if (
            !empty($content_result)
            && is_array($content_result)
        ) {
            foreach ($content_result as $key => $generated_data) {
                if (
                    empty($generated_data)
                    || empty($generated_data['ideaId'])
                    || empty($generated_data['content'])
                    || !in_array($generated_data['ideaId'], $completed_ideas_ids)
                ) {
                    continue;
                }

                $id = $generated_data['ideaId'];
                $generatedPostsIDs[] = $id;

                delete_post_meta($id, 'seoaic_generate_status');
                $this->save_generated_post($generated_data);

                /**
                 * Fires after a post has been generated and all the fields have been saved to the database.
                 *
                 * @since 2.16.10
                 *
                 * @param int $id The id of the newly generated post.
                 */
                do_action('seoaic_post_generated', $id);
            }

            if (!empty($generatedPostsIDs)) {
                $generateThumbnailForIDs = array_filter($generatedPostsIDs, function ($id) {
                    return (int) get_post_meta($id, self::GENERATE_THUMBNAIL_FIELD, true) === 1;
                });

                if (!empty($generateThumbnailForIDs)) {
                    $dataThumbnail = [ 'ids' => $generateThumbnailForIDs ];

                    $instance = new ThumbnailsGenerate($this->seoaic);
                    $this->postsMassActionRun($instance, $dataThumbnail);
                }
            }
        }
    }

    public function clearGenerationBackgroundOptionAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $this->clearGenerationBackgroundOption();
    }

    /**
     * Remove background loading process
     */
    public function clearGenerationBackgroundOption()
    {
        PostsGenerationLoader::deletePostsOption();
        SEOAICAjaxResponse::success()->wpSend();
    }

    /**
     * Stop background loading process
     */
    public function postsMassGenerateStop()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $result = $this->seoaic->curl->init('api/ai/posts/generate/clear', ['full' => true], true, false, true);
        $this->debugLog('Clear result:', $result);
        $this->stopGenerateProgress(); // stops backend polling
        $this->massGenerateCheckingStatusUnLock(); // IMPORTANT: don't forget to unlock before any response

        $this->clearGenerationBackgroundOption();
    }

    /**
     * Image uploader
     */
    public static function seoaicImageUploader($save = false)
    {
        $a = false;
        $a .= '<div class="seoaic_image_uploader">

                    <div class="image-preview-wrapper">
                        <div class="top"></div>
                        <div class="bottom">
                            <a
                            href="#"
                            data-upl="' . esc_html__('Set image', 'seoaic') . '"
                            class="remove_selected_image">

                                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-x-circle" viewBox="0 0 16 16">
                                  <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/>
                                  <path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/>
                                </svg>

                            </a>
                            <a
                            href="#"
                            class="change_selected_image upload_image_button">' . esc_html__('Change', 'seoaic') . '</a>
                        </div>
                    </div>

                    <div class="uploader_buttons_wrapper">

                        <a href="#"
                        class="upload_image_button"
                        data-change="' . esc_html__('Change image', 'seoaic') . '"
                        >' . esc_html__('Set image', 'seoaic') . '</a>

                        <input
                        type="hidden"
                        name="seoaic_mass_set_thumbnail"
                        class="set_image_id seoaic-form-item"
                        value=""
                        data-thumb-id="">

                    </div>';

        if ($save) {
            $a .= '<input type="submit" name="submit_image_selector" value="' . esc_html__('Save', 'seoaic') . '" class="button-primary">';
        }

        $a .= '</div>';

        return $a;
    }

    /**
     * Bulk posts image uploader
     */
    public static function seoaicImageUploaderBulk()
    {
        ob_start();
        ?>
        <div class="seoaic_image_uploader">
            <div class="uploader_buttons_wrapper">
                <a href="#"
                    class="seoaic_bulk_upload_image_button"
                    data-change="<?php esc_attr_e('Change all images', 'seoaic');?>"
                ><?php esc_html_e('Set image to all', 'seoaic');?></a>

                <input type="hidden"
                    name="seoaic_mass_set_thumbnail"
                    class="set_image_id seoaic-form-item"
                    value=""
                    data-thumb-id=""
                >
            </div>
       </div>
       <?php

       return ob_get_clean();
    }

    public function get_schedule_posting_date($start_date)
    {
        global $SEOAIC_OPTIONS;

        $days = !empty($SEOAIC_OPTIONS['seoaic_schedule_days']) ? $SEOAIC_OPTIONS['seoaic_schedule_days'] : '';

        if (empty($days)) {
            return false;
        }

        $days_loop = true;
        $datetime = strtotime($start_date);
        $date = $start_date;

        while ($days_loop) {
            $_day = strtolower(date('l', $datetime));

            if (isset($days[$_day])) {
                $_posts = $days[$_day]['posts'];
                $post_types = seoaic_get_post_types();
                $post_types[] = 'seoaic-post';

                $_have_posted_idea = get_posts([
                    'numberposts' => 99,
                    'fields' => 'ids',
                    'post_type' => $post_types,
                    'post_status' => 'future',
                    'meta_query' => [
                        'relation' => 'OR',
                        [
                            'key' => 'seoaic_idea_postdate',
                            'value' => $date,
                            'compare' => 'LIKE'
                        ]
                    ]
                ]);

                if (count($_have_posted_idea) < $_posts) {
                    return $date . ' ' . date('H:i:s', strtotime($days[$_day]['time']));

                    $days_loop = false;
                } else {

                    $datetime = strtotime($date . ' +1 day');
                    $date = date('Y-m-d', $datetime);
                }
            } else {

                $datetime = strtotime($date . ' +1 day');
                $date = date('Y-m-d', $datetime);
            }

        }
    }

    private function get_valid_post_datetime($date_string, $format = 'Y-m-d H:i') {
        $lines = explode("\n", $date_string);
        $date_str = trim(end($lines));
        try {
            $date_obj = new DateTime($date_str . ' 09:00');
            return $date_obj->format($format);
        } catch (Exception $e) {
            return null;
        }
    }


    /**
     * Custom meta for gutenberg sidebar
     */
    public function seoaic_register_post_meta()
    {
        register_post_meta('', '_improvement_type_select', [
            'show_in_rest' => true,
            'single' => true,
            'type' => 'string',
            'auth_callback' => function () {
                return true;
            },
            'default' => 'improve_an_existing'
        ]);

        register_post_meta('', '_thumb_yes_seoaic', [
            'show_in_rest' => true,
            'single' => true,
            'type' => 'boolean',
            'auth_callback' => function () {
                return true;
            }
        ]);

        register_post_meta('', '_frame_yes_seoaic', [
            'show_in_rest' => true,
            'single' => true,
            'type' => 'boolean',
            'auth_callback' => function () {
                return true;
            }
        ]);

        // thumb generate prompt
        register_post_meta('', 'seoaic_generate_description', [
            'show_in_rest' => true,
            'single' => true,
            'type' => 'string',
            'auth_callback' => function () {
                return true;
            }
        ]);

        // improve Instructions Prompt
        register_post_meta('', 'seoaic_improve_instructions_prompt', [
            'show_in_rest' => true,
            'single' => true,
            'type' => 'string',
            'auth_callback' => function () {
                return true;
            }
        ]);

        // Previously backup content before an improvement
        register_post_meta('', 'seoaic_rollback_content_improvement', [
            'show_in_rest' => true,
            'single' => true,
            'type' => 'string',
            'auth_callback' => function () {
                return true;
            }
        ]);

        register_post_meta('', 'seoaic_idea_thumbnail_generator', [
            'show_in_rest' => true,
            'single' => true,
            'type' => 'string',
            'auth_callback' => function () {
                return true;
            }
        ]);

        register_post_meta('', 'thumbnail_generated', [
            'show_in_rest' => true,
            'single' => true,
            'type' => 'boolean',
            'auth_callback' => function () {
                return true;
            }
        ]);

        register_post_meta('', 'thumbnail_generate_prompt', [
            'show_in_rest' => true,
            'single' => true,
            'type' => 'string',
            'auth_callback' => function () {
                return true;
            }
        ]);

        register_post_meta('', 'seoaic_article_description', [
            'show_in_rest' => true,
            'single' => true,
            'type' => 'string',
            'auth_callback' => function () {
                return true;
            }
        ]);

        register_post_meta('post', 'seoaic_article_subtitles', [
            'show_in_rest' => [
                'schema' => [
                    'type' => 'array',
                    'items' => [
                        'type' => 'string',
                    ],
                ],
            ],
            'single' => true,
            'type' => 'array',
        ]);

        register_post_meta('post53', 'seoaic_article_keywords', [
            'show_in_rest' => [
                'schema' => [
                    'type' => 'array',
                    'items' => [
                        'type' => 'string',
                    ],
                ],
            ],
            'single' => true,
            'type' => 'array',
        ]);
    }

    /**
     * Collects internal links by pulling data from related posts (keywords-posts relation)
     * @param int $ideaId ID of Idea or Post to collect the links for
     * @param int $n Number of links, default 5
     * @return string Formatted string that is used for posts generation
     */
    public function getInternalLinksString($ideaId = null, $n = 5): string
    {
        $internalLinksString = $this->seoaic->internal_links->forIdea($ideaId, $n)->toString();

        return $internalLinksString;
    }

    public static function seoaic_dropdown_cats($taxonomy, $category, $class = 'seoaic-form-item form-select', $id = 'seoaic-category', $name = 'seoaic_category')
    {
        return wp_dropdown_categories(
            [
                'echo' => false,
                'taxonomy' => $taxonomy,
                'hide_if_empty' => false,
                'show_option_none' => 'Select category',
                'hide_empty' => '0',
                'show_option_all' => '',
                'value_field' => '',
                'selected' => $category,
                'id' => $id,
                'class' => $class,
                'name' => $name,
                'required' => true,
            ]
        );
    }

    public static function getCategoriesOfPosttype()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        global $SEOAIC_OPTIONS;

        $post_type = "post";

        if (empty($_REQUEST['post_type'])) {
            wp_die();
        } else {
            $post_type = $_REQUEST['post_type'];
        }

        $html = seoaic_get_categories($post_type);

        wp_send_json(
            [
                "select" => $html,
            ]
        );



        $taxonomy = get_object_taxonomies($post_type);
        $taxonomy = $taxonomy[0] === "language" ? ($taxonomy[1] === "post_translations" ? ($taxonomy[2] === "product_type" ? "product_cat" : $taxonomy[2]) : $taxonomy[1]) : $taxonomy[0];

        $separator = ', ';

        if (!empty($taxonomy) && !is_wp_error($taxonomy)) {

            $html = '';

            $terms = self::seoaic_dropdown_cats($taxonomy, $SEOAIC_OPTIONS["seoaic_default_category"], 'seoaic-form-item form-select mb-5px', 'seoaic_default_category', 'seoaic_default_category');

            $html .= '<div class="col-12 col-12 seoaic-select-post-type-cat"><label for="seoaic_default_category">' . esc_html__('Default posts category') . '</label>';
            $html .= $terms;
            $html .= '</div>';

            wp_send_json(
                [
                    "select" => $html,
                    "taxonomy" => $taxonomy,
                    "selected" => $SEOAIC_OPTIONS["seoaic_default_category"],
                ]
            );
        }

        wp_die();
    }

    public static function selectCategoriesIdea()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        global $SEOAIC_OPTIONS;

        $category = !empty($SEOAIC_OPTIONS["seoaic_default_category"]) ? $SEOAIC_OPTIONS["seoaic_default_category"] : 0;

        $id = 0;
        if (!empty($_REQUEST['idea_post_id'])) {
            $id = $_REQUEST['idea_post_id'];
            $category = get_post_meta($id, 'seoaic_idea_content');
            $category = !empty(json_decode($category[0])->idea_category) ? json_decode($category[0])->idea_category : $SEOAIC_OPTIONS["seoaic_default_category"];

            $post_type = get_post_meta($id, 'seoaic_idea_content');
            $post_type = !empty(json_decode($post_type[0])->idea_post_type) ? json_decode($post_type[0])->idea_post_type : $_REQUEST['post_type'];
        }

        $post_type = !empty($_REQUEST['post_type']) ? $_REQUEST['post_type'] : "post";

        $html = seoaic_get_categories($post_type, $id);

        wp_send_json(
            [
                "select" => $html,
                "idea" => !empty($id) ? $id : '',
                "post_type" => !empty($_REQUEST['post_type']) ? $_REQUEST['post_type'] : '',
            ]
        );

        $taxonomy = get_object_taxonomies($post_type);
        $taxonomy = $taxonomy[0] === "language" ? ($taxonomy[1] === "post_translations" ? ($taxonomy[2] === "product_type" ? "product_cat" : $taxonomy[2]) : $taxonomy[1]) : $taxonomy[0];

        $separator = ', ';

        if (!empty($taxonomy) && !is_wp_error($taxonomy)) {

            $html = '';

            $terms = self::seoaic_dropdown_cats($taxonomy, $category);

            $html .= '<div id="seoaic-idea-content-category" class="seoaic-idea-content-section">
                      <div class="top">
                          <span class="seoaic-section-idea-title">' . esc_html__('Category', 'seoaic') . '</span><span class="icon"></span>
                      </div>
                      <div class="choose-label mb-19">' . esc_html__('Select a category', 'seoaic') . '</div>
                      <div class="choose-switchers">';
            $html .= $terms;
            $html .= '</div></div>';

            wp_send_json(
                [
                    "select" => $html,
                    "taxonomy" => $taxonomy,
                    "selected" => $SEOAIC_OPTIONS["seoaic_default_category"],
                    "idea" => !empty($id) ? $id : '',
                    "post_type" => isset($_REQUEST['post_type']) ? $_REQUEST['post_type'] : '',
                ]
            );
        }

        wp_die();
    }

    public function countContentWords($post_id, $post)
    {
        if (
            empty($post)
            || SEOAIC_IDEAS::IDEA_TYPE == $post->post_type // ideas - skip
            || SEOAIC_KEYWORDS::KEYWORD_POST_TYPE == $post->post_type // keywords - skip
            || wp_is_post_revision($post_id)
        ) {
            return;
        }

        $seoaicPosted = get_post_meta($post_id, 'seoaic_posted', true);
        if (1 == $seoaicPosted) {
            $this->saveWordsCountMeta($post);

            $this->setSEOAICPostsWordsCount();
        }
    }

    public function setCreatedDate($post_id, $post)
    {
        if (
            empty($post)
            || SEOAIC_IDEAS::IDEA_TYPE == $post->post_type  // ideas - skip
            || SEOAIC_KEYWORDS::KEYWORD_POST_TYPE == $post->post_type // keywords - skip
            || wp_is_post_revision($post_id)
        ) {
            return;
        }

        $seoaicPosted = get_post_meta($post_id, 'seoaic_posted', true);
        if (1 == $seoaicPosted) {
            $postCreatedDate = get_post_meta($post_id, 'post_created_date', true);
            if (empty($postCreatedDate)) {
                update_post_meta($post_id, 'post_created_date', time());
            }
        }
    }

    public function setSEOAICPostsWordsCount()
    {
        $allSEOAICPosts = get_posts([
            'numberposts'   => -1,
            'post_type'     => 'any',
            'post_status'   => 'any',
            'lang'          => '',
            'meta_query'    => [
                'relation'  => 'AND',
                [
                    'key'       => 'seoaic_posted',
                    'value'     => '1',
                    'compare'   => '=',
                ],
                [
                    'key'       => self::WORDS_COUNT_FIELD,
                    'compare'   => 'NOT EXISTS',
                ],
            ],
        ]);

        foreach ($allSEOAICPosts as $post) {
            if (SEOAIC_IDEAS::IDEA_TYPE != $post->post_type) {
                $this->saveWordsCountMeta($post);
            }
        }
    }

    private function saveWordsCountMeta($post)
    {
        $content = strip_tags(strip_shortcodes($post->post_content));
        // could be problems with non-latin languages
        // maybe switch to counting whitespaces
        $wordsCount = str_word_count($content, 0, "Á,Â,Ã,Ä,Å,Æ,Ç,È,É,Ê,Ë,Ì,Í,Î,Ï,Ї,Ð,Ñ,Ò,Ó,Ô,Õ,Ö,×,Ù,Ú,Û,Ü,Ý,Þ,ß,à,á,â,ã,ä,å,æ,ç,è,é,ê,ë,ì,í,î,ï,ї,ð,ñ,ò,ó,ô,õ,ö,ù,ú,û,ü,ý,þ,ÿ,ß");
        update_post_meta($post->ID, self::WORDS_COUNT_FIELD, $wordsCount);
    }

    public static function getMaxWordsCount()
    {
        global $wpdb;

        $query = "SELECT max(cast(meta_value as unsigned)) FROM {$wpdb->prefix}postmeta WHERE meta_key = %s";
        $preparedQuery = $wpdb->prepare($query, [
            self::WORDS_COUNT_FIELD,
        ]);
        $max = $wpdb->get_var($preparedQuery);

        return $max;
    }

    public function unregisterCrons()
    {
        $this->debugLog('[CRON]');
        $this->unregisterPostsCheckStatusCron(self::GENERATE_MODE);
        (new PostsMassEdit($this->seoaic))->unregisterPostsCheckStatusCron();
        (new PostsMassReview($this->seoaic))->unregisterPostsCheckStatusCron();
        (new PostsMassTranslate($this->seoaic))->unregisterPostsCheckStatusCron();
        (new ThumbnailsGenerate($this->seoaic))->unregisterPostsCheckStatusCron();
    }

    private function registerPostsGenerateCheckStatusCron()
    {
        $this->debugLog('[CRON]');
        if (!wp_next_scheduled('seoaic_posts_generate_check_status_cron_hook')) {
            wp_schedule_event(time() + 3 * 60, '5_minutes', 'seoaic_posts_generate_check_status_cron_hook');
        }
    }

    private function unregisterPostsGenerateCheckStatusCron()
    {
        $this->debugLog('[CRON]');
        $timestamp = wp_next_scheduled('seoaic_posts_generate_check_status_cron_hook');
        wp_unschedule_event($timestamp, 'seoaic_posts_generate_check_status_cron_hook');
    }

    public function add_cron_interval($schedules)
    {
        $schedules['5_minutes'] = [
            'interval' => 5 * 60,
            'display'  => esc_html__('Every 5 minutes'),
        ];
        $schedules['30_seconds'] = [
            'interval' => 30,
            'display'  => esc_html__('Every 30 seconds'),
        ];

        return $schedules;
    }

    public function cronPostsGenerateCheckStatus()
    {
        $this->debugLog('[CRON] cronExec');
        $this->postsMassGenerateCheckStatus();

        return;
    }

    public function title_like_posts_where($where, $wp_query)
    {
        global $wpdb;

        if ($post_title_like = $wp_query->get('post_title_like')) {
            $post_title_like = str_replace(['’', '‘'], "'", urldecode($post_title_like));
            $post_title_like = $wpdb->esc_like($post_title_like);
            $post_title_like = '%' . $post_title_like . '%';
            $where .= $wpdb->prepare(' AND ' . $wpdb->posts . '.post_title LIKE %s', $post_title_like);
        }

        return $where;
    }

    public function contentLikePostsWhere($where, $wp_query)
    {
        global $wpdb;

        if ($postTitleLike = $wp_query->get('post_content_like')) {
            $postTitleLike = str_replace(['’', '‘'], "'", urldecode($postTitleLike));
            $postTitleLike = $wpdb->esc_like($postTitleLike);
            $postTitleLike = '%' . $postTitleLike . '%';
            $where .= $wpdb->prepare(' AND ' . $wpdb->posts . '.post_content LIKE %s', $postTitleLike);
        }

        return $where;
    }

    public function contentNotLikePostsWhere($where, $wp_query)
    {
        global $wpdb;

        if ($string = $wp_query->get('post_content_not_like')) {
            $string = str_replace(['’', '‘'], "'", urldecode($string));
            $string = $wpdb->esc_like($string);
            $string = '%' . $string . '%';
            $where .= $wpdb->prepare(' AND ' . $wpdb->posts . '.post_content NOT LIKE %s', $string);
        }

        return $where;
    }

    function seoaicWorkaroundGetPagenumLink($url) {
        global $SEOAIC;

        if ($SEOAIC->multilang->is_multilang()) {
            $partsToFind = [];

            $partsToFind[] = $SEOAIC->multilang->get_current_language('code');
            $partsToFind[] = $SEOAIC->multilang->get_default_language('code');

            $partsToFind = array_filter($partsToFind, function ($item) {
                return !empty($item);
            }); // filter only with a value
            $partsToFind = array_map(function ($item) {
                return '\/' . $item . '\/';
            }, $partsToFind); // wrap with slashes
            $pattern = '/(' . implode('|', $partsToFind) . ')/';

            $url = preg_replace($pattern, '/', $url);
        }

        return $url;
    }

    public function postsMassEditAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $__REQUEST = wp_unslash($_REQUEST);
        $isGenerateThumbnail = FormHelpers::isCheckboxChecked('seoaic_generate_thumbnail');

        $this->cleanOldRevisions();

        if (
            !empty($__REQUEST['posts_edit_add_link'])
            || !empty($__REQUEST['seoaic_posts_mass_replacement'])
            || !empty($__REQUEST['mass_prompt'])
            || (
                !empty($__REQUEST['seoaic_presets'])
                && (
                    in_array('in_depth', $__REQUEST['seoaic_presets'], true)
                    || in_array('humanize', $__REQUEST['seoaic_presets'], true)
                )
            )
        ) {
            $instance = new PostsMassEdit($this->seoaic);
            $sendResponse = !$isGenerateThumbnail;

            $this->postsMassActionRun($instance, [], $sendResponse);
        }

        if ($isGenerateThumbnail) {
            $instance = new ThumbnailsGenerate($this->seoaic);
            $instance->preRun($__REQUEST); // sets needed meta fields required for thumbnail generation process to run

            // fix: pull & process completed posts which were not pulled for some reasons
            $this->postsMassActionCheckStatus($instance, false);
            $this->postsMassActionRun($instance);
        }
    }

    public function postsMassEditCheckStatusAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $instance = new PostsMassEdit($this->seoaic);
        $this->postsMassActionCheckStatus($instance);
    }

    public function postsMassEditStopAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $instance = new PostsMassEdit($this->seoaic);
        $this->postsMassActionStop($instance);
    }


    public function resetReviewResults($post_id, $post)
    {
        if (
            empty($post)
            || SEOAIC_KEYWORDS::KEYWORD_POST_TYPE != $post->post_type
            || SEOAIC_IDEAS::IDEA_TYPE != $post->post_type
            || 1 == get_post_meta($post_id, 'seoaic_posted', true)
        ) {
            return;
        }
        //reset all review data
        (new PostsMassReview($this->seoaic))->resetReviewResults($post_id);
    }

    public function resetOnboardingPostData($post_id, $post)
    {
        if (
            defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ||
            empty($post) ||
            'revision' === $post->post_type ||
            empty(get_post_meta($post_id, 'seoaic_ob_needs_review', true))
        ) {
            return;
        }

        $old_status = get_post_field('post_status', $post_id);
        $new_status = $post->post_status;

        if (
            $old_status === 'draft' &&
            in_array($new_status, ['publish', 'future'], true) &&
            1 == get_post_meta($post_id, 'seoaic_posted', true)
        ) {
            delete_post_meta($post_id, 'seoaic_ob_needs_review');
            delete_post_meta($post_id, 'seoaic_ob_posting_date');
        }
    }

    public function postsMassReviewAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $instance = new PostsMassReview($this->seoaic);
        $this->postsMassActionRun($instance);
    }

    public function postsMassReviewCheckStatusAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $instance = new PostsMassReview($this->seoaic);
        $this->postsMassActionCheckStatus($instance);
    }

    public function postsMassReviewStopAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $instance = new PostsMassReview($this->seoaic);
        $this->postsMassActionStop($instance);
    }


    public function postsMassTranslateAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $instance = new PostsMassTranslate($this->seoaic);
        $this->postsMassActionRun($instance);
    }


    public function postsMassThumbnailsGenerateCheckStatusAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $instance = new ThumbnailsGenerate($this->seoaic);
        $this->postsMassActionCheckStatus($instance);
    }


    /**
     * @param object $instance AbstractPostsMassAction class instanse
     * @param array $data Optional data. If empty - uses $_REQUEST array
     * @param bool $sendResponse Whether to send ajax response or not. Can be used in multi mass actions run to prevent a break after the first action
     */
    public function postsMassActionRun($instance, $data = [], $sendResponse = true)
    {
        try {
            $data = !empty($data) ? $data : $_REQUEST;
            $data = $instance->prepareData($data);
            $result = $instance->sendActionRequest($data);

            if ($instance->processActionResults($result)) {
                $errors = $instance->getErrors();

                if (empty($errors)) {
                    if ($sendResponse) {
                        SEOAICAjaxResponse::success($instance->successfullRunMessage)->wpSend();
                    }
                } else {
                    SEOAICAjaxResponse::alert("Run with some errors:<br>" . $errors)->wpSend();
                }
            }
        } catch (Exception $e) {
            SEOAICAjaxResponse::error($e->getMessage())->wpSend();
        }

        // SEOAICAjaxResponse::error('Something went wrong')->wpSend();
    }

    public function postsMassTranslateCheckStatusAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $instance = new PostsMassTranslate($this->seoaic);

        $this->postsMassActionCheckStatus($instance);
    }
    public function postsMassTranslateStopAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $instance = new PostsMassTranslate($this->seoaic);

        $this->postsMassActionStop($instance);
    }

    public function postsMassActionCheckStatus($instance, $sendResponse = true)
    {
        list('done' => $done, 'failed' => $failed, 'is_running' => $isRunning) = $instance->getStatusResults();
        $status = $isRunning ? 'in progress' : 'complete';
        $message = $isRunning ? '' : $instance->completeMessage;

        if ($sendResponse) {
            SEOAICAjaxResponse::success($message)->addFields([
                'status'    => $status,
                'done'      => $done,
                'failed'    => $failed,
            ])->wpSend();
        }
    }

    public function postsMassActionStop($instance)
    {
        $instance->stop();

        SEOAICAjaxResponse::alert($instance->stopMessage)->wpSend();
    }

    public function setPostToTrash() {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $ids = !empty($_POST['ids']) ? $_POST['ids'] : '';

        if (empty($ids)) {
            SEOAICAjaxResponse::alert(esc_html__('You have not selected any posts to delete', 'seoaic'))->wpSend();
        }

        foreach ($ids as $id) {
            wp_trash_post($id);
        }

        SEOAICAjaxResponse::reload()->wpSend();
    }

    public function setPostsStatusAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        if (
            empty($_POST['ids'])
            || !is_array($_POST['ids'])
            || empty($_POST['status'])
        ) {
            SEOAICAjaxResponse::alert(esc_html__('Wrong data', 'seoaic'))->wpSend();
        }

        $postsRepository = new PostRepository();
        $posts = $postsRepository->getByIDs($_POST['ids']);

        if (empty($posts)) {
            SEOAICAjaxResponse::alert(esc_html__('Posts not found', 'seoaic'))->wpSend();
        }

        $postStatuses = get_post_statuses();

        if (!in_array($_POST['status'], array_keys($postStatuses))) {
            SEOAICAjaxResponse::alert(esc_html__('Wrong post status sent', 'seoaic'))->wpSend();
        }

        foreach ($posts as $post) {
            $postsRepository->updateField((int)$post->ID, 'post_status', $_POST['status']);
        }

        SEOAICAjaxResponse::success()->wpSend();
    }

    public function updatePostsVisibility()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $id = !empty($_POST['id']) ? intval($_POST['id']) : '';
        $value = !empty($_POST['value']) ? intval($_POST['value']) : '';
        $meta_key = 'seoaic_visible_post';

        if (empty($id)) {
            SEOAICAjaxResponse::alert(esc_html__('No post selected.', 'seoaic'))->wpSend();
        }

        update_post_meta($id, $meta_key, $value);

        SEOAICAjaxResponse::success()->wpSend();
    }

    public function postsMassEditUndoAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $__POST = wp_unslash($_POST);

        $this->cleanOldRevisions();

        if (empty($__POST['item_ids'])) {
            SEOAICAjaxResponse::alert(esc_html__('Empty IDs param', 'seoaic'))->wpSend();
        }

        $ids = explode(',', $__POST['item_ids']);

        // sanitize the ids param and filter the numeric values only
        $ids = array_filter(
            array_map(function ($item) {
                return esc_html($item);
            }, $ids),
            function ($id) {
                return is_numeric($id);
            }
        );

        if (empty($ids)) {
            SEOAICAjaxResponse::alert(esc_html__('Empty IDs param', 'seoaic'))->wpSend();
        }

        $restored = [];
        $failed = [];

        foreach ($ids as $id) {
            if ($this->postRevisionRepository->hasRevision($id)) {
                if ($this->postRevisionRepository->restore($id)) {
                    $restored[] = $id;
                } else {
                    $failed[] = $id;
                }
            }
        }

        $msgRestored = esc_html__("These posts are restored to their previous version:", "seoaic") . '<br>' . implode('<br>', $restored);
        $msgFailed = esc_html__("Failed for:", "seoaic") . '<br>' . implode('<br>', $failed);
        $msg = !empty($restored) ? $msgRestored : '';
        $msg .= !empty($failed) ? (!empty($msg) ? '<br><br>' : '') . $msgFailed : '';

        $msg = empty($msg) ? esc_html__("Selected posts has no previously saved content.", "seoaic") : $msg;

        SEOAICAjaxResponse::success()->addFields([
            'content' => [
                'restoredIDs'   => $restored,
                'message'       => $msg,
            ],
        ])->wpSend();
    }

    private function cleanOldRevisions()
    {
        $revisionsAll = $this->postRevisionRepository->getAll();

        if (!empty($revisionsAll)) {
            foreach ($revisionsAll as $revision) {
                if ($revision->post_date < wp_date('Y-m-d H:i:s', strtotime("-1 day"))) {
                    $this->postRevisionRepository->delete($revision->ID);
                }
            }
        }
    }

    public function setMassThumbnail()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $__POST = wp_unslash($_POST);

        if (
            empty($__POST['data'])
            || !is_array($__POST['data'])
        ) {
            SEOAICAjaxResponse::alert(esc_html__("Wrong data format", "seoaic"))->wpSend();
        }

        foreach ($__POST['data'] as $row) {
            if (
                !empty($row['id'])
                && is_numeric($row['id'])
                && !empty($row['thumbnail_id'])
                && is_numeric($row['thumbnail_id'])
            ) {
                set_post_thumbnail($row['id'], $row['thumbnail_id']);
            }
        }

        SEOAICAjaxResponse::success()->wpSend();
    }

    public function get_post_statuses_with_dates($filter = true) {
        $results = $this->fetch_posts_from_db();

        if (empty($results)) {
            return esc_html__('No data found', 'seoaic');
        }

        if ($filter) {
            $dates = $this->filter_posts_by_status($results);

            return $dates;
        }

        return $results;
    }

    private function fetch_posts_from_db() {
        global $wpdb;
        $allowed_post_types = seoaic_get_post_types();
        $allowed_post_types_sql = "'" . implode("','", array_map('esc_sql', $allowed_post_types)) . "'";

        $results = $wpdb->get_results(
            "SELECT p.ID,
                    p.post_status,
                    p.post_date,
                    p.post_title
             FROM {$wpdb->posts} p
             INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
             WHERE pm.meta_key = 'seoaic_posted'
               AND pm.meta_value = 1
               AND p.post_type IN ($allowed_post_types_sql)
               AND p.post_status IN ('draft', 'publish', 'future')
             ORDER BY p.post_date ASC",
            OBJECT
        );

        foreach ($results as $result) {
            $result->post_url = get_permalink($result->ID);
        }

        return $results;
    }

    private function filter_posts_by_status($results) {
        $dates = [
            'draft'     => [],
            'published' => [],
            'scheduled' => [],
        ];

        foreach ($results as $post) {
            if ($post->post_status === 'draft') {
                $dates['draft'][] = $post->post_date;
            } elseif ($post->post_status === 'publish') {
                $dates['published'][] = $post->post_date;
            } elseif ($post->post_status === 'future') {
                $dates['scheduled'][] = $post->post_date;
            }
        }

        return $dates;
    }

    public function generateLeadFormAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $instance = new LeadsFormGenerate($this->seoaic);
        $this->postsMassActionRun($instance);
    }

    public function generateLeadFormCheckStatusAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $instance = new LeadsFormGenerate($this->seoaic);
        $this->postsMassActionCheckStatus($instance);
    }

    public function generateLeadFormStopAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $instance = new LeadsFormGenerate($this->seoaic);
        $this->postsMassActionStop($instance);
    }

    public function generateFAQAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $instance = new FAQGenerate($this->seoaic);
        $this->postsMassActionRun($instance);
    }

    public function generateFAQAjaxCheckStatus()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $instance = new FAQGenerate($this->seoaic);
        $this->postsMassActionCheckStatus($instance);
    }

    public function generateFAQAjaxStop()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $instance = new FAQGenerate($this->seoaic);
        $this->postsMassActionStop($instance);
    }

    public function generateThumbnailStopAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $instance = new ThumbnailsGenerate($this->seoaic);
        $this->postsMassActionStop($instance);
    }
}
