<?php

namespace SEOAIC;

use DateInterval;
use DateTime;
use Exception;
use SEOAIC\helpers\SEOPluginsHelper;
use SEOAIC\posts_mass_actions\ContentImprovementSuggestionsGenerate;
use SEOAIC\repositories\ContentImprovementSuggestionsRepository;
use SEOAIC\repositories\PostRepository;
use SEOAIC\traits\MassActionsWorkflow;
use WP_Post;
use WP_Query;
use SEOAIC\posts_mass_actions\ContentImprovementAutoImprovement;
use SeoaicAjaxValidation;

class SeoaicContentImprovement
{
    use MassActionsWorkflow;

    private $seoaic;
    private $postsRepository;
    private $contentImprovementSuggestionsRepository;

    public const GOOGLE_POST_KEYWORDS_COMPETITORS = 'seoaic_google_keywords_competitors';
    public const GOOGLE_POST_KEYWORDS_ANALYZE = 'seoaic_google_keywords_analyze';
    public const GOOGLE_POST_SEO_SUGGESTIONS = 'seoaic_gpt_seo_suggestions';
    public const GOOGLE_POST_IMPROVEMENT_IDEAS = 'seoaic_post_improvements_ideas';
    public const ORIGINAL_SEO_DATA = 'seoaic_post_original_seo_data';
    public const POST_CONTENT_IS_SCANNIG = 'seoaic_post_content_is_scanning';
    public const CI_PAGE_SCORE_META = 'seoaic_ci_page_score';

    public const CLICKS_FIELD = 'clicks';
    public const INDEX_FIELD = 'index';
    public const IMPRESSION_FIELD = 'impressions';
    public const CTR_FIELD = 'ctr';
    public const POSITION_FIELD = 'position';
    public const CLICKS_DIFF_FIELD = 'clicksDiff';
    public const CLICKS_GROWTH_FIELD = 'clicksGrowth';
    public const QUERY_GOOGLE_FIELD = 'google_query';
    public const TOP_KEYWORD_FIELD = 'top_keyword';
    public const TOP_KEYWORD_RANK_FIELD = 'top_keyword_rank';
    public const MONITERY_FIELD = 'value';
    public const BROKEN_INTERNAL_LINKS = 'seoai_broken_internal_links';

    function __construct($_seoaic)
    {
        $this->seoaic = $_seoaic;
        $this->postsRepository = new PostRepository();
        $this->contentImprovementSuggestionsRepository = new ContentImprovementSuggestionsRepository($this->seoaic);

        add_action('template_redirect', [$this, 'seoaicRedirectFunction']);

        add_action('wp_ajax_seoaic_redirect', [$this, 'redirect']);
        add_action('wp_ajax_seoaic_restore_post', [$this, 'restorePost']);
        // add_action('wp_ajax_seoaic_bulk_restore_post', [$this, 'bulkRestorePost']);
        add_action('wp_ajax_seoaic_add_site_to_google_console', [$this, 'addSiteToGoogleConsole']);
        // add_action('wp_ajax_seoaic_pages_for_redirect', [$this, 'getPagesForRedirect']);
        add_action('wp_ajax_seoaic_get_data_for_pruning_chart', [$this, 'getDataForPruningChart']);
        add_action('wp_ajax_seoaic_get_keyword_competitors', [$this, 'getKeywordCompetitors']);
        add_action('wp_ajax_seoaic_get_content_improvement_section_html', [$this, 'getContentImprovementSectionHTML']);
        add_action('wp_ajax_seoaic_improvements_add_to_queue', [$this, 'improvementsAddToQueue']);
        add_action('wp_ajax_seoaic_generate_improvement_text', [$this, 'generateImprovementTextAjax']);
        add_action('wp_ajax_seoaic_add_manually_improvement_text', [$this, 'addManuallyImprovementText']);
        add_action('wp_ajax_seoaic_data_improvements_load_job', [$this, 'dataImprovementsLoadJob']);
        add_action('wp_ajax_seoaic_get_automated_suggestions_section', [$this, 'getAutomatedSuggestionsSectionAjax']);
        add_action('wp_ajax_seoaic_automated_suggestions_check_status', [$this, 'automatedSuggestionsCheckStatusAjax']);
        add_action('wp_ajax_seoaic_automated_suggestions_stop_polling', [$this, 'automatedSuggestionsStopPollingAjax']);
        add_action('wp_ajax_seoaic_seo_meta_improvement_modal_html', [$this, 'seoMetaImprovementModal_HTML']);
        add_action('wp_ajax_seoaic_set_new_seo_data', [$this, 'set_new_seo_data']);
        add_action('wp_ajax_seoaic_edit_seo_data_preview', [$this, 'edit_seo_data_preview']);
        add_action('wp_ajax_seoaic_get_page_analyze', [$this, 'getPageAnalyze']);
        add_action('wp_ajax_seoaic_get_ai_suggestions', [$this, 'getAISuggestions']);
        add_action('wp_ajax_seoaic_clean_serp_data', [$this, 'cleanSerpData']);
        add_action('wp_ajax_seoaic_clear_analysis_queue', [$this, 'clearAnalysisQueue']);
        add_action('wp_ajax_seoaic_content_imptovement_get_pages', [$this, 'getPages']);
        add_action('wp_ajax_seoaic_ranking_get_pages', [$this, 'getRankingPages']);
        add_action('wp_ajax_seoaic_get_keywords_for_page', [$this, 'getKeywordsForPage']);
        add_action('wp_ajax_seoaic_get_data_for_keywords_chart', [$this, 'getDataForKeywordsChart']);
        add_action('wp_ajax_seoaic_seoaic_automated_pruning_pages', [$this, 'getAutomatedPruningPages']);
        add_action('wp_ajax_seoaic_keyword_cannibalisation_pages', [$this, 'getKeywordCannibalisationPages']);
        add_action('wp_ajax_seoaic_mass_suggestion', [$this, 'massSuggestion']);
        add_action('wp_ajax_seoaic_comparison_pages', [$this, 'getComparisonPages']);
        add_action('wp_ajax_seoaic_keyword_analysation_pages', [$this, 'getKeywordAnalysationPages']);
        add_action('wp_ajax_seoaic_verify_gsc_integration', [$this, 'verifyGSCIntegration']);
        add_action('wp_ajax_seoaic_check_broken_links', [$this, 'checkBrokenLinks']);
        add_action('wp_ajax_seoaic_get_links_from_content', [$this, 'getLinksFromContent']);
        add_action('wp_ajax_seoaic_automated_suggestion_action', [$this, 'automatedSuggestionActionAjax']);
        add_action('wp_ajax_seoaic_content_improvement_post', [$this, 'contentImprovementPost']);
        add_action('wp_ajax_seoaic_automated_improvement_content_single_tag', [$this, 'improveAutoImprovementSingleTagAjax']);
        add_action('wp_ajax_seoaic_replace_content_block', [$this, 'replaceContentBlockAjax']);
        add_action('wp_ajax_seoaic_automated_improvement_run', [$this, 'automatedImprovementRunAjax']);
        add_action('wp_ajax_seoaic_automated_improvement_check_status', [$this, 'automatedImprovementCheckStatusAjax']);
        add_action('wp_ajax_seoaic_automated_improvement_stop_polling', [$this, 'automatedImprovementStopPollingAjax']);
        add_action('wp_ajax_seoaic_replace_content_block', [$this, 'replaceContentBlock']);
        add_action('wp_ajax_seoaic_automated_improvement_republish', [$this, 'republishPostAjax']);
        add_action('wp_ajax_seoaic_get_data_for_individual_page_chart', [$this, 'getDataForIndividualPageChart']);

        add_filter('cron_schedules', [$this, 'add_cron_interval']);
    }

    /**
     * Redirect and save post
     */
    public function redirect()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $request = wp_unslash($_REQUEST);

        if (!empty($request['item_url'])) {
            $redirect_from = !empty($request['redirect_from']) ? urldecode(rtrim($request['redirect_from'], '/')) : urldecode(rtrim($request['item_url'], '/'));
            $redirect_to = urldecode(rtrim($request['item_url'], '/'));
            $code = !empty($request['code']) ? sanitize_text_field($request['code']) : '410';
            $reload = !empty($request['reload']) ? $request['reload'] : false;

            $this->setRedirectFields($redirect_from, $redirect_to, $code, $reload);
        }
    }

    public function setRedirectFields($source, $destination, $code, $reload = false)
    {
        global $SEOAIC_OPTIONS;

        if (isset($SEOAIC_OPTIONS['redirect'][$code][$source]) && array_key_exists($source, $SEOAIC_OPTIONS['redirect'][$code]) && $SEOAIC_OPTIONS['redirect'][$code][$source]['destination'] !== $destination) {
            $SEOAIC_OPTIONS['redirect'][$code][$source]['destination'] = $destination;
        } else {
            $current_date = time();

            $SEOAIC_OPTIONS['redirect'][$code][$source] = [
                'destination' => $destination,
                'created_at' => $current_date,
            ];

            if ($code === '410') {

                $post_id = url_to_postid($source);

                if (!empty($post_id)) {
                    $trashed_post = wp_trash_post($post_id);

                    if ($trashed_post !== false) {
                        $SEOAIC_OPTIONS['redirect'][$code][$source]['deleted_at'] = time();
                        $SEOAIC_OPTIONS['redirect'][$code][$source]['post_id'] = $post_id;
                    }
                }
            }
        }

        update_option('seoaic_options', $SEOAIC_OPTIONS);

        $isReload = filter_var($reload, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);

        if ($isReload === true) {
            SEOAICAjaxResponse::reload()->wpSend();
        }

        SEOAICAjaxResponse::alert('The redirect has been successfully installed, you can view your redirects at this link <a href="'. admin_url('admin.php?page=seoaic-redirects') .'" target="_blank">Redirect page</a>')->addFields(['is_redirected' => true])->wpSend();
    }

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

        global $SEOAIC_OPTIONS;

        $post = wp_unslash($_POST);
        $suggestions = !empty($post['suggestions']) ? $post['suggestions'] : [];

        if (empty($suggestions) || empty($suggestions['data'])) {
            SEOAICAjaxResponse::alert('Please select suggestion')->wpSend();
        }

        switch ($suggestions['action']) {
            case 'apply':
                $applySuggestions = $this->applySuggestions($suggestions['data']);

                update_option('seoaic_options', $SEOAIC_OPTIONS);

                if (!empty($applySuggestions)) {
                    $suggested = $this->generateDeletedPostsTable($applySuggestions);
                    SEOAICAjaxResponse::success()
                        ->addFields(['suggested_html' => $suggested])
                        ->wpSend();
                }

                break;
            case 'revert':
                $this->revertSuggestions($suggestions['data']);
                update_option('seoaic_options', $SEOAIC_OPTIONS);
                break;
            case 'delete':
                $data = $this->deleteSuggestions($suggestions['data']);

                update_option('seoaic_options', $SEOAIC_OPTIONS);

                if (!empty($data)) {
                    $suggested = $this->generateDeletedPostsTable($data);
                    SEOAICAjaxResponse::success()
                        ->addFields(['suggested_html' => $suggested])
                        ->wpSend();
                }

                break;
            default:
                SEOAICAjaxResponse::alert('Invalid action')->wpSend();
        }

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

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

        $detectedPosts = [];

        foreach ($data as $code => $item) {
            if (!empty($item['redirects'])) {
                foreach ($item['redirects'] as $redirect) {

                    $from = !empty($redirect['from']) ? urldecode(rtrim($redirect['from'], '/')) : '';
                    $to = !empty($redirect['to']) ? urldecode(rtrim($redirect['to'], '/')) : '';
                    $post_id = !empty($redirect['id']) ? intval($redirect['id']) : 0;

                    if( (int)$code === 301 && $from === $to ) {
                        continue;
                    }

                    $SEOAIC_OPTIONS['redirect'][$code][$from] = [
                        'destination' => $to,
                        'created_at' => time()
                    ];

                    if ((int)$code === 410) {
                        if (!empty($post_id)) {
                            $trashed_post = wp_trash_post($post_id);

                            if ($trashed_post !== false) {
                                $SEOAIC_OPTIONS['redirect'][$code][$from]['deleted_at'] = time();
                                $SEOAIC_OPTIONS['redirect'][$code][$from]['post_id'] = $post_id;
                            }
                        }

                        $affected_posts = $this->detectBrokenInternalLinksOnDelete($from);

                        if (!empty($affected_posts)) {
                            $detectedPosts = array_merge($detectedPosts, $affected_posts);
                        }
                    }
                }
            }
        }

        return $detectedPosts;
    }

    private function revertSuggestions($data) {
        global $SEOAIC_OPTIONS;
        foreach ($data as $code => $item) {
            if (!empty($item['links'])) {
                foreach ($item['links'] as $link) {
                    $safe_link = urldecode(rtrim($link, '/'));
                    if (!empty($safe_link) && !empty($SEOAIC_OPTIONS['redirect'][$code][$safe_link])) {
                        if (!empty($SEOAIC_OPTIONS['redirect'][$code][$safe_link]['deleted_at']) && !empty($SEOAIC_OPTIONS['redirect'][$code][$safe_link]['post_id'])) {
                            $post_id = $SEOAIC_OPTIONS['redirect'][$code][$safe_link]['post_id'];

                            if (get_post_status($post_id) === 'trash') {
                                wp_untrash_post($post_id);
                            }
                        }

                        unset($SEOAIC_OPTIONS['redirect'][$code][$safe_link]);
                    }
                }
            }
        }
    }

    private function deleteSuggestions($data) {
        global $SEOAIC_OPTIONS;
        $detectedPosts = [];

        if (!empty($data['ids'])) {
            foreach ($data['ids'] as $id) {
                if (!empty($id)) {
                    $permalink = get_permalink($id);
                    $url = rtrim($permalink, '/');

                    $affected_posts = $this->detectBrokenInternalLinksOnDelete($permalink);

                    $SEOAIC_OPTIONS['redirect']['410'][$url] = [
                        'destination' => $url
                    ];

                    $trashed_post = wp_trash_post($id);

                    if ($trashed_post !== false) {
                        $SEOAIC_OPTIONS['redirect']['410'][$url]['post_id'] = $id;
                        $SEOAIC_OPTIONS['redirect']['410'][$url]['deleted_at'] = time();
                    }

                    if (!empty($affected_posts)) {
                        $detectedPosts = array_merge($detectedPosts, $affected_posts);
                    }
                }
            }
        }

        return $detectedPosts;
    }

    private function generateDeletedPostsTable($detectedPosts) {
        if (empty($detectedPosts)) {
            return '<p>No affected posts found.</p>';
        }

        $html = '<div class="deleted-posts-container">';
        $html .= '<table class="deleted-posts-table" border="1" cellspacing="0" cellpadding="5">';
        $html .= '<thead>';
        $html .= '<tr>';
        $html .= '<th>Page with Broken Link</th>';
        $html .= '<th>Broken Link</th>';
        $html .= '<th>Suggested Replacement</th>';
        $html .= '</tr>';
        $html .= '</thead>';
        $html .= '<tbody>';

        foreach ($detectedPosts as $post) {
            $postId = $post['post_id'];
            $pageWithLink = $post['post_title'];
            $pageUrl = esc_url($post['post_link']);
            $deletedLink = esc_url($post['deleted_url']);

            $html .= '<tr>';
            $html .= '<td><a href="' . esc_url($pageUrl) . '" target="_blank" class="affected-page" data-post-id="' . $postId . '">' . esc_html($pageWithLink) . '</a></td>';
            $html .= '<td><a href="' . $deletedLink . '" target="_blank" class="broken-page">' . $deletedLink . '</a></td>';
            $html .= '<td>';
            $html .= '<select name="page_link" class="seoaic-keyword-page-link seoaic-form-item form-select"></select>';
            $html .= '</td>';
            $html .= '</tr>';
        }

        $html .= '</tbody>';
        $html .= '</table>';
        $html .= '</div>';

        return $html;
    }

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

        $_post = wp_unslash($_POST);
        $brokenLinks = $_post['brokenLinks'];

        if (empty($brokenLinks)) {
            SEOAICAjaxResponse::alert('No broken links found')->wpSend();
        }

        $detectedPosts = [];

        foreach ($brokenLinks as $link) {
            $affected_posts = $this->detectBrokenInternalLinksOnDelete(urldecode($link));

            if (!empty($affected_posts)) {
                $detectedPosts = array_merge($detectedPosts, $affected_posts);
            }
        }

        if (!empty($detectedPosts)) {
            $suggested = $this->generateDeletedPostsTable($detectedPosts);
            SEOAICAjaxResponse::success()
                ->addFields(['suggested_html' => $suggested])
                ->wpSend();
        }

        SEOAICAjaxResponse::alert('No broken links found')->wpSend();
    }

    public function seoaicRedirectFunction()
    {
        global $SEOAIC_OPTIONS;

        $protocol = 'http';
        if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') {
            $protocol .= 's';
        }
        $protocol .= '://';

        if (!empty($_SERVER['HTTP_HOST']) && !empty($_SERVER['REQUEST_URI'])) {
            $host = sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST']));
            $uri = sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI']));
            $current_page_link = $protocol . $host . $uri;
        }

        $current_page_link = rtrim($current_page_link, '/');

        if (!empty($SEOAIC_OPTIONS['redirect']) && is_array($SEOAIC_OPTIONS['redirect'])) {
            foreach ($SEOAIC_OPTIONS['redirect'] as $code => $redirects) {
                if (isset($redirects[$current_page_link])) {
                    if ((int)$code === 410) {
                        status_header(410);
                        echo 'This page is no longer available.';
                    } else {
                        $destination = esc_url_raw($redirects[$current_page_link]['destination']);
                        wp_redirect($destination, 301);
                    }
                    exit;
                }
            }
        }
    }

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

        global $SEOAIC_OPTIONS;

        $request = wp_unslash($_REQUEST);

        $source = urldecode(rtrim($request['source'], '/'));
        $code = sanitize_text_field($request['code']);
        $reload = !empty($request['reload']) ? $request['reload'] : true;

        if (empty($code) || empty($source)) {
            SEOAICAjaxResponse::alert('Redirect status or url is empty!')->wpSend();
        }

        if (!empty($SEOAIC_OPTIONS['redirect']) && is_array($SEOAIC_OPTIONS['redirect']) && !empty($SEOAIC_OPTIONS['redirect'][$code][$source])) {

            if ((int)$code === 410) {
                $post_id = !empty($SEOAIC_OPTIONS['redirect'][$code][$source]['post_id']) ? $SEOAIC_OPTIONS['redirect'][$code][$source]['post_id'] : '';

                if (!empty($post_id) && get_post_status($post_id) === 'trash') {
                    wp_untrash_post($post_id);
                }
            }

            unset($SEOAIC_OPTIONS['redirect'][$code][$source]);
            update_option('seoaic_options', $SEOAIC_OPTIONS);

            $isReload = filter_var($reload, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
            if ($isReload === true) {
                SEOAICAjaxResponse::reload()->wpSend();
            }

            SEOAICAjaxResponse::alert('Post successfully restored')->wpSend();
        }
    }

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

        global $SEOAIC_OPTIONS;

        $_post = wp_unslash($_POST);
        $isScan = $_post['isScan'];
        $url = urldecode($_post['url']);
        $verificationMethod = sanitize_text_field($_post['verificationMethod']);

        if (empty($url)) {
            SEOAICAjaxResponse::alert('URL can\'t be empty!')->wpSend();
        }

        if (!empty($isScan) && $isScan === 'yes') {
            $this->integratedSiteWithGoogle($verificationMethod, $url);
            SEOAICAjaxResponse::alert('Site added to Google Search Console')->wpSend();
        } else {
            $SEOAIC_OPTIONS['googleIntegrationPopup'] = 0;
            update_option('seoaic_options', $SEOAIC_OPTIONS);
        }

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

    public function checkIntegratedSiteWithGoogle()
    {
        global $SEOAIC_OPTIONS;

        $currentSiteUrl = !empty($SEOAIC_OPTIONS['seoaic_gsc_url']) ? esc_url($SEOAIC_OPTIONS['seoaic_gsc_url']) : get_home_url();

        $data = [
            'url' => trailingslashit($currentSiteUrl),
        ];

        $result = $this->seoaic->curl->init('api/pruning/google/check', $data, true, true, true);
        $result_json = is_string($result) ? json_decode($result, true) : $result;

        return $result_json['isIntegrated'] ?? false;
    }

    public function integratedSiteWithGoogle($verificationMethod, $url = '')
    {
        global $SEOAIC_OPTIONS;

        if (!empty($url)) {
            $currentSiteUrl = esc_url($url);
        } elseif (!empty($SEOAIC_OPTIONS['seoaic_gsc_url'])) {
            $currentSiteUrl = esc_url($SEOAIC_OPTIONS['seoaic_gsc_url']);
        } else {
            $currentSiteUrl = get_home_url();
        }

        $gscIntegrationMethod = strtoupper($verificationMethod);

        $data = [
            'url' => trailingslashit($currentSiteUrl),
            'verificationMethod' => $gscIntegrationMethod
        ];

        $SEOAIC_OPTIONS['googleIntegrationPopup'] = 1;
        $SEOAIC_OPTIONS['seoaicGscIntegrationMethod'] = $gscIntegrationMethod;
        $SEOAIC_OPTIONS['seoaic_gsc_url'] = $currentSiteUrl;
        update_option('seoaic_options', $SEOAIC_OPTIONS);

        $result = $this->seoaic->curl->init('api/pruning/google/add-site', $data, true, true, true);

        if (!empty($result)) {

            if (!empty($result['status']) && $result['status'] === 'error') {
                SEOAICAjaxResponse::alert($result['message'])->wpSend();
            }

            if ($verificationMethod === 'meta') {
                $SEOAIC_OPTIONS['googleMetaTag'] = $result;
                update_option('seoaic_options', $SEOAIC_OPTIONS);

                if ($this->verifySite()) {
                    SEOAICAjaxResponse::reload()->wpSend();
                }
            } elseif ($verificationMethod === 'dns_txt') {
                SEOAICAjaxResponse::success()
                    ->addFields(['dns' => $result, 'domain' => $currentSiteUrl])
                    ->wpSend();
            }  elseif ($verificationMethod === 'dns_cname') {
                SEOAICAjaxResponse::success()
                    ->addFields(['cname' => $result, 'domain' => $currentSiteUrl])
                    ->wpSend();
            }
        }

        SEOAICAjaxResponse::alert('Google site integration failed')->wpSend();
    }

    public function verifySite()
    {
        global $SEOAIC_OPTIONS;

        $data = [
            'verificationMethod' => !empty($SEOAIC_OPTIONS['seoaicGscIntegrationMethod']) ? $SEOAIC_OPTIONS['seoaicGscIntegrationMethod'] : 'META',
        ];

        $result = $this->seoaic->curl->init('api/pruning/google/verify', $data, true, true, true);

        if (!empty($result) && !empty($result['id'])) {
            $SEOAIC_OPTIONS['seoaic_integrate_google_search_console_checkbox'] = true;
            update_option('seoaic_options', $SEOAIC_OPTIONS);

            return true;
        }

        return false;
    }

    public function addGoogleSiteVerificationMetaTag()
    {
        global $SEOAIC_OPTIONS;
        echo $SEOAIC_OPTIONS['googleMetaTag'] . "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }

    private function unregisterPostsAdditionalInfoCron()
    {
        $timestamp = wp_next_scheduled('seoaic_get_additional_info_cron_hook');
        wp_unschedule_event($timestamp, 'seoaic_get_additional_info_cron_hook');
    }

    private function unregisterGoogleConsoleInfoCron()
    {
        $timestamp = wp_next_scheduled('seoaic_get_google_info_cron_hook');
        wp_unschedule_event($timestamp, 'seoaic_get_google_info_cron_hook');
    }

    public function unregisterBackgroundCrons()
    {
        $this->unregisterGoogleConsoleInfoCron();
        $this->unregisterPostsAdditionalInfoCron();
    }

    public function backgroundProcessPost($postsToProcess, $pruningInstance, $manualScan = false)
    {
        global $SEOAIC_OPTIONS;
        $dateStatus = !empty($SEOAIC_OPTIONS['seoaicPruningRescanDateStatus']) ? $SEOAIC_OPTIONS['seoaicPruningRescanDateStatus'] : 'completed';

        $result = $data = [];

        if (!empty($postsToProcess)) {
            try {
                foreach ($postsToProcess as $post) {
                    $postId = $post->ID;
                    $url = get_permalink($postId);

                    $data[] = [
                        'id' => $postId,
                        'url' => $url,
                        'language' => $this->seoaic->multilang->get_post_language($postId),
                    ];
                }

                $resultData = $pruningInstance->requestData($data);

                foreach ($resultData as $postId => $postData) {
                    if ($manualScan && !empty($postData['error'])) {
                        SEOAICAjaxResponse::alert($postData['error'])->wpSend();
                    }

                    $result = $pruningInstance->saveData($postId, $postData);
                    $pruningInstance->saveStatus($postId, $dateStatus);
                }
            } catch (Exception $e) {
                error_log(' ' . print_r($e->getMessage(), true));
            }

            return $result;
        }

        return false;
    }

    public function getPosts($key = '')
    {
        global $SEOAIC_OPTIONS;
        $dateStatus = !empty($SEOAIC_OPTIONS['seoaicPruningRescanDateStatus']) ? $SEOAIC_OPTIONS['seoaicPruningRescanDateStatus'] : 'completed';

        $posts = get_posts([
            'post_type' => seoaic_get_post_types(),
            'numberposts' => 5,
            'meta_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
                'relation' => 'OR',
                [
                    'key' => $key,
                    'compare' => 'NOT EXISTS',
                ],
                [
                    'key' => $key,
                    'value' => $dateStatus,
                    'compare' => '!=',
                ],
            ]
        ]);

        if (empty($posts)) {
            $this->unregisterBackgroundCrons();
        }

        return $posts;
    }

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

        return $schedules;
    }

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

        $checkIntegratedSiteWithGoogle = $this->isSiteIntegratedWithGoogle();

        $_post = wp_unslash($_POST);
        $dateFrom = !empty($_post['dateFrom']) ? sanitize_text_field($_post['dateFrom']) : '';
        $dateTo = !empty($_post['dateTo']) ? sanitize_text_field($_post['dateTo']) : '';
        $dateSelect = !empty($_post['dateSelect']) ? sanitize_text_field($_post['dateSelect']) : '';
        $interval = !empty($_post['interval']) ? sanitize_text_field($_post['interval']) : 'weekly';
        $data = [];

        if (!empty($dateFrom) && !empty($dateTo)) {
            $data = [
                'dateFrom' => $dateFrom,
                'dateTo' => $dateTo,
            ];
        } else {
            $data = $this->getDateRange($dateSelect, $interval);
        }

        $result = $this->seoaic->curl->init('api/pruning/google/site-stats', $data, true, true, true);

        SEOAICAjaxResponse::success()
            ->addFields(['siteStats' => $result])
            ->wpSend();
    }

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

        $this->isSiteIntegratedWithGoogle();

        $_post = wp_unslash($_POST);
        $postUrl = !empty($_post['url']) ? $_post['url'] : '';
        $interval = !empty($_post['interval']) ? sanitize_text_field($_post['interval']) : 'weekly';
        $period = !empty($_post['period']) ? sanitize_text_field($_post['period']) : 'last_3_months';

        if (empty($postUrl)) {
            SEOAICAjaxResponse::alert('Empty url')->wpSend();
        }

        $data = $this->getDateRange($period, $interval);
        $data['url'] = $postUrl;

        $result = $this->seoaic->curl->init('api/pruning/google/page-stats', $data, true, true, true);

        SEOAICAjaxResponse::success()
            ->addFields(['siteStats' => $result])
            ->wpSend();
    }

    function getDateRange($option, $rangeDuration)
    {
        // Google data delay: always subtract 3 days from today
        $today = new DateTime();
        $dateTo = (clone $today)->sub(new DateInterval('P3D'));

        switch ($option) {
            case 'last_7_days':
                $interval = new DateInterval('P7D');
                break;
            case 'last_28_days':
                $interval = new DateInterval('P28D');
                break;
            case 'last_3_months':
                $interval = new DateInterval('P3M');
                break;
            case 'last_6_months':
                $interval = new DateInterval('P6M');
                break;
            case 'last_12_months':
                $interval = new DateInterval('P1Y');
                break;
            case 'last_16_months':
                $interval = new DateInterval('P16M');
                break;
            default:
                $interval = new DateInterval('P3M');
        }

        $dateFrom = clone $dateTo;
        $dateFrom->sub($interval);

        if ($rangeDuration === 'monthly') {
            // Move dateTo to the end of the last complete month
            $dateTo = new DateTime('first day of this month');
            $dateTo->modify('-1 day');

            // Align dateFrom to the first day of the month, and subtract interval
            $dateFrom = new DateTime('first day of ' . $dateTo->format('F Y'));
            $dateFrom->sub($interval);
        }

        if ($rangeDuration === 'weekly') {
            // Get last completed week end (Sunday), considering delay
            $dayOfWeek = (int) $today->format('N');
            $lastSunday = new DateTime('last sunday');
            $lastSunday->setTime(0, 0, 0);

            // If today is Mon-Wed, subtract another week to ensure completeness
            if ($dayOfWeek >= 1 && $dayOfWeek <= 3) {
                $lastSunday->modify('-1 week');
            }

            $dateTo = $lastSunday;

            // Align dateFrom to the Monday of the starting week
            $dateFrom = clone $dateTo;
            $dateFrom->sub($interval);
            $dayOfWeekFrom = (int) $dateFrom->format('N');
            $daysBack = $dayOfWeekFrom - 1;
            $dateFrom->modify("-{$daysBack} days");
        }

        return [
            'dateFrom' => $dateFrom->format('Y-m-d'),
            'dateTo' => $dateTo->format('Y-m-d'),
        ];
    }

    /**
     * @param $event_name
     * @return bool
     */
    public function seoaic_check_wp_cron_running($event_name = '')
    {
        $cron = _get_cron_array();

        $event_found = true;

        if (!wp_next_scheduled($event_name)) {
            $event_found = false;
        }

        return $event_found;
    }

    /**
     * @param $post_id
     * @param $keyword
     * @param $competitor_seo_url
     * @param $my_seo_url
     * @return mixed|string|null
     */
    public function requestGPTSuggestion($post_id, $keyword, $competitor_seo_url, $my_seo_url)
    {

        $seo_data = get_post_meta($post_id, self::GOOGLE_POST_KEYWORDS_ANALYZE, true) ?: [];

        if (!$seo_data) {
            return null;
        }

        $competitor_seo_data = $seo_data[$competitor_seo_url][$keyword];
        $my_seo_data = $seo_data[$my_seo_url][$keyword];

        $check_my_seo_data = isset($my_seo_data['data']) && !empty($my_seo_data['data']);
        $check_competitor_seo_data = isset($competitor_seo_data['data']) && !empty($competitor_seo_data['data']);

        $data = [
            'email' => wp_get_current_user()->user_email,
            'language' => SEOAIC_SETTINGS::getLanguage(),
            'location' => SEOAIC_SETTINGS::getLocation(),
            'page_url' => $my_seo_url,
            'seo_data' => $check_my_seo_data ? wp_json_encode($my_seo_data['data']) : false,
            'competitor_page_url' => $competitor_seo_url,
            'competitor_seo_data' => $check_competitor_seo_data ? wp_json_encode($competitor_seo_data['data']) : false,
            'keyword' => $keyword
        ];

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

        if (!isset($result['status']) || $result['status'] != 'success') {
            return esc_html__('Error', 'seoaic');
        }

        $patterns = [
            '/```html|```/' => '',
        ];

        foreach ($patterns as $pattern => $replacement) {
            $result = preg_replace($pattern, $replacement, $result);
        }

        return $result['content'];
    }

    /**
     * @param $keyword
     * @return mixed|null
     */
    public function requestCompetitors($keyword, $data = [])
    {

        $language = !empty($data['language']) ? $data['language'] : SEOAIC_SETTINGS::getLanguage();
        $location = !empty($data['location']) ? $data['location'] : SEOAIC_SETTINGS::getLocation();

        $data = [
            'email' => wp_get_current_user()->user_email,
            'language' => $language,
            'location' => $location,
            'keywords' => [$keyword],
            'extended' => true
        ];

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

        if (is_wp_error($result)) {
            error_log('error_competitors_request: ' . $result->get_error_message());
            return null;
        }

        return !empty($result['status']) && $result['status'] === 'success' ? $result['data'][$keyword] : null;
    }

    /**
     * @param $url
     * @param $keyword
     * @return mixed
     */
    public function requestPageAnalyze($url, $keyword)
    {
        if (!filter_var($url, FILTER_VALIDATE_URL)) {
            SEOAICAjaxResponse::error('Not valid page url')->wpSend();
        }

        $target = preg_replace('/^www\./', '', wp_parse_url($url, PHP_URL_HOST));

        $data = [
            'email' => wp_get_current_user()->user_email,
            'url' => $url,
            'target' => $target,
            'keyword' => $keyword,
            'language' => SEOAIC_SETTINGS::getLanguage(),
            'location' => SEOAIC_SETTINGS::getLocation(),
        ];

        return $this->seoaic->curl->init('/api/ai/keyword-stats', $data, true, true, true);
    }

    /**
     * @param $keyword
     * @param $post_id
     * @return array|false|mixed
     */
    public function setupKeywordCompetitors($keyword, $post_id, $data = [])
    {

        if ($post_id != -1) {
            $result = get_post_meta($post_id, self::GOOGLE_POST_KEYWORDS_COMPETITORS, true) ?: [];

            if (isset($result[$keyword])) {
                return $result[$keyword];
            }
        }

        $response = $this->requestCompetitors($keyword, $data);

        if (is_array($response)) {
            $result[$keyword] = $response;
            update_post_meta($post_id, self::GOOGLE_POST_KEYWORDS_COMPETITORS, $result);
            return $response;
        }

        SEOAICAjaxResponse::alert('Error response')->wpSend();
        return false;
    }

    /**
     * @param $url
     * @param $keyword
     * @param $post_id
     * @return array|false|mixed
     */
    public function setupPageAnalyze($url, $keyword, $post_id)
    {
        $result = get_post_meta($post_id, self::GOOGLE_POST_KEYWORDS_ANALYZE, true) ?: [];

        if (isset($result[$url][$keyword])) {
            return $result[$url][$keyword];
        }

        $response = $this->requestPageAnalyze($url, $keyword);

        if (is_array($response)) {
            $result[$url][$keyword] = $response;
            update_post_meta($post_id, self::GOOGLE_POST_KEYWORDS_ANALYZE, $result);
            return $response;
        }

        SEOAICAjaxResponse::alert('Error response')->wpSend();
        return false;
    }

    /**
     * @param $post_id
     * @param $keyword
     * @param $competitor_seo_url
     * @param $my_seo_url
     * @return false|mixed|string
     */
    public function setupGPTSuggestions($post_id, $keyword, $competitor_seo_url, $my_seo_url)
    {
        $result = get_post_meta($post_id, self::GOOGLE_POST_SEO_SUGGESTIONS, true) ?: [];

        if (isset($result[$competitor_seo_url . '_' . $my_seo_url][$keyword])) {
            return $result[$competitor_seo_url . '_' . $my_seo_url][$keyword];
        }

        $decodedKeyword = urldecode($keyword);
        $response = $this->requestGPTSuggestion($post_id, $decodedKeyword, $competitor_seo_url, $my_seo_url);

        if ($response) {
            $result[$competitor_seo_url . '_' . $my_seo_url][$keyword] = $response;
            update_post_meta($post_id, self::GOOGLE_POST_SEO_SUGGESTIONS, $result);
            return $response;
        }

        SEOAICAjaxResponse::alert('Error response')->wpSend();
        return false;
    }

    /**
     * @param $competitors
     * @param $keyword
     * @param $url
     * @param $post_id
     * @return string
     */
    public function keywordCompetitorsHTML($competitors, $keyword, $url, $post_id)
    {
        $header = function ($content) {
            return '<div class="table-row heading">' . implode('', array_map(function ($text) {
                    return '<div class="' . strtolower($text) . '">' . $text . '</div>';
                }, $content)) . '</div>';
        };

        $row = function ($competitor) use ($keyword, $url, $post_id) {
            return '<div class="table-row">
                    <div class="competitor">
                        <div class="meta-title">' . $competitor['title'] . '</div>
                        <div class="domain"><a target="_blank" href="' . $competitor['url'] . '">' . $competitor['domain'] . '</a></div>
                        <div class="description">' . $competitor['description'] . '</div>
                    </div>
                    <div class="rank">' . $competitor['avg_position'] . '</div>
                    <div class="analyze"><span data-keyword="' . $keyword . '" data-page-url="' . $url . '" data-competitor-url="' . $competitor['url'] . '" data-post-id="' . $post_id . '" class="modal-button" data-modal="#seoaic-content-improvement-analyze">' . esc_html__('View', 'seoaic') . '</span></div>
                </div>';
        };

        $html = '<div class="competitors-table">';
        $html .= $header([esc_html__('Competitor', 'seoaic'), esc_html__('Rank', 'seoaic'), esc_html__('Analyze', 'seoaic')]);

        foreach ((array)$competitors as $competitor) {
            $html .= $row($competitor);
        }

        $html .= '</div>';
        return $html;
    }

    /**
     * @param $competitors
     * @param $keyword
     * @param $url
     * @param $post_id
     * @return string
     */
    public function peopleAlsoAskHTML($competitors, $keyword, $url, $post_id)
    {
        $header = function ($content) {
            return '<div class="table-row heading">' . implode('', array_map(function ($text) {
                    $checkbox = sanitize_title($text) !== 'more-info' ? '<input class="seoaic-checkbox check_all_' . sanitize_title($text) . '" type="checkbox" value="' . sanitize_title($text) . '">' : '';
                    return '<div class="' . sanitize_title($text) . '">' . $checkbox . esc_html($text) . '</div>';
                }, $content)) . '</div>';
        };

        $expanded_html = function ($expanded_element) {
            $html = '';
            if (!empty($expanded_element)) {
                $html .= '<div class="expanded_data">';
                $html .= '<div class="meta-title">' . esc_html($expanded_element['title']) . '</div>
                <div class="domain"><a target="_blank" href="' . esc_url($expanded_element['url']) . '">' . esc_html($expanded_element['domain']) . '</a></div>
                <div class="description">' . esc_html($expanded_element['description']) . '</div>';
                $html .= '</div>';
            }
            return $html;
        };

        $row = function ($competitor) use ($keyword, $url, $post_id, $expanded_html) {
            if ($competitor) {
                $seed_question = !empty($competitor['seed_question']) ? '<input class="seoaic-checkbox checkbox_seed-question" type="checkbox" value="' . esc_attr($competitor['seed_question']) . '">' . esc_html($competitor['seed_question']) : '';
                $expanded_data = !empty($competitor['expanded_element']) ? $expanded_html($competitor['expanded_element']) : '';

                return '<div class="table-row">
                        <div class="title">
                            <input class="seoaic-checkbox checkbox_title" type="checkbox" value="' . esc_attr($competitor['title']) . '">' . esc_html($competitor['title']) . '
                            ' . $expanded_data . '
                        </div>
                        <div class="seed-question">' . $seed_question . '</div>
                        <div class="analyze">
                            <span
                                data-keyword="' . esc_attr($keyword) . '"
                                data-page-url="' . esc_url($url) . '"
                                data-competitor-url="' . esc_url($competitor['expanded_element']['url'] ?? '') . '"
                                data-post-id="' . esc_attr($post_id) . '"
                                data-people-also-ask="1"
                                data-people-also-ask-title="' . esc_attr($competitor['title']) . '"
                                data-modal="#seoaic-content-improvement-analyze">
                                ' . esc_html__('View', 'seoaic') . '
                            </span>
                        </div>
                    </div>';
            } else {
                return '<div class="table-row">no data</div>';
            }
        };

        $html = '<div class="competitors-table people-also-ask">';
        $html .= $header([
            esc_html__('Title', 'seoaic'),
            esc_html__('Seed question', 'seoaic'),
            esc_html__('More info', 'seoaic')
        ]);

        foreach ((array)$competitors as $competitor_group) {
            if (!empty($competitor_group['items'])) {
                foreach ($competitor_group['items'] as $competitor) {
                    $html .= $row($competitor);
                }
            } else {
                $html .= '<div class="table-row">no data</div>';
            }
        }

        if (empty($competitor_group['items'])) {
            $html .= '<div class="tc mt-40">' . esc_html__('No questions based on this keyword') . '</div>';
        }

        $html .= '</div>';
        return $html;
    }

    /**
     * @param $data
     * @return string
     */
    public function AISuggestionsHTML($data)
    {

        $html = '<div class="inner">
                    <div class="title">' . esc_html__('Summary and AI suggestion what to improve:', 'seoaic') . '</div>
                    <div class="suggestion">' . $data . '.</div>
                 </div>';

        return $html;
    }

    /**
     * @param $data
     * @param $url
     * @return string
     */
    public function pageAnalyzeHTML($data, $url)
    {
        if (empty($data['status']) || $data['status'] != 'success' || empty($data['data'])) {
            SEOAICAjaxResponse::alert('Error fetch page: ' . $url)->wpSend();
        }

        $onPageSeo = $data['data']['on_page_seo'] ?? [];
        $pageTiming = $onPageSeo['page_timing'] ?? [];
        $meta = $onPageSeo['meta'] ?? [];
        $content = $meta['content'] ?? [];
        $htags = $meta['htags'] ?? [];

        $metrics = [
            'time_to_interactive' => $pageTiming['time_to_interactive'] ?? 0,
            'connection_time' => $pageTiming['connection_time'] ?? 0,
            'duration_time' => $pageTiming['duration_time'] ?? 0,
            'onpage_score' => floor($onPageSeo['onpage_score'] ?? 0),
            'automated_readability_index' => floor($content['automated_readability_index'] ?? 0),
            'plain_text_word_count' => floor($content['plain_text_word_count'] ?? 0),
            'meta_title' => $meta['title'] ?? '―',
            'meta_description' => $meta['description'] ?? '―',
            'images_count' => floor($meta['images_count'] ?? 0),
            'internal_links_count' => floor($meta['internal_links_count'] ?? 0),
            'external_links_count' => floor($meta['external_links_count'] ?? 0),
        ];

        $formatTags = function ($tags) {
            return empty($tags) ? '―' : '<b>' . implode('</b><b>', $tags) . '</b>';
        };

        $h1_titles = $formatTags($htags['h1'] ?? []);
        $h2_titles = $formatTags($htags['h2'] ?? []);
        $h3_titles = $formatTags($htags['h3'] ?? []);

        $labels = [
            'connection_time' => esc_html__('Connection time', 'seoaic'),
            'duration_time' => esc_html__('Duration time', 'seoaic'),
            'automated_readability_index' => esc_html__('Readability', 'seoaic'),
            'onpage_score' => esc_html__('Onpage score', 'seoaic')
        ];

        $html = '<div class="top-numbers">';
        foreach ($labels as $key => $label) {
            $ms_label = $key === 'connection_time' || $key === 'duration_time' ? esc_html__('ms', 'seoaic') : '';
            $html .= '<div class="' . strtolower(str_replace(' ', '-', $label)) . '">
                    <div class="num">' . $metrics[$key] . '<span>' . $ms_label . '</span></div>
                    <div class="text">' . $label . '</div>
                  </div>';
        }
        $html .= '</div>';

        $html .= '<div class="bottom-seo-params">
                <div class="page-name">
                    <p>' . esc_html__('Page title:', 'seoaic') . '</p>
                    <h2>' . $metrics['meta_title'] . '</h2>
                </div>
                <div class="page-desc">
                    <p>' . esc_html__('Page description:', 'seoaic') . '</p>
                    <p>' . $metrics['meta_description'] . '</p>
                </div>
                <div class="page-info">
                    <div class="left">
                        <div class="word-count"><p>' . esc_html__('Word count:', 'seoaic') . '</p><b>' . $metrics['plain_text_word_count'] . '</b></div>
                        <div class="images-count"><p>' . esc_html__('Image count:', 'seoaic') . '</p><b>' . $metrics['images_count'] . '</b></div>
                        <div class="internal-link-count"><p>' . esc_html__('Internal link count:', 'seoaic') . '</p><b>' . $metrics['internal_links_count'] . '</b></div>
                        <div class="external-link-count"><p>' . esc_html__('External link count:', 'seoaic') . '</p><b>' . $metrics['external_links_count'] . '</b></div>
                        <div class="h1-title"><p>' . esc_html__('H1 Title to content:', 'seoaic') . '</p>' . $h1_titles . '</div>
                    </div>
                    <div class="right">
                        <div class="word-count"><p>' . esc_html__('H2 titles:', 'seoaic') . '</p>' . $h2_titles . '</div>
                        <div class="images-count"><p>' . esc_html__('H3 titles:', 'seoaic') . '</p>' . $h3_titles . '</div>
                    </div>
                </div>
              </div>';

        return $html;
    }

    /**
     * @return void
     */
    public function getKeywordCompetitors()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $_post = wp_unslash($_POST);
        if (empty($_post['keyword']) || (empty($_post['post_id']) && $_post['post_id'] != -1)) {
            SEOAICAjaxResponse::error('Keyword and post ID is required')->wpSend();
        }

        $keyword = $_post['keyword'];
        $post_id = $_post['post_id'];
        $page_url = $_post['page_url'];

        $data = [];

        if(!empty($_post['language']) && !empty($_post['location'])) {
            $data['language'] = $_post['language'];
            $data['location'] = $_post['location'];
        }

        $competitors = $this->setupKeywordCompetitors($keyword, $post_id, $data);

        $isAllCompetitors = !empty($_post['competitors_type_all']);

        $response = [];

        $response['html'] = $this->keywordCompetitorsHTML($competitors['organic'], $keyword, $page_url, $post_id);

        if ($isAllCompetitors) {
            $response['people_also_ask'] = $this->peopleAlsoAskHTML($competitors['people_also_ask'], $keyword, $page_url, $post_id);
        }

        wp_send_json($response);
    }

    /**
     * @return void
     */
    public function getPageAnalyze()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $_post = wp_unslash($_POST);
        if (empty($_post['keyword']) || empty($_post['post_id'])) {
            //SEOAICAjaxResponse::error('Keyword and post ID is required')->wpSend();
        }

        $keyword = $_post['keyword'];
        $post_id = $_post['post_id'];
        $page_url = $_post['page_url'];

        wp_send_json([
            'html' => $this->pageAnalyzeHTML($this->setupPageAnalyze($page_url, $keyword, $post_id), $page_url),
        ]);

    }

    /**
     * @return void
     */
    public function getAISuggestions()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $_post = wp_unslash($_POST);
        if (empty($_post['keyword']) || empty($_post['post_id'])) {
            SEOAICAjaxResponse::error('Keyword and post ID is required')->wpSend();
        }

        $keyword = $_post['keyword'];
        $post_id = $_post['post_id'];
        $page_url = $_post['page_url'];
        $my_page_url = $_post['my_page_url'];

        wp_send_json([
            'html' => $this->AISuggestionsHTML($this->setupGPTSuggestions($post_id, $keyword, $page_url, $my_page_url))
        ]);

    }

    /**
     * @param array $args
     */
    public function getPageKeywordsWithStats(array $args = []): array
    {
        if (SEOAIC_SETTINGS::isGSCIntegrated()) {
            // default data
            $data = [
                'page'          => 1,
                'limit'         => 50,
                'order'         => 'DESC',
                'orderBy'       => 'clicks',
                'dateFrom'      => wp_date('Y-m', strtotime('-3 months')),
                'dateTo'        => wp_date('Y-m', strtotime('-3 days')),
                'seoaicPost'    => 'include',
                'search'        => [],
            ];

            // overwrite the default data
            foreach ($args as $key => $value) {
                if (!isset($data[$key])) {
                    $data[$key] = '';
                }

                $data[$key] = $value;
            }

            return $this->seoaic->curl->initWithReturn('api/pruning/google/inspection/keywords', $data, true, true);
        }

        return [];
    }

    /**
     * @param string $keyword
     * @param int $post_id
     * @return array|false
     */
    public function getKeywordCompetitorsREST(string $keyword, int $postId)
    {
        $permalink = get_permalink($postId);

        if (
            empty($keyword)
            || !$permalink
        ) {
            return false;
        }

        $args = [
            'limit'     => 0,
            'dateFrom'  => wp_date('Y-m', strtotime('-3 months')),
            'dateTo'    => wp_date('Y-m', strtotime('-3 days')),
            'search'    => [$permalink],
        ];

        $result = $this->getPageKeywordsWithStats($args);

        if (empty($result['keywords'])) {
            return false;
        }

        $keywordsTitles = array_column($result['keywords'], 'title');
        $decodedKeyword = urldecode($keyword);

        if ($decodedKeyword === $keyword) {
            $decodedKeyword = $keyword;
        }

        if (
            in_array($decodedKeyword, $keywordsTitles)
            && get_post_status($postId)
        ) {
            $competitors = $this->setupKeywordCompetitors($decodedKeyword, $postId);

            if (!empty($competitors['organic'])) {
                $competitors = $competitors['organic'];
            }

            return array_slice($competitors, 0, 10);
        }

        return false;
    }

    /**
     * @param $post_id
     * @param $keyword
     * @param $page_url
     * @return false|mixed
     */
    public function getCompetitorAnalysisREST($post_id, $keyword, $page_url)
    {
        if (empty($keyword)) {
            return false;
        }

        $decoded_keyword = urldecode($keyword);
        if ($decoded_keyword === $keyword) {
            $decoded_keyword = $keyword;
        }

        // $google_queries = get_post_meta($post_id, self::QUERY_GOOGLE_FIELD, true);
        // $kw_competitors = get_post_meta($post_id, self::GOOGLE_POST_KEYWORDS_COMPETITORS, true) ?: [];
        // if (
        //     !is_array($google_queries) ||
        //     !isset($kw_competitors[$decoded_keyword]) ||
        //     !is_array($kw_competitors[$decoded_keyword])
        // ) {
        //     return false;
        // }

        // $google_queries = array_column($google_queries, 'query');
        // $comp_urls = array_column($kw_competitors[$decoded_keyword], 'url');

        // if (
        //     in_array($decoded_keyword, $google_queries)
        //     && in_array($page_url, $comp_urls)
        //     && get_post_status($post_id)
        // ) {
            $pageAnalyze = $this->setupPageAnalyze($page_url, $keyword, $post_id);

            if (
                "success" !== $pageAnalyze['status']
                || empty($pageAnalyze['data'])
            ) {
                return false;
            }

            return $pageAnalyze['data'];
        // }

        // return false;
    }

    /**
     * @param $id
     * @return void
     */
    public function cleanSerpData($id)
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $_post = wp_unslash($_POST);
        if (!empty($_post['post_id'])) {
            $id = $_post['post_id'];
        }

        $serp_data = [
            self::GOOGLE_POST_KEYWORDS_COMPETITORS,
            self::GOOGLE_POST_KEYWORDS_ANALYZE,
            self::GOOGLE_POST_SEO_SUGGESTIONS,
            self::GOOGLE_POST_IMPROVEMENT_IDEAS
        ];

        foreach ($serp_data as $meta_key) {
            delete_post_meta($id, $meta_key);
        }

        wp_send_json([
            'clean_serp_post' => intval($id)
        ]);
    }

    /**
     * @param $post_id
     * @return bool
     */
    public function seoaic_is_editable_post($post_id)
    {

        $post = get_post($post_id);

        if (!$post) {
            return false;
        }

        if (current_user_can('edit_post', $post_id)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * @param $id
     * @return array
     */
    public function seoMetaData($id)
    {

        if (defined('WPSEO_VERSION')) {
            // Yoast SEO
            $meta_title = get_post_meta($id, '_yoast_wpseo_title', true);
            $meta_description = get_post_meta($id, '_yoast_wpseo_metadesc', true);
        } elseif (defined('AIOSEO_VERSION')) {
            // All in One SEO Pack
            $meta_title = get_post_meta($id, '_aioseop_title', true);
            $meta_description = get_post_meta($id, '_aioseop_description', true);
        } elseif (defined('SEOPRESS_VERSION')) {
            // SEOPress
            $meta_title = get_post_meta($id, '_seopress_titles_title', true);
            $meta_description = get_post_meta($id, '_seopress_titles_desc', true);
        } elseif (defined('RANK_MATH_VERSION')) {
            // Rank Math
            $meta_title = get_post_meta($id, 'rank_math_title', true);
            $meta_description = get_post_meta($id, 'rank_math_description', true);
        }

        if (empty($meta_title)) {
            $meta_title = 'no meta title';
        }

        if (empty($meta_description)) {
            $meta_description = 'no meta description';
        }

        return [
            'title' => $meta_title,
            'description' => $meta_description
        ];
    }

    /**
     * @param $id
     * @return bool
     */
    public function is_loading_status_improvements($id)
    {

        $improvements_ideas = get_post_meta($id, self::GOOGLE_POST_IMPROVEMENT_IDEAS, true);
        if (!is_array($improvements_ideas) && $improvements_ideas === 'loading') {
            return true;
        }
        return false;
    }

    public function updateGoogleQueriesMeta($id, $keywords_external)
    {
        $keywords_local = get_post_meta($id, self::QUERY_GOOGLE_FIELD, true);

        if ($keywords_local != $keywords_external) {
            update_post_meta($id, self::QUERY_GOOGLE_FIELD, $keywords_external);
        }
    }

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

        $this->isSiteIntegratedWithGoogle();

        $params = $this->getPostArgs();
        $result = $this->seoaic->curl->init('api/pruning/google/inspection', $params, true, true, true);
        $urls = array_column($result['links'], 'url');
        $batch_size = $params['limit'] > 200 ? 100 : 10;
        $post_ids = $this->processBatch($urls, $batch_size);

        $status = 'error';
        if (!empty($result['links'])) {
            $rowsData = $this->makeContentImprovementRows($result['links'], $post_ids);
            $status = 'success';
        }

        $response = [
            'result' => $result,
            'rows' => !empty($rowsData['html']) ? $rowsData['html'] : '<div class="error">' . esc_html__('There are no data for this period', 'seoaic') . '</div>',
            'status' => $status
        ];

        wp_send_json($response);
    }

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

        $checkIntegratedSiteWithGoogle = $this->isSiteIntegratedWithGoogle();

        $params = $this->getPostArgs();
        $result = $this->seoaic->curl->init('api/pruning/google/inspection/keywords', $params, true, true, true);

        $urls = array_column($result['keywords'], 'url');
        $batch_size = $params['limit'] > 200 ? 100 : 10;
        $post_ids = $this->processBatch($urls, $batch_size);

        $status = 'error';
        if (!empty($result['keywords'])) {
            $rowsData = $this->makeRankingRows($result['keywords'], $post_ids);
            $status = 'success';
        }

        $response = [
            'result' => $result,
            'rows' => !empty($rowsData['html']) ? $rowsData['html'] : '<div class="error">' . esc_html__('There are no data', 'seoaic') . '</div>',
            'status' => $status
        ];

        wp_send_json($response);
    }

    private function getPostArgs()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $_post = wp_unslash($_POST);
        $params = $_post['params'];

        if (empty($params)) {
            SEOAICAjaxResponse::error('Empty params')->wpSend();
        }

        $dateFrom           = !empty($params['dateFrom']) ? str_replace('/', '-', $params['dateFrom']) : date('Y-m', strtotime('-3 months'));
        $dateTo             = !empty($params['dateTo']) ? str_replace('/', '-', $params['dateTo']) : date('Y-m', strtotime('-3 days'));
        $publishedMonth     = !empty($params['publishedMonth']) ? $params['publishedMonth'] : null;

        $postType   = !empty($params['postTypeFilter']) && $params['postTypeFilter'] !== 'all' ? $params['postTypeFilter'] : null;
        $trendStatus = !empty($params['trendStatus']) ? $params['trendStatus'] : '';

        $args = [
            'page' => !empty($params['currentPage']) ? $params['currentPage'] : 1,
            'limit' => !empty($params['limit']) ? $params['limit'] : 50,
            'order' => !empty($params['order']) ? $params['order'] : 'ASC',
            'orderBy' => !empty($params['orderBy']) ? $params['orderBy'] : 'clicks',
            'dateFrom' => $dateFrom,
            'dateTo' => $dateTo,
            'publishedMonth' => $publishedMonth,
            'seoaicPost' => 'include',
        ];

        if (!empty($trendStatus)) {
            $args['trendStatus'] = $trendStatus;
        }

        $s = $searchKeywords = !empty($params['search']) ? sanitize_text_field($params['search']) : '';
        $seoaicPost = (!empty($params['seoaicPost']) && $params['seoaicPost'] !== 'all') ? $params['seoaicPost'] : '';

        if ($params['seoaicPost'] === 'not-seoai') {
            if (empty($s)) {
                $args['seoaicPost'] = 'exclude';
                $seoaicPost = 'seoai';
            } else {
                $seoaicPost = 'not-seoai';
            }
        }

        if ($_post['action'] === 'seoaic_ranking_get_pages' || $_post['action'] === 'seoaic_keyword_analysation_pages') {
            $s = '';
        }

        if ($_post['action'] === 'seoaic_seoaic_automated_pruning_pages') {
            if (!empty($params['publishedMonth']) && $params['publishedMonth'] !== 'all') {
                $search_results = $this->get_search_results_links_db($s, $seoaicPost, $postType, $args['publishedMonth']);
            } else {
                $search_results = $this->get_search_results_links_db($s, $seoaicPost, $postType, $dateFrom, $dateTo);
            }
        } else {
            if ($_post['action'] === 'seoaic_content_imptovement_get_pages' && !empty($params['publishedMonth']) && $params['publishedMonth'] !== 'all') {
                $search_results = $this->get_search_results_links_db($s, $seoaicPost, $postType, $args['publishedMonth']);
            } else {
                $search_results = $this->get_search_results_links_db($s, $seoaicPost);
            }
        }

        if (isset($search_results['status']) && $search_results['status'] === 'error') {
            wp_send_json([
                'rows' => '<div class="error">' . esc_html__('No pages found matching the search criteria', 'seoaic') . '</div>',
                'status' => 'error'
            ]);
        }
        $args['search'] = !empty($search_results['links']) ? $search_results['links'] : [];

        if (!empty($params['url'])) {
            $args['search'] = [$params['url']];
            $args['limit'] = 0;
            $args['post_id'] = $params['post_id'];
        }

        if (!empty($params['filter'])) {
            if (!empty($params['filter']['clicks'])) {
                $args['filter']['clicks'] = $params['filter']['clicks'];
            }
            if (!empty($params['filter']['position'])) {
                $args['filter']['position'] = $params['filter']['position'];
            }
            if (!empty($params['filter']['impressions']) ) {
                $args['filter']['impressions'] = $params['filter']['impressions'];
            }
            if (!empty($params['filter']['ctr']) ) {
                $args['filter']['ctr']['min'] = $params['filter']['ctr']['min'] / 100;
                $args['filter']['ctr']['max'] = $params['filter']['ctr']['max'] / 100;
            }
        }

        if (!empty($params['brandedKeywords']) && $params['brandedKeywords'] !== 'all') {
            $args['brandedKeywords'] = [
                'action' => $params['brandedKeywords'],
                'keywords' => seoaic_get_branded_keywords()
            ];
        }

        if ($_post['action'] === 'seoaic_ranking_get_pages' || $_post['action'] === 'seoaic_keyword_analysation_pages') {
            if (!empty($searchKeywords)) {
                $args['brandedKeywords'] = [
                    'action' => 'like',
                    'keywords' => [$searchKeywords]
                ];
            }
        }

        if (!empty($params['redirectSuggestion']) && $params['redirectSuggestion'] !== 'all') {
            $args['sharedPages'] = $params['redirectSuggestion'];
        }

        if (!empty($params['redirectFilter']) && $params['redirectFilter'] !== 'all') {
            $redirectUrls = $this->getRedirectList();

            if (empty($redirectUrls)) {
                if ($params['redirectFilter'] !== 'without_redirects') {
                    wp_send_json([
                        'rows' => '<div class="error">' . esc_html__('You have no active redirects.', 'seoaic') . '</div>',
                        'status' => 'error'
                    ]);
                }
            }

            if (!empty($args['search'])) {
                if ($params['redirectFilter'] === 'without_redirects') {
                    $args['seoaicPost'] = 'exclude';
                    $args['search'] = array_diff($args['search'], $redirectUrls);
                } else {
                    $args['search'] = array_intersect($args['search'], $redirectUrls);
                }
            } else {
                $args['search'] = $redirectUrls;

                if ($params['redirectFilter'] === 'without_redirects') {
                    $args['seoaicPost'] = 'exclude';
                }
            }

            $args['search'] = array_values($args['search']);
        }

        if (!empty($params['compareKeywordPositionFrom']) && !empty($params['compareKeywordPositionTo'])) {
            $args['group'] = [[$params['compareKeywordPositionFrom'], $params['compareKeywordPositionTo']]];
        }

        if (!empty($params['statusKeyword'])) {
            $args['status'] = $params['statusKeyword'];
        }

        return $args;
    }

    public function processBatch($urls, $batch_size = 10, $home_translations = true)
    {
        $all_ids = [];
        $batches = array_chunk($urls, $batch_size);

        foreach ($batches as $batch) {
            $batch_ids = $this->getPostIdsByUrls($batch, $home_translations);
            $all_ids = array_merge($all_ids, $batch_ids);
        }

        return $all_ids;
    }

    private function getPostIdsByUrls($urls, $home_translations = true)
    {
        global $wpdb;
        $ids = [];

        if (empty($urls)) {
            return $ids;
        }

        $language_codes = $this->activeLanguagesCodes();

        $slugs = array_map(function ($url) {
            return basename(wp_parse_url($url, PHP_URL_PATH));
        }, $urls);

        $placeholders = implode(',', array_fill(0, count($slugs), '%s'));

        $query = $wpdb->prepare(
            "SELECT ID, post_name
         FROM $wpdb->posts
         WHERE post_name IN ($placeholders)
         AND post_type != 'attachment'", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
            ...$slugs
        );

        $results = $wpdb->get_results($query); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.NotPrepared

        foreach ($results as $result) {
            $ids[$result->post_name] = $result->ID;
        }

        if (in_array("", $slugs, true)) {
            $front_page_id = get_option('page_on_front');
            if ($front_page_id) {
                $ids[''] = $front_page_id;
            }
        }

        if ($home_translations) {
            if (!empty($language_codes)) {
                foreach ($language_codes as $code) {
                    $front_page_id = $this->getFrontPageForLanguage($code);
                    if ($front_page_id) {
                        $ids[$code] = $front_page_id;
                    }
                }
            }
        }

        return $ids;
    }

    private function activeLanguagesCodes()
    {
        $language_codes = [];

        if (function_exists('icl_get_languages')) {
            $languages = icl_get_languages('skip_missing=0');
            if (!empty($languages)) {
                $language_codes = array_keys($languages);
            }
        } elseif (function_exists('pll_languages_list')) {
            $language_codes = pll_languages_list(['fields' => 'slug']);
        }

        return $language_codes;
    }

    private function getFrontPageForLanguage($language_code)
    {
        if (function_exists('icl_object_id')) {
            return icl_object_id(get_option('page_on_front'), 'page', true, $language_code);
        } elseif (function_exists('pll_get_post')) {
            return pll_get_post(get_option('page_on_front'), $language_code);
        }
        return null;
    }

    public function isContentImprovementAvailable($ID, $row_url)
    {
        if (!current_user_can('edit_post', $ID)) {
            return false;
        }

        $post = get_post($ID);

        $row_url = rtrim(ltrim(parse_url($row_url, PHP_URL_PATH), '/'), '/');
        $post_url = rtrim(ltrim(parse_url(get_the_permalink($ID), PHP_URL_PATH), '/'), '/');

        if ($row_url !== $post_url) {
            return false;
        }

        if ($post && $post->post_status !== 'auto-draft') {

            if (post_type_supports($post->post_type, 'editor')) {
                return true;
            }

            if (function_exists('get_fields')) {
                $acf_fields = get_fields($ID);
                if (!empty($acf_fields)) {
                    return true;
                }
            }

            $elementor_data = get_post_meta($ID, '_elementor_data', true);
            if (!empty($elementor_data)) {
                return true;
            }

            $meta_fields = get_post_meta($ID);
            if (!empty($meta_fields)) {
                return true;
            }
        }

        return false;
    }

    private function get_score_color($score)
    {
        if ($score === null) {
            return '';
        }

        if ($score >= 1 && $score <= 29) {
            return 'bad';
        } elseif ($score >= 30 && $score <= 79) {
            return 'medium';
        } elseif ($score >= 80 && $score <= 100) {
            return 'good';
        }
    }

    private function ci_page_score_data($id) {
        $page_score_data = get_post_meta($id, self::CI_PAGE_SCORE_META, true);

        if (empty($page_score_data) || !is_array($page_score_data)) {
            return false;
        }

        $get_value = static function ($array, $key, $default = '—') {
            return esc_html($array[$key] ?? $default);
        };

        $get_score_block = function ($array) use ($get_value) {
            $score = $array['score'] ?? 0;
            return [
                'score'       => $get_value($array, 'score'),
                'explanation' => $get_value($array, 'explanation'),
                'score_class' => $this->get_score_color($score),
            ];
        };

        $content_score = $page_score_data['content_score']['total'] ?? 0;
        $content_score_explanation = $page_score_data['content_score']['explanation'] ?? '';
        $subscores = $page_score_data['content_score']['subscores'] ?? [];

        return [
            'ai-readiness' => $get_score_block($page_score_data['ai_readiness_score'] ?? []),
            'content_score' => esc_html($content_score ?: '—'),
            'content_score_explanation' => esc_html($content_score_explanation ?: '—'),
            'content_score_class' => $this->get_score_color($content_score),
            'depth'       => $get_score_block($subscores['depth'] ?? []),
            'freshness'   => $get_score_block($subscores['freshness'] ?? []),
            'readability' => $get_score_block($subscores['readability'] ?? []),
            'intent_match'=> $get_score_block($subscores['intent_match'] ?? []),

            'performance_safeguard' => [
                'applied' => $get_value($page_score_data['performance_safeguard'] ?? [], 'applied'),
                'reason'  => $get_value($page_score_data['performance_safeguard'] ?? [], 'reason'),
            ],
        ];
    }


    private function ci_page_score_details($id) {

        $page_score_data = $this->ci_page_score_data($id);

        $data = [
            'main_score' => esc_html('—'),
            'score_preview' => esc_html('—'),
        ];

        if (empty($page_score_data)) {
            return $data;
        }

        $data['main_score'] =
            '<div class="ci-score-details-mini">
                <ul class="ci-score-details-mini-list">
                <li><div class="ci-score-details-main-list"><span>' . esc_html__('AI-Readiness Score:', 'seoaic') . '</span><span data-seoaic-tooltip-info="' . $page_score_data['ai-readiness']['explanation'] . '" class="score-value score-bg ' . $page_score_data['ai-readiness']['score_class'] . '">' . $page_score_data['ai-readiness']['score'] . '</span></div><div class="ci-score-details-main-list-description"></div></li>
                </ul>
                <ul class="ci-score-details-mini-list">
                <li><div class="ci-score-details-main-list"><span>' . esc_html__('Content Score:', 'seoaic') . '</span><span data-seoaic-tooltip-info="' . esc_attr($page_score_data['content_score_explanation']) . '" class="score-value score-bg ' . esc_attr($page_score_data['content_score_class']) . '">' . $page_score_data['content_score'] . '</span></div></li>
                <li><div class="ci-score-details-main-list"><span>' . esc_html__('Depth:', 'seoaic') . '</span><span data-seoaic-tooltip-info="' . esc_attr($page_score_data['depth']['explanation']) . '" class="score-value score-bg ' . esc_attr($page_score_data['depth']['score_class']) . '">' . $page_score_data['depth']['score'] . '</span></div><div class="ci-score-details-main-list-description"></div></li>
                <li><div class="ci-score-details-main-list"><span>' . esc_html__('Freshness:', 'seoaic') . '</span><span data-seoaic-tooltip-info="' . esc_attr($page_score_data['freshness']['explanation']) . '" class="score-value score-bg ' . esc_attr($page_score_data['freshness']['score_class']) . '">' . $page_score_data['freshness']['score'] . '</span></div><div class="ci-score-details-main-list-description"></div></li>
                <li><div class="ci-score-details-main-list"><span>' . esc_html__('Readability:', 'seoaic') . '</span><span data-seoaic-tooltip-info="' . esc_attr($page_score_data['readability']['explanation']) . '" class="score-value score-bg ' . esc_attr($page_score_data['readability']['score_class']) . '">' . $page_score_data['readability']['score'] . '</span></div><div class="ci-score-details-main-list-description"></div></li>
                <li><div class="ci-score-details-main-list"><span>' . esc_html__('Intent Match:', 'seoaic') . '</span><span data-seoaic-tooltip-info="' . esc_attr($page_score_data['intent_match']['explanation']) . '" class="score-value score-bg ' . esc_attr($page_score_data['intent_match']['score_class']) . '">' . $page_score_data['intent_match']['score'] . '</span></div><div class="ci-score-details-main-list-description"></div></li>
                </ul>
           </div>';

        $data['score_preview'] = $this->ci_page_score_details_mini($id, $page_score_data);

        return $data;
    }

    private function ci_page_score_details_mini($id, $score_data = null) {

        $page_score_data = $score_data ? $score_data : $this->ci_page_score_data($id);

        if (empty($page_score_data)) {
            return esc_html('—');
        }

        $tooltip = '<div class="ci-score-details-mini">
                    <ul class="ci-score-details-mini-list">
                    <li><span>' . esc_html__('AI-Readiness Score (AI):', 'seoaic') . '</span><span class="score-value ' . $page_score_data['ai-readiness']['score_class'] . '">' . $page_score_data['ai-readiness']['score'] . '</span></li>
                    </ul>
                    <ul class="ci-score-details-mini-list">
                    <li><span>' . esc_html__('Content Score (CS):', 'seoaic') . '</span><span class="score-value ' . $page_score_data['content_score_class'] . '">' . $page_score_data['content_score'] . '</span></li>
                    <li><span>' . esc_html__('Depth:', 'seoaic') . '</span><span class="score-value ' . $page_score_data['depth']['score_class'] . '">' . $page_score_data['depth']['score'] . '</span></li>
                    <li><span>' . esc_html__('Freshness:', 'seoaic') . '</span><span class="score-value ' . $page_score_data['freshness']['score_class'] . '">' . $page_score_data['freshness']['score'] . '</span></li>
                    <li><span>' . esc_html__('Readability:', 'seoaic') . '</span><span class="score-value ' . $page_score_data['readability']['score_class'] . '">' . $page_score_data['readability']['score'] . '</span></li>
                    <li><span>' . esc_html__('Intent Match:', 'seoaic') . '</span><span class="score-value ' . $page_score_data['intent_match']['score_class'] . '">' . $page_score_data['intent_match']['score'] . '</span></li>
                    </ul>
                 </div>';

        return '<div class="ci-average" data-html="' . esc_attr($tooltip) . '">
                    <div class="ci-average-ai-readiness-score"><span class="bullet"></span><span class="score-label">' . esc_html__('AI: ', 'seoaic') . '</span><span class="score-value ' . $page_score_data['ai-readiness']['score_class'] . '">' . $page_score_data['ai-readiness']['score'] . '</span></div>
                    <div class="ci-average-content-score"><span class="bullet"></span><span class="score-label">' . esc_html__('CS: ', 'seoaic') . '</span><span class="score-value ' . $page_score_data['content_score_class'] . '">' . $page_score_data['content_score'] . '</span></div>
                </div>';
    }

    public function makeContentImprovementRows($rows, $post_ids)
    {
        global $SEOAIC;
        $postsRepository = new PostRepository();
        $seaAuthArgs = $SEOAIC->sea->getSeaAuthToken();

        ob_start();

        foreach ($rows as $key => $row) {
            $google_queries = !empty($row['queries']) ? $row['queries'] : '';
            $link = $row['url'];
            $path = wp_parse_url($row['url'], PHP_URL_PATH);
            $slug = basename($path);
            $ID = isset($post_ids[$slug]) ? $post_ids[$slug] : 0;

            $content_improvement_available = $this->isContentImprovementAvailable($ID, $row['url']);

            if (!empty($ID)) {
                $title = get_the_title($ID);
            }

            $pageData = $postsRepository->check_page_type_with_regex_and_message($path);

            if ($slug === '') {
                $title = $pageData['content'];
            }

            if ($slug !== '' && empty($ID)) {
                $title = $pageData['content'];
            }

            $impressions = intval($row['impressions']);
            $clicks = intval($row['clicks']);
            $position = floor($row['position']);
            $ctr = round($row['ctr'] * 100, 2);
            $status_data = $SEOAIC->content_improvement->has_improvement_data($ID);
            $monitery = !empty($row['value']) ? $row['value'] . ' €' : '-';
            ?>
            <div class="row-line seoaic-has-children"
                 data-id="<?php echo esc_attr($ID) ?>">
                <div class="main-info">
                    <div class="page-name">
                        <input id="improve_page_selected_<?php echo esc_attr($ID); ?>"
                               value="<?php echo esc_attr($ID); ?>"
                               type="checkbox"
                               class="seoaic-checkbox right-15 light"
                            <?php if (!empty($ID) && $content_improvement_available) {
                                echo !empty($status_data) && $status_data !== 'failed' ? ' disabled' : '';
                            } else {
                                echo ' disabled';
                            }
                            ?>
                        >
                        <span><?php echo $title // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></span>
                    </div>
                    <div class="page-url url">
                        <a href="<?php echo esc_url($link) ?>" target="_blank">
                            <span class="dashicons dashicons-admin-links"></span>
                        </a>
                    </div>
                    <div class="index">
                        <?php echo $this->ci_page_score_details_mini($ID); ?>
                    </div>
                    <div class="impressions"><?php echo esc_html($impressions) ?></div>
                    <div class="clicks"><?php echo esc_html($clicks) ?></div>
                    <div class="ctr"><?php echo esc_html($ctr) ?>%</div>
                    <div class="monitery"><?php echo esc_html($monitery); ?></div>
                    <div class="edited">
                        <div><?php echo esc_html(get_the_modified_date('d/m/Y', $ID)); ?></div>
                        <div><?php echo esc_html(get_the_modified_date('g:i a', $ID)); ?></div>
                    </div>
                    <div class="published">
                        <div><?php echo esc_html(get_the_date('d/m/Y', $ID)); ?></div>
                        <div><?php echo esc_html(get_the_date('g:i a', $ID)); ?></div>
                    </div>
                    <div class="actions">
                        <?php if (!empty($ID)) {
                            $editLink = get_edit_post_link($ID);
                            $link = !empty($editLink) ? esc_url($editLink) : '';
                        ?>
                            <?php if (!empty($editLink)) { ?>
                                <a class="seoaic-button seoaic-improve"
                                    href="<?php echo esc_url($editLink);?>"
                                    target="_blank"><?php esc_html_e('Improve', 'seoaic') ?></a>
                            <?php } ?>

                            <button
                                class="seoaic-button modal-button seaoic-promote seoaic-promote-modal-button"
                                data-post-id="<?php echo esc_attr($ID); ?>"
                                data-post-url="<?php echo esc_url($link); ?>"
                                data-post-title="<?php echo esc_attr($title); ?>"
                                data-modal="#seoaic-promote-modal"
                                ><?php esc_html_e('Promote', 'seoaic'); ?></button>

                            <button class="seoaic-button modal-button seoaic-redirect_301"
                                data-modal="#seoaic-redirect_301-modal"
                                data-url="<?php echo esc_url($link) ?>"
                                data-action="seoaic_add_keyword"><?php esc_html_e('301 Redirect', 'seoaic'); ?></button>

                            <button title="Remove post" type="button"
                                data-post-id="<?php echo esc_attr($ID); ?>"
                                data-post-url="<?php echo esc_url($link); ?>"
                                data-suggestion="delete"
                                class="seoaic-remove seoaic-remove-post seoaic-suggestion-button"
                            >
                            </button>
                            <button title="Scan post" type="button" data-id="<?php echo esc_attr($ID); ?>"
                                    class="seoaic-update seoaic-scan-post"></button>
                            <?php
                            $loading = '';
                            if ($SEOAIC->content_improvement->is_loading_status_improvements($ID)) {
                                $loading = 'active';
                            }
                            ?>
                            <div id="loader_improvement_id_<?php echo esc_attr($ID); ?>"
                                 class="show <?php echo esc_attr($loading); ?> <?php
                                 if ($content_improvement_available) {
                                     $status_data = $SEOAIC->content_improvement->has_improvement_data($ID);
                                     echo esc_html($status_data);
                                     if (!empty($status_data) && $status_data !== 'failed' || !$google_queries) {
                                         echo ' disabled';
                                     }
                                 }
                                 ?>">
                            </div>
                        <?php } ?>
                    </div>
                </div>

                <?php
                $idForKeywordsTab = 'seoaic_improvement_keywords_' . $ID;
                $idForImprovementTab = 'seoaic_improvement_improvement_' . $ID;
                $idForSuggestionsTab = 'seoaic_improvement_suggestions_' . $ID;
                $idForAutoImprovementTab = 'seoaic_auto_improvement_' . $ID;
                $idForSEATab = 'seoaic_sea_' . $ID;
                ?>
                <div class="google-keywords d-none">
                    <div class="page-graph">
                        <div class="page-graph-header">
                            <button class="toggle-chart seoaic-mini-btn" type="button" data-mini="false" aria-pressed="false">
                                <svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
                                    <path class="icon-up" d="M6 14l6-6 6 6" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                    <path class="icon-down" d="M6 10l6 6 6-6" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                                <span class="label">Minimize</span>
                            </button>
                            <div class="page-graph-actions">
                                <div class="page-graph-actions-wrap">
                                    <div>
                                        <select class="form-select pp-select seoaic-graph-date-range">
                                            <option value="last_7_days" selected="">Last 7 days</option>
                                            <option value="last_28_days">Last 28 days</option>
                                            <option value="last_3_months" selected="">Last 3 months</option>
                                            <option value="last_6_months">Last 6 months</option>
                                            <option value="last_12_months">Last 12 months</option>
                                            <option value="last_16_months">Last 16 months</option>
                                        </select>
                                    </div>
                                    <div class="seoaic-graph-intervals">
                                        <button class="seoaic-individual_graph-interval active" data-interval="weekly">Weekly</button>
                                        <button class="seoaic-individual_graph-interval" data-interval="monthly">Monthly</button>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="individual-page-graph"></div>
                    </div>
                    <div class="header-tabs">
                        <?php
                            if (!empty($ID)) {
                                ?>
                                <input type="radio"
                                    id="<?php echo esc_attr($idForKeywordsTab);?>"
                                    name="seoaic_improvement_tab_<?php echo esc_attr($ID);?>"
                                    class="seoaic-improvement-keywords seoaic-improvement-tab-input d-none"
                                    checked="checked"
                                    data-post-id="<?php echo esc_attr($ID);?>"
                                    data-tab="keywords"
                                    value="<?php echo esc_attr($ID);?>"
                                /><label
                                    for="<?php echo esc_attr($idForKeywordsTab);?>"
                                    class="seoaic-improvement-tab-label switcher active"
                                    data-tab="keywords"
                                ><?php esc_attr_e('Keywords', 'seoaic');?></label>
                                <?php
                                if ($content_improvement_available) {
                                    ?><input type="radio"
                                        id="<?php echo esc_attr($idForImprovementTab);?>"
                                        name="seoaic_improvement_tab_<?php echo esc_attr($ID);?>"
                                        class="seoaic-improvement-improvement seoaic-improvement-tab-input d-none"
                                        data-post-id="<?php echo esc_attr($ID);?>"
                                        data-tab="improvement"
                                        value="<?php echo esc_attr($ID);?>"
                                    /><label
                                        for="<?php echo esc_attr($idForImprovementTab);?>"
                                        class="seoaic-improvement-tab-label switcher"
                                        data-tab="improvement"
                                    ><?php esc_html_e('Content Improvement', 'seoaic');?></label><?php
                                }

                                ?><input type="radio"
                                    id="<?php echo esc_attr($idForSuggestionsTab);?>"
                                    name="seoaic_improvement_tab_<?php echo esc_attr($ID);?>"
                                    class="seoaic-improvement-suggestions seoaic-improvement-tab-input d-none"
                                    data-post-id="<?php echo esc_attr($ID);?>"
                                    data-tab="suggestions"
                                    value="<?php echo esc_attr($ID);?>"
                                /><label
                                    for="<?php echo esc_attr($idForSuggestionsTab);?>"
                                    class="seoaic-improvement-tab-label switcher"
                                    data-tab="suggestions"
                                ><?php esc_html_e('Suggestions', 'seoaic');?></label>

                                <input type="radio"
                                    id="<?php echo esc_attr($idForAutoImprovementTab);?>"
                                    name="seoaic_improvement_tab_<?php echo esc_attr($ID);?>"
                                    class="seoaic-auto-improvement seoaic-improvement-tab-input d-none"
                                    data-post-id="<?php echo esc_attr($ID);?>"
                                    data-tab="auto-improvement"
                                    value="<?php echo esc_attr($ID);?>"
                                /><label
                                    for="<?php echo esc_attr($idForAutoImprovementTab);?>"
                                    class="seoaic-improvement-tab-label switcher"
                                    data-tab="auto-improvement"
                                ><?php esc_html_e('Auto improvements', 'seoaic');?></label>
                                <?php if (!empty($seaAuthArgs['token'])) { ?>
                                    <input type="radio"
                                        id="<?php echo esc_attr($idForSEATab);?>"
                                        name="seoaic_improvement_tab_<?php echo esc_attr($ID);?>"
                                        class="seoaic-improvement-sea seoaic-improvement-tab-input d-none"
                                        data-post-id="<?php echo esc_attr($ID);?>"
                                        data-tab="sea"
                                        value="<?php echo esc_attr($ID);?>"
                                    /><label
                                        for="<?php echo esc_attr($idForSEATab);?>"
                                        class="seoaic-improvement-tab-label switcher"
                                        data-tab="sea"
                                    ><?php esc_attr_e('SEA', 'seoaic');?></label>
                                <?php } ?>
                                <?php
                            }
                        ?>
                    </div>

                    <div class="tabs-content">
                        <?php
                        if ($content_improvement_available) {
                            ?>
                            <div id="inner-improvement-<?php echo esc_attr($ID); ?>"
                                class="inner-improvement seoaic-improvement-tab-data <?php echo $status_data ? 'has-data' : '' ?>"
                                data-tab="improvement"
                            ></div>
                            <?php
                        }
                        ?>
                        <div class="inner-keywords seoaic-improvement-tab-data active" data-tab="keywords">
                            <div class="d-flex">
                                <div class="additional-info additional-info_<?php echo esc_attr($ID) ?>">
                                    <div class="additional-info-row heading">
                                        <div class="actions">
                                            <button disabled=""
                                                    data-ideas-label="<?php esc_attr_e('Generate ideas after adding a keywords', 'seoaic') ?>"
                                                    data-modal="#add-keyword-modal"
                                                    class="modal-button improve-add-keywords"
                                            ><?php esc_attr_e('Add to keywords', 'seoaic') ?></button>
                                            <button disabled=""
                                                    data-modal="#generate-ideas-new-keywords"
                                                    class="modal-button improve-generate-ideas"
                                            ><?php esc_attr_e('Generate ideas', 'seoaic') ?></button>
                                        </div>
                                        <div class="additional-keyword">
                                            <span></span>&nbsp;<?php esc_html_e('Keywords', 'seoaic'); ?>
                                        </div>
                                        <div class="additional-clicks table-sort active"
                                            data-orderby="<?php echo esc_attr(SeoaicContentImprovement::CLICKS_FIELD); ?>"
                                            data-order="DESC"
                                        >
                                            <?php esc_html_e('Clicks', 'seoaic') ?><span></span>
                                        </div>
                                        <div class="additional-impressions table-sort"
                                            data-orderby="<?php echo esc_attr(SeoaicContentImprovement::IMPRESSION_FIELD); ?>"
                                        >
                                            <?php esc_html_e('Impressions', 'seoaic') ?><span></span>
                                        </div>
                                        <div class="additional-ctr table-sort"
                                            data-orderby="<?php echo esc_attr(SeoaicContentImprovement::CTR_FIELD); ?>"
                                        >
                                            <?php esc_html_e('CTR', 'seoaic') ?><span></span>
                                        </div>
                                        <div class="additional-rank table-sort"
                                            data-orderby="<?php echo esc_attr(SeoaicContentImprovement::POSITION_FIELD); ?>"
                                        >
                                            <?php esc_html_e('Rank', 'seoaic') ?><span></span>
                                        </div>
                                        <div class="also-ask-map-additional-keyword-row"><?php esc_html_e('Content map', 'seoaic') ?></div>
                                    </div>
                                    <span class="loader-ellipsis small" style="display: block;"></span>
                                    <div class="anchor"></div>
                                    <div class="seaaic-sea-action">
                                        <button type="button" class="seoaic-sea-create-campaign" data-base-text="<?php esc_html_e('Create SEA Campaign', 'seoaic'); ?>"></button>
                                    </div>
                                </div>
                                <div class="keywords-serp">
                                    <div class="serp-content">
                                        <span><?php esc_html_e('Show SERP', 'seoaic'); ?></span>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="inner-suggestions seoaic-improvement-tab-data" data-tab="suggestions">
                            <div class="loading-data">
                                <div class="loading-label accent"><?php esc_html_e('Generating suggestions', 'seoaic');?></div>
                                <div class="loading-icon">
                                    <div class="loader-ellipsis small do-not-remove"></div>
                                </div>
                            </div>
                        </div>
                        <div class="inner-auto-improvement seoaic-improvement-tab-data" data-tab="auto-improvement" data-post-id="<?php echo esc_attr($ID); ?>">
                            <div class="loading-data">
                                <div class="loading-label accent"><?php esc_html_e('Generate automatic improvement suggestions', 'seoaic');?></div>
                                <div class="loading-icon">
                                    <div class="loader-ellipsis small do-not-remove"></div>
                                </div>
                            </div>
                            <div class="auto-improvements-container d-none">
                                <div>
                                    <div class="auto-improvement-header">
                                        <div class="global-prompt-popup-wrapper">
                                            <button type="button" class="seoai-suggested-update-button toggle-global-prompt">
                                                📝 Add custom prompt
                                            </button>
                                            <div class="global-prompt-popup" style="display: none;">
                                                <div>
                                                    <label for="global-suggested-prompt">Edit global prompt</label>
                                                    <textarea id="global-suggested-prompt"
                                                        class="global-prompt-textarea"
                                                        placeholder="Write your prompt that applies to all improvements..."></textarea>
                                                </div>
                                                <div class="auto-improvement-general-options">
                                                    <label for="auto-improvement-select"><?php esc_html_e('Improvement Goals', 'seoaic'); ?></label>
                                                    <select class="global-suggested-options" name="auto-improvement-select" id="auto-improvement-select">
                                                        <option value="default" disabled selected hidden><?php esc_html_e('Choose an option', 'seoaic'); ?></option>
                                                        <option value="find_content_gaps"><?php esc_html_e('Find content gaps', 'seoaic'); ?></option>
                                                        <option value="optimise_for_conversion"><?php esc_html_e('Optimise for conversion', 'seoaic'); ?></option>
                                                        <option value="optimise_for_readability "><?php esc_html_e('Optimise for readability ', 'seoaic'); ?></option>
                                                        <option value="optimise_for_llms "><?php esc_html_e('Optimize for LLMs ', 'seoaic'); ?></option>
                                                    </select>
                                                </div>
                                                <div class="auto-improvement-actions">
                                                    <button class="auto-improvement-generate"><?php esc_html_e('Update', 'seoaic'); ?></button>
                                                </div>
                                            </div>
                                        </div>
                                        <div class="auto-improvement-actions">
                                            <button class="auto-improvement-generate"><?php esc_html_e('Refresh Suggestions', 'seoaic'); ?></button>
                                        </div>
                                    </div>
                                </div>
                                <div class="auto-improvement-table" data-post-id="<?php echo esc_attr($ID); ?>"></div>
                            </div>
                        </div>
                        <?php if (!empty($seaAuthArgs['token'])) { ?>
                            <div class="inner-sea seoaic-improvement-tab-data" data-tab="sea">
                                <div class="loading-data">
                                    <div class="loading-label accent"><?php esc_html_e('Loading campaign', 'seoaic');?></div>
                                    <div class="loading-icon">
                                        <div class="loader-ellipsis small do-not-remove"></div>
                                    </div>
                                </div>
                                <div class="seoaic-sea-container">
                                    <div class="ad-campaigns-table">
                                        <h2><?php esc_html_e('Associated Ad Campaigns', 'seoaic');?></h2>
                                        <p class="subtext"><?php esc_html_e('Ad campaigns potentially linked to this page’s content or keywords.', 'seoaic');?></p>

                                        <div class="ad-campaigns-table-wrap"></div>
                                    </div>
                                </div>
                            </div>
                        <?php } ?>
                    </div>
                </div>
            </div>
            <?php
        }

        $html = ob_get_clean();

        return [
            'html' => $html
        ];
    }

    public function makeRankingRows($rows, $post_ids)
    {
        $postsRepository = new PostRepository();

        ob_start();

        foreach ($rows as $key => $row) {
            $link = $row['url'];
            $path = wp_parse_url($row['url'], PHP_URL_PATH);
            $slug = basename($path);
            $ID = isset($post_ids[$slug]) ? $post_ids[$slug] : 0;

            if (!empty($ID)) {
                $title = get_the_title($ID);
            }

            $pageData = $postsRepository->check_page_type_with_regex_and_message($path);

            if ($slug === '') {
                $title = $pageData['content'];
            }

            $impressions = intval($row['impressions']);
            $clicks = intval($row['clicks']);
            $position = floor($row['position']);
            $ctr = round($row['ctr'] * 100, 2);
            ?>
            <div data-keyword="<?php echo esc_html($row['title']); ?>" data-post-id="<?php echo esc_attr($ID); ?>"
                 class="additional-info-row additional-info-row-content">
                <div class="ranking-keyword">
                    <input type="checkbox" class="seoaic-checkbox" data-term="<?php echo esc_html($row['title']); ?>"
                           data-term-id="0">
                    <?php echo esc_html($row['title']); ?>
                </div>
                <div class="ranking-impressions"><?php echo esc_html($impressions); ?></div>
                <div class="ranking-clicks"><?php echo esc_html($clicks); ?></div>
                <div class="ranking-rank"><?php echo esc_html($position); ?></div>
                <div class="ranking-ctr"><?php echo esc_html($ctr); ?>%</div>
                <div class="edited">
                    <div><?php echo esc_html(get_the_modified_date('d/m/Y', $ID)); ?></div>
                    <div><?php echo esc_html(get_the_modified_date('g:i a', $ID)); ?></div>
                </div>
                <div class="published">
                    <div><?php echo esc_html(get_the_date('d/m/Y', $ID)); ?></div>
                    <div><?php echo esc_html(get_the_date('g:i a', $ID)); ?></div>
                </div>
                <div class="ranking-page">
                    <a href="<?php echo esc_attr($link); ?>" target="_blank">
                        <?php echo esc_html($title); ?>&nbsp;<span class="dashicons dashicons-external"></span>
                    </a>
                </div>
                <div class="ranking-serp">
                    <button
                            type="button"
                            data-keyword="<?php echo esc_attr($row['title']); ?>"
                            data-page-url="<?php echo esc_url($link); ?>"
                            data-post-id="<?php echo esc_attr($ID); ?>"
                            data-modal="#seoaic-rankings-serp-modal"
                            class="modal-button"
                    >Show
                    </button>
                </div>
            </div>
            <?php
        }

        $html = ob_get_clean();

        return [
            'html' => $html
        ];
    }

    private function get_search_results_links_db( $search_query = '', $seoaic_post = '', $seoaic_post_type = null, $date_from = '', $date_to = '')
    {
        if (empty($search_query) && empty($seoaic_post) && ! $seoaic_post_type && ! $date_from && ! $date_to) {
            return [];
        }

        global $wpdb;

        $allowed_post_types = $seoaic_post_type ? [$seoaic_post_type] : seoaic_get_post_types();
        $post_types_placeholder = implode("','", array_map('esc_sql', $allowed_post_types));
        $data['status'] = 'success';

        $query = "
            SELECT DISTINCT p.ID
            FROM {$wpdb->posts} p
            LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
            WHERE p.post_type IN ('$post_types_placeholder')
            AND p.post_status IN ('publish')
        ";

        if (!empty($search_query)) {
            $search_term = '%' . $wpdb->esc_like($search_query) . '%';
            $query .= $wpdb->prepare(" AND (p.post_title LIKE %s)", $search_term, $search_term);
        }

        if (!empty($seoaic_post)) {
            if ($seoaic_post === 'seoai') {
                $query .= " AND pm.meta_key = 'seoaic_posted' AND pm.meta_value = '1'";
            } elseif ($seoaic_post === 'not-seoai') {
                $query .= " AND p.ID NOT IN (
                    SELECT pm.post_id
                    FROM {$wpdb->postmeta} pm
                    WHERE pm.meta_key = 'seoaic_posted'
                )";
            }
        }

        if (!empty($date_from) && !empty($date_to)) {
            $query .= $wpdb->prepare(
                " AND p.post_date BETWEEN %s AND %s",
                "$date_from 00:00:00",
                "$date_to 23:59:59"
            );
        } elseif (!empty($date_from) && empty($date_to)) {
            $timestamp = strtotime($date_from);
            $year  = (int) date('Y', $timestamp);
            $month = (int) date('m', $timestamp);

            $query .= $wpdb->prepare(
                " AND YEAR(p.post_date) = %d AND MONTH(p.post_date) = %d",
                $year,
                $month
            );
        } elseif (!empty($date_to) && empty($date_from)) {
            $query .= $wpdb->prepare(
                " AND p.post_date <= %s",
                "$date_to 23:59:59"
            );
        }

        $post_ids = $wpdb->get_col($query); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.NotPrepared

        $links = array_map('get_permalink', $post_ids);

        if (empty($links)) {
            $data['status'] = 'error';
        }

        $data['links'] = $links;

        return $data;
    }

    /**
     * @param $id
     * @return bool
     */
    public function has_improvement_data($id)
    {

        $improvement_data = get_post_meta($id, self::GOOGLE_POST_IMPROVEMENT_IDEAS, true);
        if (is_array($improvement_data) || $improvement_data === 'loading') {
            return 'has-data';
        }
        if ($improvement_data === 'failed') {
            return 'failed';
        }
        return false;
    }

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

        $_post = wp_unslash($_POST);
        if (
            empty($_post['post_id'])
            || empty($_post['index_suggestion'])
        ) {
            SEOAICAjaxResponse::error('post IDs is required')->wpSend();
        }

        wp_send_json($result = $this->generateImprovementText($_post));
    }

    /**
     * @return void
     */
    public function generateImprovementText($_post)
    {
        $post_id = $_post['post_id'];
        $index = $_post['index_suggestion'];
        $type = $_post['type'];

        $improvements_ideas = get_post_meta($post_id, self::GOOGLE_POST_IMPROVEMENT_IDEAS, true);

        $meta_title = $this->seoMetaData($post_id)['title'];
        $meta_description = $this->seoMetaData($post_id)['description'];
        $get_post = get_post($post_id);
        $content = apply_filters('the_content', $get_post->post_content);

        if ($type === 'content') {
            if (!empty($improvements_ideas['suggestions']['meta'])) {
                $index = $index - 2;
            } else {
                $index = $index - 1;
            }
            $suggestion_title = $improvements_ideas['suggestions']['content'][$index]['title'];
            $suggestion_description = $improvements_ideas['suggestions']['content'][$index]['description'];
            $suggestion_implementation = $improvements_ideas['suggestions']['content'][$index]['implementation'];
        }

        if ($type === 'meta') {
            $suggestion_title = $improvements_ideas['suggestions']['meta']['title'];
            $suggestion_description = $improvements_ideas['suggestions']['meta']['description'];
            $suggestion_implementation = $improvements_ideas['suggestions']['meta']['implementation'];
        }

        $data = [
            "type" => $type,
            "data" => [
                "title" => $meta_title,
                "description" => $meta_description,
                "content" => '<h1>' . get_the_title($post_id) . '</h1>' . $content
            ],
            'language' => $this->seoaic->multilang->get_post_language($post_id),
            "suggestion" => [
                "title" => $suggestion_title ?? '',
                "description" => $suggestion_description ?? '',
                "implementation" => $suggestion_implementation ?? ''
            ]
        ];

        $response = $this->seoaic->curl->init('/api/ai/pages/suggestions/use', $data, true, true, true);
        $generated_content = !empty($response['data']['content']) ? $response['data']['content'] : '';

        if (!empty($generated_content) && $type === 'content') {
            $generated_content = !empty($response['data']['content']) ? $response['data']['content'] : '';
            $improvements_ideas['suggestions']['content'][$index]['generated_content'] = $generated_content;
        } else {
            $action_link = '<div data-id="' . $post_id . '" class="action-link modal-button" data-modal="#seoaic-seo-meta-improvement"></div>';
            $label_meta = esc_html__('SEO META', 'seoaic');
            $edit_button = esc_html__('Edit', 'seoaic');
            $done_button = esc_html__('Done', 'seoaic');
            $generated_meta = !empty($response['data']['content']) ? $response['data']['content'] : [];
            $meta_title = $generated_meta['title'];
            $meta_desc = $generated_meta['description'];
            $generated_content = '<div class="label-meta">' . $label_meta . '<button data-edit="' . $edit_button . '" data-done="' . $done_button . '" data-id="' . $post_id . '" class="seoaic_edit_seo_meta" type="button">' . $edit_button . '</button></div>' . $action_link . '<h4 id="seo_title_preview_' . $post_id . '">' . $meta_title . '</h4><p id="seo_description_preview_' . $post_id . '">' . $meta_desc . '</p>';
            $improvements_ideas['suggestions']['meta']['generated_content'] = $generated_meta;
            $improvements_ideas['suggestions']['meta']['generated_content']['html'] = $generated_content;
        }
        update_post_meta($post_id, self::GOOGLE_POST_IMPROVEMENT_IDEAS, $improvements_ideas);

        return [
            'generated_content' => '<div class="inner-text">' . $generated_content . '</div>',
            'generated_content_wo_wrapper' => $generated_content,
            'data' => $data
        ];
    }

    /**
     * @return void
     */
    public function addManuallyImprovementText()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $_post = wp_unslash($_POST);
        if (empty($_post['post_id'])) {
            SEOAICAjaxResponse::error('Post ID is required')->wpSend();
        }

        $post_id = $_post['post_id'];
        $text_value = $_post['text_value'] ?? '';

        $improvements_ideas = get_post_meta($post_id, self::GOOGLE_POST_IMPROVEMENT_IDEAS, true);

        if (!empty($text_value)) {
            if (!preg_match('/^\s*<[^>]+>/', $text_value)) {
                $text_value = '<p>' . esc_html($text_value) . '</p>';
            }
            $improvements_ideas['suggestions']['manually_added_content'] = $text_value;
            update_post_meta($post_id, self::GOOGLE_POST_IMPROVEMENT_IDEAS, $improvements_ideas);
        }

        wp_send_json([
            'manually_added_content' => $text_value
        ]);
    }

    /**
     * @param $array
     * @return array
     */
    private function mergeKeywordsResults($array, $urls_to_ids = false)
    {
        $result = [];

        foreach ($array['keywords'] as $keyword) {
            $url = $keyword['url'];
            if ($urls_to_ids) {
                $url = url_to_postid($url);
            }

            $data = [
                'title' => $keyword['title'],
                'clicks' => $keyword['clicks'],
                'impressions' => $keyword['impressions'],
                'position' => $keyword['position'],
            ];
            $result[$url][] = $data;
        }

        return $result;
    }

    /**
     * @return void
     */
    public function improvementsAddToQueue()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $_post = wp_unslash($_POST);
        if (empty($_POST['post_ids'])) {
            SEOAICAjaxResponse::error('Post IDs are required')->wpSend();
        }

        $search_urls = array_map('get_permalink', $_POST['post_ids']);

        $params_data = $this->getPostArgs();
        $params_data['search'] = $search_urls;

        $result = [];
        if (isset($params_data['brandedKeywords']) && $params_data['brandedKeywords'] !== 'all') {
            $result = $this->seoaic->curl->init('api/pruning/google/inspection/keywords', $params_data, true, true, true);
            $result = $this->mergeKeywordsResults($result);
        }

        $data_pages = [];
        $posts_with_keywords = [];

        foreach ($result as $url => $keywords) {
            $id = url_to_postid($url);
            $keywords_data = array_map(function ($item) {
                return [
                    'keyword' => $item['title'],
                    'rank' => $item['position'],
                    'impressions' => $item['impressions']
                ];
            }, is_array($keywords) ? array_slice($keywords, 0, 10) : []);

            $data_pages[] = $this->preparePageData($id, $keywords_data);
            $posts_with_keywords[] = $id;
        }

        foreach ($_POST['post_ids'] as $id) {
            if (!in_array($id, $posts_with_keywords)) {
                $data_pages[] = $this->preparePageData($id, [[
                    'keyword' => strtolower(get_the_title($id)),
                    'rank' => 1,
                    'impressions' => 0
                ]]);
            }
        }

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

        $this->seoaic->curl->init('/api/ai/pages/analyze', ['pages' => $data_pages], true, true, true);
        $this->massAnalysis($_post['post_ids']);

        wp_send_json(['data' => $data_pages]);
        wp_die();
    }

    /**
     * @param int $id
     * @param array $keywords_data
     * @return array
     */
    private function preparePageData($id, $keywords_data)
    {
        $post = get_post($id);
        $meta = $this->seoMetaData($id);
        $meta_title = $meta['title'] ?: 'no title';

        return [
            'page_id' => $id,
            'title' => $meta_title,
            'description' => $meta['description'],
            'content' => '<h1>' . get_the_title($id) . '</h1>' . apply_filters('the_content', $post->post_content),
            'language' => SEOAIC_SETTINGS::getLanguage(),
            'location' => SEOAIC_SETTINGS::getLocation(),
            'keywords' => $keywords_data,
            'page_url' => get_the_permalink($id),
        ];
    }

    /**
     * @return void
     */
    public function getContentImprovementSectionHTML()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $_post = wp_unslash($_POST);
        if (empty($_post['post_id'])) {
            SEOAICAjaxResponse::error('Post ID is required')->wpSend();
        }

        $post_id = $_post['post_id'];
        $html = '';
        $status = 'success';

        $improvements_ideas = get_post_meta($post_id, self::GOOGLE_POST_IMPROVEMENT_IDEAS, true);
        $keywords = get_post_meta($post_id, self::QUERY_GOOGLE_FIELD, true);

        if ($improvements_ideas !== 'failed' && !is_array($improvements_ideas)) {
            update_post_meta($post_id, self::GOOGLE_POST_IMPROVEMENT_IDEAS, 'loading');
            $improvements_ideas = 'loading';
            $status = 'loading';
        }

        if ($improvements_ideas === 'failed') {
            $status = 'failed';
        }

        $target_audience = $improvements_ideas['audience'] ?? '';
        $main_intents = $improvements_ideas['intents']['main'] ?? '';
        $sub_intents = $improvements_ideas['intents']['sub'] ?? '';
        $competitors = $improvements_ideas['competitors'] ?? '';
        $suggestions = $improvements_ideas['suggestions'] ?? '';

        $sub_intents_list = is_array($sub_intents) ? '<ul><li>' . implode('</li><li>', $sub_intents) . '</li></ul>' : '';
        $keywords_list = is_array($keywords) ? '<ul><li>' . implode('</li><li>', array_column(array_slice($keywords, 0, 10), 'keyword')) . '</li></ul>' : '';
        $competitors_list = is_array($competitors) ? '<ul><li>' . implode('</li><li>', array_map(function ($item) {
                $base_url = wp_parse_url($item['url'], PHP_URL_SCHEME) . '://' . wp_parse_url($item['url'], PHP_URL_HOST);
                return "<a target='_blank' href='{$item['url']}'>$base_url</a>";
            }, $competitors)) . '</li></ul>' : '';

        $suggestions_list = '';
        $index_move = 1;
        $link = esc_html__('Generate example text', 'seoaic');
        $generating_link = esc_html__('Generating', 'seoaic');
        if (isset($suggestions['meta']) && is_array($suggestions['meta'])) {
            $title = $suggestions['meta']['title'];
            $description = $suggestions['meta']['description'];
            $implementation = $suggestions['meta']['implementation'];
            $index_move = 2;
            $suggestions_list .= "<h3>" . esc_html__('SEO meta idea', 'seoaic') . "</h3>";
            $suggestions_list .= "<div data-i=\"1\" data-type=\"meta\" data-id=\"$post_id\" class=\"improvement-idea-card meta-data\">
                                    <div class=\"improvement-card-inner\">
                                        <h4>$title</h4>
                                        <p data-implementation=\"$implementation\">$description</p>
                                        <a data-generate=\"$link\" data-generating=\"$generating_link\" class=\"accent\" href=\"#\">$link</a>
                                    </div>
                                  </div>";
        }
        if (isset($suggestions['content']) && is_array($suggestions['content'])) {
            $suggestions_list .= "<h3>" . esc_html__('Content improvement ideas', 'seoaic') . "</h3>";
            foreach ($suggestions['content'] as $i => $item) {
                $index = $i + $index_move;
                $view_result_text = esc_html__('View', 'seoaic');
                $view_result_link = !empty($suggestions['content'][$i]['generated_content']) ? '<a class="accent ml-15" data-view-index="" href="#">' . $view_result_text . '</a>' : '';
                $title = $item['title'] ? esc_html($item['title']) : esc_html__('No title', 'seoaic');
                $description = $item['description'] ? esc_html($item['description']) : esc_html__('No description', 'seoaic');
                $implementation = $item['implementation'] ? esc_html($item['implementation']) : esc_html__('No implementation', 'seoaic');

                $suggestions_list .= "<div data-i=\"$index\" data-type=\"content\" data-id=\"$post_id\" class=\"improvement-idea-card\">
                                    <div class=\"improvement-card-inner\">
                                        <h4>$title</h4>
                                        <p data-implementation=\"$implementation\">$description</p>
                                        <a data-view-result_text='$view_result_text' data-generate=\"$link\" data-generating=\"$generating_link\" class=\"accent\" href=\"#\">$link</a>
                                        $view_result_link
                                    </div>
                                  </div>";
            }
        } else {
            $suggestions_list .= "<p>" . esc_html__('No content suggestions available.', 'seoaic') . "</p>";
        }

        $improvements_list = '';
        if (isset($suggestions['meta']) && is_array($suggestions['meta'])) {
            $improvements_list .= "<h3>" . esc_html__('SEO meta preview', 'seoaic') . "</h3>";
            $seo_meta = !empty($suggestions['meta']['generated_content']['html']) ? $suggestions['meta']['generated_content']['html'] : '';
            $content = !empty($suggestions['meta']) ? '<div class="inner-text">' . wp_kses_post($seo_meta) . '</div>' : '';
            $improvements_list .= "<div data-i=\"1\" data-id=\"$post_id\" class=\"generated_content-card meta-data\">$content</div>";
        }

        if (isset($suggestions['content']) && is_array($suggestions['content'])) {
            $improvements_list .= "<h3>" . esc_html__('Content preview', 'seoaic') . "</h3>";
            foreach ($suggestions['content'] as $i => $item) {
                $index = $i + $index_move;
                $generated_content = !empty($item['generated_content']) ? '<div class="inner-text">' . wp_kses_post($item['generated_content']) . '</div>' : '';
                $improvements_list .= "<div data-i=\"$index\" data-id=\"$post_id\" class=\"generated_content-card\">$generated_content</div>";
            }
        } else {
            $improvements_list .= "<p>" . esc_html__('No suggestions available.', 'seoaic') . "</p>";
        }

        $manual_field = (is_array($suggestions) && !empty($suggestions['manually_added_content']))
            ? '<div class="inner-text">' . wp_kses_post($suggestions['manually_added_content']) . '</div>'
            : '';
        $improvements_list .= "<div data-i=\"manual-field\" data-id=\"$post_id\" class=\"generated_content-card manual-field\">$manual_field</div>";
        $edit_link = get_edit_post_link($post_id);
        $update = esc_html__('Update', 'seoaic');
        $content_score = $this->ci_page_score_details($post_id);
        $html .= '
            <button type="button" data-id="' . $post_id . '" class="update-improvements active">' . $update . '</button>
            <div class="top-section">
                <div class="column">
                    <h3>' . esc_html__('Content score', 'seoaic') . '</h3><div class="inner-improvement-content"><p>' . $content_score['main_score'] . '</p></div>
                </div>
                <div class="column">
                    <h3>' . esc_html__('Main Intent', 'seoaic') . '</h3><div class="inner-improvement-content"><p>' . $main_intents . '</p></div>
                </div>
                <div class="column">
                    <h3>' . esc_html__('Sub Intent', 'seoaic') . '</h3><div class="inner-improvement-content">' . $sub_intents_list . '</div>
                </div>
                <div class="column">
                    <h3>' . esc_html__('Target Audience', 'seoaic') . '</h3><div class="inner-improvement-content"><p>' . $target_audience . '</p></div>
                </div>
                <div class="column">
                    <h3>' . esc_html__('Main Search Terms', 'seoaic') . '</h3><div class="inner-improvement-content">' . $keywords_list . '</div>
                </div>
                <div class="column">
                    <h3>' . esc_html__('Top Competitors', 'seoaic') . '</h3><div class="inner-improvement-content">' . $competitors_list . '</div>
                </div>
            </div>
            <div class="bottom-section">
                <div class="column">
                    ' . $suggestions_list . '
                </div>
                <div class="column">
                    <div class="post-preview-improvements">' . $improvements_list . '</div>
                    <div class="form-section">
                        <label>' . esc_html__('Improve Field', 'seoaic') . '</label>
                        <textarea rows="5" class="seoaic-form-item form-input light mb-0"></textarea>
                        <button type="submit" data-edit-link="' . $edit_link . '" data-id="' . $post_id . '" class="seoaic-popup__btn">' . esc_html__('Copy and Add to Page', 'seoaic') . '</button>
                    </div>
                </div>
            </div>';

        $loading_html = "<div class=\"loading-data\" data-id=\"$post_id\"><div class=\"loading-label accent\">" . esc_html__('Analysing', 'seoaic') . "</div><div class=\"loading-icon\"><div class=\"loader-ellipsis small show\"></div></div>";

        if ($status === 'failed') {
            $html = '<div class="failed-data" data-id="' . $post_id . '"><div class="failed-label red">' . esc_html__('Failed to load', 'seoaic') . '</div></div><button type="button" data-id="' . $post_id . '" class="update-improvements active">' . esc_html__('refresh', 'seoaic') . '</button>';
        }

        wp_send_json([
            'status' => $status,
            'html' => $status === 'loading' ? $loading_html : $html,
            'meta_idea_title' => esc_html__('SEO meta improvement idea', 'seoaic'),
            'meta_preview_title' => esc_html__('SEO meta preview', 'seoaic'),
            'content_ideas_title' => esc_html__('Content improvement ideas', 'seoaic'),
            'content_ideas_preview_title' => esc_html__('Content preview', 'seoaic'),
            'score_preview' => $content_score['score_preview'],
        ]);

        wp_die();
    }

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

        $_post = wp_unslash($_POST);
        if (empty($_post['post_id'])) {
            SEOAICAjaxResponse::error(esc_html__('Post ID is required', 'seoaic'))->wpSend();
        }

        $html = '';
        $postID = $_post['post_id'];
        $posts = $this->postsRepository->getByIDs([$postID]);

        if (
            empty($posts)
            || empty($posts[0])
            || empty($posts[0]->ID)
        ) {
            SEOAICAjaxResponse::error(esc_html__('Post not found', 'seoaic'))->wpSend();
        }

        if (empty($posts[0]->post_title)) {
            SEOAICAjaxResponse::error(esc_html__("Post title can't be empty", 'seoaic'))->wpSend();
        }

        try {
            $post = $posts[0];
            $postIssues = $this->contentImprovementSuggestionsRepository->getForPost($post);

            $pendingPostIssues = array_filter($postIssues, function ($postIssue) {
                return ContentImprovementSuggestionsRepository::CI_POST_ISSUE_STATUS_PENDING == $postIssue['status'];
            });

            $requestedPostIssues = array_filter($postIssues, function ($postIssue) {
                return ContentImprovementSuggestionsRepository::CI_POST_ISSUE_STATUS_REQUESTED == $postIssue['status'];
            });

            $completedPostIssues = array_filter($postIssues, function ($postIssue) {
                return ContentImprovementSuggestionsRepository::CI_POST_ISSUE_STATUS_COMPLETED == $postIssue['status'];
            });

            $statusesPostsForDisplaying = array_merge($pendingPostIssues, $requestedPostIssues, $completedPostIssues);

            if (!empty($statusesPostsForDisplaying)) {
                $html = $this->makeAutomatedContentSuggestionsTable($post, $statusesPostsForDisplaying);

                if (!empty($pendingPostIssues)) {
                    $suggestionsGenerateInstance = new ContentImprovementSuggestionsGenerate($this->seoaic);
                    $seoPlugin = SEOPluginsHelper::getAvailableSEOPlugin();
                    $metaDescription = $seoPlugin ? $seoPlugin->getDescription($post->ID) : '';
                    $metaDescription = !empty($metaDescription) ? $metaDescription : 'no meta description';
                    $language = $this->seoaic->multilang->get_post_language($post->ID, 'name');
                    $content = !empty($post->post_content) ? $post->post_content : 'no content';

                    $data = [
                        'post_id'       => $post->ID,
                        'language'      => $language,
                        'title'         => $post->post_title,
                        'description'   => $metaDescription,
                        'content'       => $content,
                        'issues'        => array_map(
                            function ($item) {
                                return $item['issue'];
                            },
                            $pendingPostIssues
                        ),
                    ];

                    $preparedData = $suggestionsGenerateInstance->prepareData($data);
                    $this->postsMassActionRun($suggestionsGenerateInstance, $preparedData, false);

                    $errors = $suggestionsGenerateInstance->getErrors();

                    if (!empty($errors)) {
                        SEOAICAjaxResponse::error("Errors found:<br>" . $errors)->wpSend();
                    }
                }

            } else {
                $html = '<div class="tc pb-10">' . esc_html__('No issues found.', 'seoaic') . '</div>';
            }
        } catch (Exception $e) {
            SEOAICAjaxResponse::error($e->getMessage())->wpSend();
        }

        SEOAICAjaxResponse::success()->addFields([
            'html' => $html,
        ])->wpSend();
    }

    private function makeAutomatedContentSuggestionsTable(WP_Post $post, array $postIssues = [])
    {
        ob_start();
        ?>
        <div class="seoaic-improvement-automated-suggestions-table">
            <div class="table-row heading d-flex">
                <div class="seoaic-suggestion-issue-col"><?php esc_html_e('Issue', 'seoaic');?></div>
                <div class="w-100"><?php esc_html_e('Current', 'seoaic');?></div>
                <div class="w-100"><?php esc_html_e('New', 'seoaic');?></div>
                <div class="seoaic-suggestion-actions-col"></div>
            </div>
            <?php
            foreach ($postIssues as $postIssue) {
                // error_log('postIssue '.print_r($postIssue, true));
                $suggestion = $postIssue['suggestion'];
                $hasDescription = !empty($suggestion->getDescription());
                $postSuggestionId = $post->ID . '--' . $suggestion->getId();
                $acceptActionId = $postSuggestionId . '--' . 'accept';
                $rejectActionId = $postSuggestionId . '--' . 'reject';
                $isCompleted = $postIssue['status'] == ContentImprovementSuggestionsRepository::CI_POST_ISSUE_STATUS_COMPLETED;
                $btnDisabledAttr = !$isCompleted ? 'disabled' : '';
                ?>
                <div
                    class="table-row position-relative seoaic-ci-post-issue-row seoaic-ci-post-issue-status-<?php echo esc_attr($postIssue['status']);?>"
                    id="<?php echo esc_attr($postSuggestionId);?>"
                >
                    <div
                        class="seoaic-suggestion-issue-col <?php echo esc_attr($hasDescription ? 'has-description' : '');?>"
                        title="<?php echo esc_attr($hasDescription ? $suggestion->getDescription() : '');?>"
                    >
                        <?php echo esc_html($suggestion->getLabel());?>
                    </div>
                    <div class="seoaic-suggestion-current-col w-100"><?php echo wp_kses($suggestion->currentValue($post), [
                        'b' => [],
                        'span' => [
                            'class' => [],
                        ],
                        'a' => [
                            'href' => [],
                            'target' => [],
                        ],
                    ]);?></div>
                    <div class="seoaic-suggestion-new-col w-100">
                    <?php
                    if (
                        $isCompleted
                        && !empty($postIssue['new_value'])) {
                            echo esc_html($postIssue['new_value']);
                        } else {
                            ?>
                            <div class="w-100 seoaic-content-placeholder">
                                <?php echo wp_kses($suggestion->makePlaceholder(), [
                                    'div' => [
                                        'class' => [],
                                    ],
                                    'p' => [
                                        'class' => [],
                                    ],
                                    'span' => [
                                        'class' => [],
                                    ],
                                ]);?>
                            </div>
                            <?php
                        }
                    ?>
                    </div>
                    <div class="seoaic-suggestion-actions-col text-end">
                        <?php
                        if ($suggestion->canGenerateSuggestion) {
                            ?>
                            <button
                                class="seoaic-automated-suggestion-btn seoaic-automated-suggestion-accept"
                                id="<?php echo esc_attr($acceptActionId);?>"
                                <?php echo esc_attr($btnDisabledAttr);?>
                            ><?php esc_html_e("Accept", "seoaic");?></button>
                            <?php
                        }
                        ?>
                        <button
                            class="seoaic-automated-suggestion-btn seoaic-automated-suggestion-reject"
                            id="<?php echo esc_attr($rejectActionId);?>"
                            <?php echo esc_attr($btnDisabledAttr);?>
                        ><?php esc_html_e("Reject", "seoaic");?></button>
                    </div>
                </div>
                <?php
            }
            ?>
        </div>
        <?php

        return ob_get_clean();
    }

    function automatedSuggestionsCheckStatusAjax()
    {
        $instance = new ContentImprovementSuggestionsGenerate($this->seoaic);
        $this->postsMassActionCheckStatus($instance);
    }

    function automatedSuggestionsStopPollingAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $instance = new ContentImprovementSuggestionsGenerate($this->seoaic);
        $this->postsMassActionStop($instance, false);

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

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

        $__POST = wp_unslash($_POST);

        if (
            empty($__POST['post_id'])
            || empty($__POST['suggestion_id'])
            || empty($__POST['suggestion_action'])
        ) {
            SEOAICAjaxResponse::alert(esc_html__("Not enough parameters.", "seoaic"))->wpSend();
        }

        if (!is_numeric($__POST['post_id'])) {
            SEOAICAjaxResponse::alert(esc_html__("Wrong parameters.", "seoaic"))->wpSend();
        }

        try {
            $suggestion = $this->contentImprovementSuggestionsRepository->getById($__POST['suggestion_id']);

            if (!$suggestion) {
                SEOAICAjaxResponse::alert(esc_html__("Suggestion not found.", "seoaic"))->wpSend();
            }

            if ('reject' == $__POST['suggestion_action']) {
                if ($suggestion->reject($__POST['post_id'])) {
                    SEOAICAjaxResponse::success()->wpSend();
                } else {
                    SEOAICAjaxResponse::alert(esc_html__("Not rejected", "seoaic"))->wpSend();
                }

            } else if ('accept' == $__POST['suggestion_action']) {
                if ($suggestion->apply($__POST['post_id'])) {
                    SEOAICAjaxResponse::success()->wpSend();
                } else {
                    SEOAICAjaxResponse::alert(esc_html__("Not accepted", "seoaic"))->wpSend();
                }
            }

        } catch (Exception $e) {
            SEOAICAjaxResponse::alert(esc_html__("Error: ", "seoaic") . $e->getMessage())->wpSend();
        }

        SEOAICAjaxResponse::alert(esc_html__("Something went wrong", "seoaic"))->wpSend();
    }

    public function massAnalysis($ids)
    {
        $return = [];
        foreach ($ids as $id) {
            $improvements_ideas = get_post_meta($id, self::GOOGLE_POST_IMPROVEMENT_IDEAS, true);

            update_post_meta($id, self::POST_CONTENT_IS_SCANNIG, '1');
            if ($improvements_ideas == 'failed' || !is_array($improvements_ideas)) {
                update_post_meta($id, self::GOOGLE_POST_IMPROVEMENT_IDEAS, 'loading');
            }

            $return[] = $id;
        }

        return $return;
    }

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

        $data = ['page_ids' => $_POST['ids']];

        $status = $this->seoaic->curl->init('/api/ai/pages/analyze/status', $data, true, true, true);
        $failed_ids = $status['failed'] ?? [];
        $pending_ids = $status['pending'] ?? [];
        $completed_ids = $status['completed'] ?? [];
        $loaded = [];

        if (array_intersect($data['page_ids'], $completed_ids)) {
            $data = ['page_ids' => $completed_ids];
            $response = $this->seoaic->curl->init('/api/ai/pages/analyze/content', $data, true, true, true);
            foreach ($response as $value) {
                if (!empty($value['pageId'])) {
                    $pageId = $value['pageId'];
                    $contentData = $value['content'] ?? '';
                    $contentKeywords = $value['params']['keywords'] ?? '';
                    $score = $contentData['score'] ?? '';
                    update_post_meta($pageId, self::GOOGLE_POST_IMPROVEMENT_IDEAS, $contentData);
                    update_post_meta($pageId, self::POST_CONTENT_IS_SCANNIG, '0');
                    update_post_meta($pageId, self::QUERY_GOOGLE_FIELD, $contentKeywords);
                    update_post_meta($pageId, self::CI_PAGE_SCORE_META, $score);
                    $loaded[] = $pageId;
                }
            }
        }

        foreach ($failed_ids as $id) {
            update_post_meta($id, self::GOOGLE_POST_IMPROVEMENT_IDEAS, 'failed');
            update_post_meta($pageId, self::POST_CONTENT_IS_SCANNIG, '0');
            $loaded[] = [$id => 'failed'];
        }

        foreach ($data['page_ids'] as $id) {
            $loading_status = get_post_meta($id, self::GOOGLE_POST_IMPROVEMENT_IDEAS, true);
            if (
                !in_array($id, $pending_ids) &&
                !in_array($id, $completed_ids) &&
                !in_array($id, $failed_ids) &&
                $loading_status === 'loading') {

                update_post_meta($id, self::GOOGLE_POST_IMPROVEMENT_IDEAS, 'failed');
                update_post_meta($pageId, self::POST_CONTENT_IS_SCANNIG, '0');
                $loaded[] = [$id => 'failed'];

            }
        }

        return $loaded;
    }

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

        $_post = wp_unslash($_POST);

        if (empty($_post['ids'])) {
            SEOAICAjaxResponse::alert('Post ID is required')->wpSend();
        }

        $postId = $_post['ids'][0];
        $edit_url = get_edit_post_link($postId);
        $this->setDataImprovementsLoadJob();

        SEOAICAjaxResponse::redirect()->redirectTo($edit_url . '&content-improvement=true', true)->wpSend();
    }

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

        $data = $this->setDataImprovementsLoadJob();

        wp_send_json($data);
    }

    public function get_seo_meta_data($post_id)
    {
        if (defined('WPSEO_VERSION')) {
            $yoast_wpseo_title = get_post_meta($post_id, '_yoast_wpseo_title', true);
            $seo_data['title'] = $yoast_wpseo_title ? $yoast_wpseo_title : get_the_title($post_id);
            $seo_data['description'] = get_post_meta($post_id, '_yoast_wpseo_metadesc', true);
        } elseif (defined('AIOSEO_VERSION')) {
            $aioseop_title = get_post_meta($post_id, '_aioseop_title', true);
            $seo_data['title'] = $aioseop_title ? $aioseop_title : get_the_title($post_id);
            $seo_data['description'] = get_post_meta($post_id, '_aioseop_description', true);
        } elseif (defined('RANK_MATH_VERSION')) {
            $rank_math_title = get_post_meta($post_id, 'rank_math_title', true);
            $seo_data['title'] = $rank_math_title ? $rank_math_title : get_the_title($post_id);
            $seo_data['description'] = get_post_meta($post_id, 'rank_math_description', true);
        } else {
            $seo_data['title'] = get_the_title($post_id);
            $seo_data['description'] = get_the_excerpt($post_id);
        }

        return $seo_data;
    }

    public function update_seo_meta_data($post_id, $seo_title, $seo_description)
    {

        if (defined('WPSEO_VERSION')) {
            update_post_meta($post_id, '_yoast_wpseo_title', $seo_title);
            update_post_meta($post_id, '_yoast_wpseo_metadesc', $seo_description);
        } elseif (defined('AIOSEO_VERSION')) {
            update_post_meta($post_id, '_aioseop_title', $seo_title);
            update_post_meta($post_id, '_aioseop_description', $seo_description);
        } elseif (defined('RANK_MATH_VERSION')) {
            update_post_meta($post_id, 'rank_math_title', $seo_title);
            update_post_meta($post_id, 'rank_math_description', $seo_description);
        } else {
            return 'no_plugin';
        }

        return true;
    }

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

        $_post = wp_unslash($_POST);
        if (empty($_post['post_id'])) {
            SEOAICAjaxResponse::error('Post ID is required')->wpSend();
        }

        $post_id = $_post['post_id'];

        $improvements_ideas = get_post_meta($post_id, self::GOOGLE_POST_IMPROVEMENT_IDEAS, true);
        $generated_title = $improvements_ideas['suggestions']['meta']['generated_content']['title'];
        $generated_content = $improvements_ideas['suggestions']['meta']['generated_content']['description'];
        $original_title = $this->get_seo_meta_data($post_id)['title'];
        $original_content = $this->get_seo_meta_data($post_id)['description'];

        $seo_meta['original'] = [
            'title' => $original_title,
            'description' => $original_content,
        ];

        $titles_identical = $generated_title === $original_title;
        $descriptions_identical = $generated_content === $original_content;

        $identical = 'identical';
        $set_new = esc_html__('Metas are identical', 'seoaic');
        if (!$titles_identical || !$descriptions_identical) {
            $identical = 'set-new-to-page';
            $set_new = esc_html__('Set new to page', 'seoaic');
        }

        $improvements_ideas['suggestions']['meta']['compare'] = $seo_meta;
        update_post_meta($post_id, self::GOOGLE_POST_IMPROVEMENT_IDEAS, $improvements_ideas);

        $edit_button = esc_html__('Edit', 'seoaic');
        $done_button = esc_html__('Done', 'seoaic');

        $html = '<div class="compare-meta">
                    <div class="original">
                    <h4 class="original-label">' . esc_html__('Your original meta', 'seoaic') . '</h4>
                    <div class="title"><span class="label-meta">' . esc_html__('Title:', 'seoaic') . '</span><span id="seo_title_oroginal_preview_' . $post_id . '_modal">' . $this->get_seo_meta_data($post_id)['title'] . '</span></div>
                    <div class="description"><span class="label-meta">' . esc_html__('Description:', 'seoaic') . '</span><span id="seo_description_oroginal_preview_' . $post_id . '_modal">' . $this->get_seo_meta_data($post_id)['description'] . '</span></div>
                    <a href="#" class="original-action-link accent seoaic-modal-close">' . esc_html__('Leave it as it is', 'seoaic') . '</a>
                 </div>
                 <div class="generated">
                    <h4 class="original-label">' . esc_html__('Generated meta', 'seoaic') . '<button data-edit="' . $edit_button . '" data-done="' . $done_button . '" data-id="' . $post_id . '" class="seoaic_edit_seo_meta" type="button">' . $edit_button . '</button></h4>
                    <div class="title"><span class="label-meta">' . esc_html__('Title:', 'seoaic') . '</span><span id="seo_title_preview_' . $post_id . '_modal">' . $generated_title . '</span></div>
                    <div class="description"><span class="label-meta">' . esc_html__('Description:', 'seoaic') . '</span><span id="seo_description_preview_' . $post_id . '_modal">' . $generated_content . '</span></div>
                    <a href="#" target="_blank" data-id="' . $post_id . '" class="original-action-link ' . $identical . ' accent">' . $set_new . '</a>
                    </div>
                </div>';

        wp_send_json($html);
    }

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

        $_post = wp_unslash($_POST);
        if (empty($_post['post_id'])) {
            SEOAICAjaxResponse::error('Post ID is required')->wpSend();
        }

        $post_id = $_post['post_id'];

        $improvements_ideas = get_post_meta($post_id, self::GOOGLE_POST_IMPROVEMENT_IDEAS, true);

        $generated_title = $improvements_ideas['suggestions']['meta']['generated_content']['title'];
        $generated_content = $improvements_ideas['suggestions']['meta']['generated_content']['description'];

        $updated_seo_meta = $this->update_seo_meta_data($post_id, $generated_title, $generated_content);

        $edit_link = get_edit_post_link($post_id);

        $result = [
            'status' => 'success',
            'label' => esc_html__('Done! Open in editor', 'seoaic'),
            'editor_link' => $edit_link,
            'new_title' => $this->get_seo_meta_data($post_id)['title'],
            'new_desc' => $this->get_seo_meta_data($post_id)['description'],
        ];

        if (!$updated_seo_meta) {
            $result['status'] = 'error';
        }

        if ($updated_seo_meta === 'no_plugin') {
            $result['status'] = $updated_seo_meta;
            $result['label'] = esc_html__('No SEO plugin found', 'seoaic');
        }

        wp_send_json($result);
    }

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

        $_post = wp_unslash($_POST);
        if (empty($_post['post_id'])) {
            SEOAICAjaxResponse::error('Post ID is required')->wpSend();
        }

        $post_id = $_post['post_id'];
        $new_title = $_post['seo_title'];
        $new_desc = $_post['seo_desc'];

        if (empty($new_title) || empty($new_desc)) {
            SEOAICAjaxResponse::alert('Title or description cannot be empty')->wpSend();
        }

        $label_meta = esc_html__('SEO META', 'seoaic');
        $edit_button = esc_html__('Edit', 'seoaic');
        $done_button = esc_html__('Done', 'seoaic');
        $action_link = '<div data-id="' . $post_id . '" class="action-link modal-button" data-modal="#seoaic-seo-meta-improvement"></div>';

        $improvements_ideas = get_post_meta($post_id, self::GOOGLE_POST_IMPROVEMENT_IDEAS, true);
        $generated_content = '<div class="label-meta">' . $label_meta . '<button data-edit="' . $edit_button . '" data-done="' . $done_button . '" data-id="' . $post_id . '" class="seoaic_edit_seo_meta" type="button">' . $edit_button . '</button></div>' . $action_link . '<h4 id="seo_title_preview_' . $post_id . '">' . $new_title . '</h4><p id="seo_description_preview_' . $post_id . '">' . $new_desc . '</p>';
        $improvements_ideas['suggestions']['meta']['generated_content']['title'] = $new_title;
        $improvements_ideas['suggestions']['meta']['generated_content']['description'] = $new_desc;
        $improvements_ideas['suggestions']['meta']['generated_content']['html'] = $generated_content;

        $update = update_post_meta($post_id, self::GOOGLE_POST_IMPROVEMENT_IDEAS, $improvements_ideas);

        // set button
        $original_title = $this->get_seo_meta_data($post_id)['title'];
        $original_content = $this->get_seo_meta_data($post_id)['description'];

        $titles_identical = $new_title === $original_title;
        $descriptions_identical = $new_desc === $original_content;

        $identical = 'identical';
        $set_new = esc_html__('Metas are identical', 'seoaic');
        if (!$titles_identical || !$descriptions_identical) {
            $identical = 'set-new-to-page';
            $set_new = esc_html__('Set new to page', 'seoaic');
        }

        if ($update) {
            wp_send_json([
                'status' => 'success',
                'seo_title' => $new_title,
                'seo_desc' => $new_desc,
                'button' => '<a href="#" target="_blank" data-id="' . $post_id . '" class="original-action-link ' . $identical . ' accent">' . $set_new . '</a>'
            ]);
        }
    }

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

        $args = [
            'post_type' => 'any',
            'post_status' => 'any',
            'meta_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
                [
                //    'key' => self::GOOGLE_POST_IMPROVEMENT_IDEAS,
                //    'value' => 'loading',
                //    'compare' => '='

                    'key' => self::GOOGLE_POST_IMPROVEMENT_IDEAS,
                    'compare' => 'EXISTS'
                ]
            ],
            'fields' => 'ids',
            'nopaging' => true,
        ];

        $query = new \WP_Query($args);

        $post_ids = $query->posts;

        wp_reset_postdata();

        if (!empty($post_ids)) {
            foreach ($post_ids as $post_id) {
                delete_post_meta($post_id, self::GOOGLE_POST_IMPROVEMENT_IDEAS);
            }
        }

        $this->seoaic->curl->init('/api/ai/pages/analyze/clear', ['full' => true], true, true, true);

        wp_send_json($post_ids);
    }

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

        $params = $this->getPostArgs();
        $result = $this->seoaic->curl->init('api/pruning/google/inspection/keywords', $params, true, true, true);
        $ID = $params['post_id'];
        $rows = '<div class="error-info">' . esc_html__('There are no keywords for this period', 'seoaic') . '</div>';
        if (!empty($result['keywords'])) {
            $rows = $this->makeKeywordsRows($result['keywords'], $ID);
        }

        wp_send_json([
            'rows' => $rows,
            'keywords' => $result['keywords']
        ]);
    }

    public function makeKeywordsRows($rows, $ID)
    {
        ob_start();
        foreach ($rows as $item) :
            $impressions = intval($item['impressions']);
            $clicks = intval($item['clicks']);
            $ctr = round($item['ctr'] * 100, 2);
        ?>
            <div data-keyword="<?php echo esc_html($item['title']) ?>"
                 data-page-url="<?php echo esc_url($item['url']); ?>"
                 data-post-id="<?php echo esc_attr($ID) ?>"
                 class="additional-info-row additional-info-row-content">
                <div class="additional-keyword">
                    <input type="checkbox" class="seoaic-checkbox"
                           data-term="<?php echo esc_html($item['title']) ?>"
                           data-term-id="0">
                    <?php echo esc_html($item['title']) ?>
                </div>
                <div class="additional-clicks"><?php echo esc_html($clicks) ?></div>
                <div class="additional-impressions"><?php echo esc_html($impressions) ?></div>
                <div class="additional-ctr"><?php echo esc_html($ctr); ?>%</div>
                <div class="additional-rank"><?php echo esc_html(round($item['position'])) ?></div>
                <div class="also-ask-map-additional-keyword-row">
                    <a
                            href="#"
                            data-post-id="<?php echo esc_attr($ID);?>"
                            data-keyword="<?php echo esc_html($item['title']) ?>"
                            class="modal-button seoaic-generate-also-ask-map accent fs-16 dashicons dashicons-networking"
                            data-modal="#seoaic-also-ask-generate-ideas"
                            title="<?php esc_attr_e("Create Content map ", 'seoaic');?>">
                    </a>
                </div>
            </div>
        <?php endforeach;

        return ob_get_clean();
    }

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

        $checkIntegratedSiteWithGoogle = $this->isSiteIntegratedWithGoogle();

        $_post = wp_unslash($_POST);

        $months = !empty($_post['months']) ? sanitize_text_field($_post['months']) : 12;
        $endDate = !empty($_post['endDate']) ? sanitize_text_field($_post['endDate']) : '';

        $data = ['months' => $months];

        if (!empty($endDate)) {
            $data['endDate'] = str_replace('/', '-', $endDate);
        }

        $result = $this->seoaic->curl->init('api/pruning/google/inspection/keywords/graph', $data, true, true, true);

        SEOAICAjaxResponse::success()
            ->addFields(['data' => $result])
            ->wpSend();
    }

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

        $checkIntegratedSiteWithGoogle = $this->isSiteIntegratedWithGoogle();

        global $SEOAIC_OPTIONS;

        $params = $this->getPostArgs();
		$result = $this->seoaic->curl->init('api/pruning/google/automated', $params, true, true, true);

        $postsRepository = new PostRepository();
        $associativePosts = $postsRepository->get_associative_posts_array('post_name', ['post_title', 'ID', 'post_modified']);

        $redirects = !empty($SEOAIC_OPTIONS['redirect']) ? $SEOAIC_OPTIONS['redirect'] : [];

        $response = [
            'result' => $result,
            'associativePosts' => $associativePosts,
            'redirects' => $redirects,
        ];

        wp_send_json($response);
    }

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

        $checkIntegratedSiteWithGoogle = $this->isSiteIntegratedWithGoogle();

        global $SEOAIC_OPTIONS;

        $params = $this->getPostArgs();
		$result = $this->seoaic->curl->init('api/pruning/google/cannibalization', $params, true, true, true);
        $redirects = !empty($SEOAIC_OPTIONS['redirect']) ? $SEOAIC_OPTIONS['redirect'] : [];

        $associativePosts = $this->postsRepository->get_associative_posts_array(true);

        $response = [
            'result' => $result,
            'associativePosts' => $associativePosts,
            'redirects' => $redirects,
        ];

        wp_send_json($response);
    }

    private function getRedirectList() {
        global $SEOAIC_OPTIONS;
        $redirects = !empty($SEOAIC_OPTIONS['redirect']) ? $SEOAIC_OPTIONS['redirect'] : [];
        $links = [];

        foreach ($redirects as $status => $urls) {
            foreach (array_keys($urls) as $url) {
                if (substr($url, -1) !== '/') {
                    $url .= '/';
                }
                $links[] = $url;
            }
        }

        return $links;
    }

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

        $checkIntegratedSiteWithGoogle = $this->isSiteIntegratedWithGoogle();

        $params = $this->getPostArgs();

        $params['dates'] = [
            $params['dateFrom'],
            $params['dateTo']
        ];

		$result = $this->seoaic->curl->init('api/pruning/google/comparison', $params, true, true, true);

        $postsRepository = new PostRepository();
        $associativePosts = $postsRepository->get_associative_posts_array('post_name', ['post_title', 'ID', 'post_modified']);

        $response = [
            'result' => $result,
            'associativePosts' => $associativePosts
        ];

        wp_send_json($response);
    }


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

        $this->isSiteIntegratedWithGoogle();

        $params = $this->getPostArgs();

        $params['dates'] = [
            $params['dateFrom'],
            $params['dateTo']
        ];

		$result = $this->seoaic->curl->init('api/pruning/google/keywords-comparison', $params, true, true, true);

        $postsRepository = new PostRepository();
        $associativePosts = $postsRepository->get_associative_posts_array('post_name', ['post_title']);

        $response = [
            'result' => $result,
            'associativePosts' => $associativePosts
        ];

        wp_send_json($response);
    }

    public function isSiteIntegratedWithGoogle() {
        global $SEOAIC_OPTIONS;

        $popupOptionExists = array_key_exists('googleIntegrationPopup', $SEOAIC_OPTIONS);

        if (!$popupOptionExists) {
            SEOAICAjaxResponse::success()->addFields(['integrationGSCModal' => true])->wpSend();
        }

        $popupOption = $popupOptionExists ? $SEOAIC_OPTIONS['googleIntegrationPopup'] : null;
        $integrationMethod = $SEOAIC_OPTIONS['seoaicGscIntegrationMethod'] ?? 'META';
        $isIntegrated = $this->checkIntegratedSiteWithGoogle();

        if (!$isIntegrated && !$popupOptionExists) {
            SEOAICAjaxResponse::success()
                ->addFields(['integrationGSCModal' => true])
                ->wpSend();
        }

        if ($integrationMethod !== 'META' && !$isIntegrated) {
            $currentSiteUrl = !empty($SEOAIC_OPTIONS['seoaic_gsc_url']) ? esc_url($SEOAIC_OPTIONS['seoaic_gsc_url']) : get_home_url();

            $data = [
                'url' => trailingslashit($currentSiteUrl),
                'verificationMethod' => $integrationMethod,
            ];

            $messageHTML = '<blockquote>' . esc_html__('If you have already added the DNS record and a few days have passed, please contact support for assistance.', 'seoaic') . '</blockquote>';

            $result = $this->seoaic->curl->init('api/pruning/google/add-site', $data, true, true, true);

            SEOAICAjaxResponse::success()
                    ->addFields([$integrationMethod => $result, 'messageHTML' => $messageHTML])
                    ->wpSend();
        }

        if (
            !$popupOptionExists ||
            (!$isIntegrated && $popupOption !== false)
        ) {
            SEOAICAjaxResponse::success()->addFields(['integrationGSCModal' => true])->wpSend();
        }

        return true;
    }

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

        $isIntegrated = $this->verifySite();

        if ($isIntegrated) {
            SEOAICAjaxResponse::reload()->wpSend();
        }

        SEOAICAjaxResponse::alert(esc_html__('Failed to verify integration', 'seoaic'))->wpSend();
    }

    /**
     * Detects and records internal links to a post that is being deleted.
     *
     * @param string $deleted_post_url The URL of the post being deleted.
     */
    function detectBrokenInternalLinksOnDelete($deleted_post_url) {
        global $wpdb;

        $query = $wpdb->prepare(
            "SELECT ID FROM {$wpdb->posts} WHERE post_type != 'revision' AND post_status = 'publish' AND post_content LIKE %s",
            '%' . $wpdb->esc_like($deleted_post_url) . '%'
        );

        $affected_posts = $wpdb->get_col($query);

        $detected_posts = [];

        if (!empty($affected_posts)) {
            foreach ($affected_posts as $affected_post_id) {
                $detected_posts[] = [
                    'post_id'       => $affected_post_id,
                    'post_title'    => get_the_title($affected_post_id),
                    'post_link'     => get_permalink($affected_post_id),
                    'deleted_url'   => $deleted_post_url,
                ];
            }
        }

        return $detected_posts;
    }

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

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

        if (empty($ids)) {
            SEOAICAjaxResponse::alert('No IDs provided.')->wpSend();
        }

        $links = $this->getLinksFromContentByPostId($ids);
        $tableHtml = $this->generateReplacementTable($links);

        SEOAICAjaxResponse::success(['html' => $tableHtml])->wpSend();
    }

    private function getLinksFromContentByPostId($ids) {
        global $wpdb;

        $placeholders = implode(',', array_fill(0, count($ids), '%d'));
        $query = $wpdb->prepare(
            "SELECT ID, post_content FROM {$wpdb->posts} WHERE ID IN ($placeholders)",
            ...$ids
        );

        $results = $wpdb->get_results($query);
        $all_links = [];

        foreach ($results as $row) {
            $post_id = $row->ID;
            $content = $row->post_content;

            preg_match_all('#<a[^>]+href=["\']([^"\']+)["\']#i', $content, $matches);

            $all_links = array_merge($all_links, $matches[1]);
        }

        return $all_links;
    }

    private function generateReplacementTable($links) {
	    if ( empty( $links ) ) {
		    return '<p>No links found in posts</p>';
	    }

	    $html = '<div class="deleted-posts-container">';
	    $html .= '<table class="deleted-posts-table" border="1" cellspacing="0" cellpadding="5">';
	    $html .= '<thead>';
	    $html .= '<tr>';
	    $html .= '<th class="replacement-link"><span>Replacement Link</span></th>';
	    $html .= '<th class="suggested-link"><span>Suggested Replacement</span></th>';
	    $html .= '</tr>';
	    $html .= '</thead>';
	    $html .= '<tbody>';

	    foreach ( $links as $link ) {
		    $deletedLink = esc_url( $link );

		    $html .= '<tr>';
		    $html .= '<td class="replacement-link"><a href="' . $deletedLink . '" target="_blank" class="broken-page" title="' . $deletedLink . '">' . $deletedLink . '</a></td>';
		    $html .= '<td class="suggested-link">';
		    $html .= '<select name="page_link" class="seoaic-keyword-page-link seoaic-form-item form-select"></select>';
		    $html .= '</td>';
		    $html .= '</tr>';
	    }

	    $html .= '</tbody>';
	    $html .= '</table>';
	    $html .= '</div>';

	    return $html;
    }

    /**
     * Handles the AJAX request to improve a single tag of a post.
     *
     * @return void
     */
    public function improveAutoImprovementSingleTagAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $_post = wp_unslash($_POST);
        $data = [];
        $postId = !empty($_post['postId']) ? intval($_post['postId']) : 0;
        $tags = !empty($_post['tags']) ? trim($_post['tags']) : '';
        $prompt = !empty($_post['prompt']) ? trim($_post['prompt']) : '';
        $goal = !empty($_post['goal']) ? trim($_post['goal']) : null;

        if (!$postId || !$tags) {
            SEOAICAjaxResponse::alert(__('Missing post ID or tag', 'seoaic'))->wpSend();
        }

        $data = [
            'postId' => $postId,
            'data' => [
                [
                    'content' => $tags,
                    'goal' => $goal,
                    'prompt' => $prompt,
                ]
            ],
        ];

        $instance = new ContentImprovementAutoImprovement($this->seoaic);
        $additionalData = $instance->getContentImprovementMainData($postId);
        $data = array_merge($data, $additionalData);

        $result = $instance->sendSingleTagRequest($data);

        if (empty($result)) {
            SEOAICAjaxResponse::error(__('No improvement for the tag', 'seoaic'))->wpSend();
        }

        SEOAICAjaxResponse::success()->addFields([
            'result' => $result,
        ])->wpSend();
    }

    /**
     * Handles the AJAX request to replace a content block.
     *
     * @return void
     */
    public function replaceContentBlockAjax()
    {
        $instance = new ContentImprovementAutoImprovement($this->seoaic);
        $result = $instance->replaceContentBlock();

        SEOAICAjaxResponse::success()->addFields($result)->wpSend();
    }



    /**
     * Handles the AJAX request to run automated content improvement.
     *
     * @return void
     */
    public function automatedImprovementRunAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $_post = wp_unslash($_POST); // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.NonceVerification.Missing
        $postId = !empty($_post['postId']) ? intval($_post['postId']) : 0;
        $shouldResetCache = filter_var($_post['shouldResetCache'], FILTER_VALIDATE_BOOLEAN);

        if (!$postId) {
            SEOAICAjaxResponse::alert(__('Invalid post ID', 'seoaic'))->wpSend();
        }

        $instance = new ContentImprovementAutoImprovement($this->seoaic);
        $transient_key = $instance::AUTO_IMPROVE_POST_CACHE . $postId;

        if ($shouldResetCache) {
            delete_transient($transient_key);
        }

        $cached = get_transient($transient_key);

        if ($cached !== false) {
            $result = $cached;

            SEOAICAjaxResponse::success()->addFields([
                'result' => $result,
            ])->wpSend();
        } else {
            $this->postsMassActionRun($instance);
        }

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

    /**
     * Handles the AJAX request to check the status of automated content improvement.
     *
     * @return void
     */
    public function automatedImprovementCheckStatusAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);
        $instance = new ContentImprovementAutoImprovement($this->seoaic);
        $this->postsMassActionCheckStatus($instance);
    }

    function automatedImprovementStopPollingAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);
        $instance = new ContentImprovementSuggestionsGenerate($this->seoaic);
        $this->postsMassActionStop($instance, false);

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

    function republishPostAjax()
    {
        check_ajax_referer(SeoaicAjaxValidation::ACTION_STRING);

        $_post = wp_unslash($_POST);
        $postId = !empty($_post['postId']) ? intval($_post['postId']) : 0;

        if (!$postId) {
            SEOAICAjaxResponse::alert(esc_html__('Invalid post ID', 'seoaic'))->wpSend();
        }

        $post = get_post($postId);
        if (!$post) {
            SEOAICAjaxResponse::alert(esc_html__('Post not found', 'seoaic'))->wpSend();
        }

        $updated = wp_update_post([
            'ID' => $postId,
            'post_date' => current_time('mysql'),
            'post_date_gmt' => current_time('mysql', 1),
        ], true);

        if ($updated) {
            SEOAICAjaxResponse::alert(esc_html__('Post republished successfully', 'seoaic'))->wpSend();
        } else {
            SEOAICAjaxResponse::alert(esc_html__('Failed to republish post', 'seoaic'))->wpSend();
        }
    }
}