<?php

use SEOAIC\loaders\PostsGenerationLoader;
use SEOAIC\posts_mass_actions\PostsMassTranslate;
use SEOAIC\SEOAICAjaxResponse;

class SEOAIC_MULTILANG
{
    const TRANSIENT_LOCATIONS_FIELD = 'seoaic_locations';
    const TRANSIENT_LAST_LOCATION_FIELD = 'seoaic_last_location';
    const TRANSIENT_LANGUAGES_LOCATIONS_FIELD = 'seoaic_languages_locations';
    private $seoaic;

    function __construct($_seoaic)
    {
        $this->seoaic = $_seoaic;

        //add_action('init', [$this, 'ml_class_init']);

        add_action('wp_ajax_seoaic_get_locations', [$this, 'getLocationsAjax']);
        add_action('wp_ajax_seoaic_get_location_languages', [$this, 'getLocationLanguagesAjax']);
        add_action('wp_ajax_seoaic_get_language_locations', [$this, 'getLanguageLocationsAjax']);
    }

    /**
     * Init Multilanguage class init
     */
    // function ml_class_init () {
    //     $post_types = seoaic_get_post_types();

    //     foreach ( $post_types as $post_type ) {
    //         add_action('bulk_actions-edit-' . $post_type, [$this, 'add_bulk_action_translate']);
    //         add_action('handle_bulk_actions-edit-' . $post_type, [$this, 'handle_bulk_action_translate'], 20, 3);
    //     }
    //     //add_action('restrict_manage_posts', [$this, 'admin_filter_languages']);
    // }

    /**
     * Show languages in post table page
     */
    function admin_filter_languages () {
        //$this->get_multilang_checkboxes();
    }

    /**
     * Add bulk action
     * @param $bulk_actions array
     * @return array
     */
    function add_bulk_action_translate ( $bulk_actions ) {
        $bulk_actions['seoaic_translate'] = 'Translate';

        $this->get_multilang_checkboxes();

        return $bulk_actions;
    }

    /**
     * Handle bulk action
     * @param $redirect_url string
     * @param $action string
     * @param $post_ids array
     */
    // function handle_bulk_action_translate ( $redirect_url, $action, $post_ids ) {
    //     if ( $action === 'seoaic_translate' && !empty($_REQUEST['seoaic_multilanguages']) ) {

    //         $posts_to_translate = [];

    //         foreach ( $post_ids as $post_id ) {
    //             $languages_to_translate = $_REQUEST['seoaic_multilanguages'];
    //             $post_language = $this->get_post_language($post_id, 'locale');
    //             $post_type = get_post_type($post_id);

    //             if ( empty($post_language) ) {
    //                 $args = [
    //                     'language'  => $this->get_default_language(),
    //                     'post_type' => $post_type,
    //                     'parent_id' => 0,
    //                     'multi'     => false,
    //                 ];
    //                 $this->add_new_idea_manually($post_id, $args);
    //                 $post_language = $this->get_post_language($post_id, 'locale');
    //             }

    //             $post_translations = $this->get_post_translations($post_id);

    //             $post_translated_ideas = [];
    //             if ( empty($post_translations) ) {
    //                 $post_translations = [$this->get_post_language($post_id, 'code') => $post_id];
    //             }

    //             foreach ( $post_translations as $post_translation_locale => $post_translation_id ) {

    //                 if ( $post_translation_id == $post_id ) {
    //                     if ( ($key = array_search($post_language, $languages_to_translate)) !== false )
    //                         unset($languages_to_translate[$key]);
    //                     continue;
    //                 }

    //                 $post_translation_type = get_post_type($post_translation_id);
    //                 if ( $post_translation_type !== 'seoaic-post' ) {
    //                     if ( ($key = array_search($this->get_post_language($post_translation_id, 'locale'), $languages_to_translate)) !== false )
    //                         unset($languages_to_translate[$key]);
    //                     continue;
    //                 }

    //                 $post_translated_ideas[$post_translation_locale] = $post_translation_id;

    //                 if ( ($key = array_search($this->get_post_language($post_translation_id, 'locale'), $languages_to_translate)) !== false )
    //                     unset($languages_to_translate[$key]);
    //             }

    //             if ( empty($languages_to_translate) && empty($post_translated_ideas) ) {
    //                 continue;
    //             }

    //             $idea_content = get_post_meta($post_id, 'seoaic_idea_content', true);

    //             $title = get_the_title($post_id);
    //             foreach ( $languages_to_translate as $language_locale ) {
    //                 $language = $this->get_language_by($language_locale, 'locale');
    //                 $args = [
    //                     'name'      => $title . ' (' . $language['name'] . ')',
    //                     'language'  => $language['name'],
    //                     'parent_id' => $post_id,
    //                     'return'    => true,
    //                 ];
    //                 $idea_id = $this->seoaic->ideas->add_idea($args);

    //                 $post_translated_ideas[$language['code']] = $idea_id;
    //             }

    //             $posts_to_translate[$post_id] = [
    //                 'thumbnail' => get_post_thumbnail_id($post_id),
    //                 'idea_content' => $idea_content,
    //                 'post_type' => $post_type,
    //                 'translate' => $post_translated_ideas,
    //             ];
    //         }

    //         $ideas_array = [];
    //         $post_type = '';

    //         foreach ( $posts_to_translate as $post_id => $post ) {
    //             $post_type = $post['post_type'];

    //             foreach ( $post['translate'] as $idea_language => $idea_id ) {
    //                 $ideas_array[] = $idea_id;

    //                 update_post_meta($idea_id, 'seoaic_idea_content', $post['idea_content']);
    //                 update_post_meta($idea_id, 'seoaic_ml_original_post', $post_id);

    //                 if (!empty($post['thumbnail'])) {
    //                     set_post_thumbnail($idea_id, $post['thumbnail']);
    //                 }
    //             }
    //         }

    //         $data = [
    //             'domain' => $_SERVER['HTTP_HOST'],
    //             'idea_id' => $ideas_array,
    //             'posting_date' => NULL,
    //             'manual_mass_thumb' => 0,
    //             'type' => $post_type,
    //         ];

    //         $prev_option = PostsGenerationLoader::getPostsOption();

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

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

    //         PostsGenerationLoader::setPostsOption($option);

    //         // TODO: change to new endpoints
    //         // api/ai/posts/translate
    //         $result = $this->seoaic->curl->init('api/schedule', $data, true, false, true);

    //         return $redirect_url;
    //     }
    // }


    /**
     * WordPress is multilingual
     *
     * @return boolean|string
     */
    public function is_multilang () {

        if ( $this->_is_polylang_active() ) {
            return 'polylang';
        }

        if ( $this->_is_wpml_active() ) {
            return 'wpml';
        }

        return false;
    }

    /**
     * Check if Polylang is active
     * @return boolean
     */
    private function _is_polylang_active() {
        return function_exists('pll_the_languages') && function_exists('pll_count_posts');
    }

    /**
     * Check if WPML SitePress is active
     * @return boolean
     */
    private function _is_wpml_active() {
        return class_exists('SitePress');
    }

    /**
     * Get WordPress default language
     * @return false|string
     */
    public function get_default_language ( $key = 'name' ) {

        switch ( $this->is_multilang() ) {
            case 'polylang':
                if ( $key === 'code' ) {
                    return pll_default_language();
                }
                return pll_default_language( $key );
                break;
            case 'wpml':
                $language = apply_filters('wpml_default_language', NULL );
                if ( $key === 'code' ) {
                    return $language;
                }
                $language = $this->get_language_by($language, 'code');
                if ( !empty($language[$key]) ) {
                    return $language[$key];
                }
                break;
        }

        return false;
    }

    /**
     * Get all WordPress active languages
     * @return array
     */
    public function get_multilanguages () {
        $langs = [];

        switch ( $this->is_multilang() ) {
            case 'polylang':
                foreach ( pll_languages_list(['fields' => []]) as $_lang ) {
                    $langs[] = [
                        'code' => $_lang->slug,
                        'name' => $_lang->name,
                        'locale' => $_lang->locale,
                        'flag' => $_lang->flag_url,
                    ];
                }
                break;
            case 'wpml':
                foreach ( apply_filters( 'wpml_active_languages', NULL ) as $_lang ) {
                    $langs[] = [
                        'code' => $_lang['language_code'],
                        'name' => $_lang['translated_name'],
                        'locale' => $_lang['default_locale'],
                        'flag' => $_lang['country_flag_url'],
                    ];
                }
                break;
        }

        return $langs;
    }

    /**
     * Get post language
     * @param int $post_id
     * @param string $key Optional. The value we want to retriene. The "name" field by default.
     * @return false|string
     */
    public function get_post_language ( $post_id, $key = 'name' ) {

        if ( empty($post_id) ) return false;

        global $SEOAIC_OPTIONS;
        // $language = !empty($SEOAIC_OPTIONS['seoaic_language']) ? $SEOAIC_OPTIONS['seoaic_language'] : 'English';
        $language = false;

        switch ( $this->is_multilang() ) {
            case 'polylang':
                switch ( $key ) {
                    case 'code': $key = 'slug'; break;
                }
                $pllLanguage = pll_get_post_language( $post_id, $key );
                if ($pllLanguage) {
                    $language = $pllLanguage;
                }
                break;
            case 'wpml':
                $wpmlLanguage = apply_filters( 'wpml_post_language_details', NULL, $post_id );
                switch ( $key ) {
                    case 'name': $key = 'display_name'; break;
                    case 'code': $key = 'language_code'; break;
                    //case 'locale': $key = 'default_locale'; break;
                }
                if ($wpmlLanguage) {
                    $language = $wpmlLanguage[$key];
                }
                break;
        }
        if (!$this->is_multilang()) {
            $language = $SEOAIC_OPTIONS['seoaic_language'];
        }
        return $language;
    }

    /**
     * Get language`s image tag
     * @param string $language_in
     * @return string
     */
    public function get_language_flag_img ( $language_in ) {
        $flag = $this->get_language_info($language_in, 'flag');

        if ( !empty($flag) ) {
            return '<img src="' . esc_attr($flag) . '" width="16" height="11" alt="' . esc_attr($language_in) . '">';
        }

        return '';
    }

    /**
     * Get language information as name, code, flag, locale
     * @param string $language_in
     * @param string $key
     * @return false|string
     */
    public function get_language_info ( $language_in, $key = 'name' ) {

        $language = $this->get_language_by($language_in);

        if ( !empty($language) && array_key_exists($key, $language) ) {
            return $language[$key];
        }

        return false;
    }

    /**
     * Get language by name, code, locale
     * @param string $language_in
     * @param string $by
     * @return false|array
     */
    public function get_language_by ( $language_in, $by = 'name' ) {
        foreach ( $this->get_multilanguages() as $_lang ) {
            if ( $language_in === $_lang[$by] ) {
                return $_lang;
            }
        }

        return false;
    }

    /**
     * Get post existing translations
     * @param int $post_id
     * @return false|array
     */
    public function get_post_translations ( $post_id, $post_type = 'post_seoaic-post' ) {
        switch ( $this->is_multilang() ) {
            case 'polylang':
                return pll_get_post_translations($post_id);
                break;
            case 'wpml':
                if ( !apply_filters( 'wpml_element_has_translations', null, $post_id, $post_type ) )
                    return false;

                global $wpdb;

                $sql = "SELECT `trid` FROM `{$wpdb->prefix}icl_translations` WHERE `element_id` = %d AND `element_type` LIKE 'post_%'";
                $prepared_sql = $wpdb->prepare($sql, [
                    $post_id
                ]);
                $trid = $wpdb->get_var($prepared_sql);

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

                $sql = "SELECT `element_id`, `language_code` FROM `{$wpdb->prefix}icl_translations` WHERE `trid` = {$trid} AND `element_type` LIKE 'post_%'";
                $translations = $wpdb->get_results( $sql );

                $translationsArray = [];
                foreach ( $translations as $translation ) {
                    $translationsArray[$translation->language_code] = intval($translation->element_id);
                }

                return $translationsArray;
                break;
        }

        return false;
    }

    /**
     * Sort posts by languages
     * @param array $posts
     * @return array
     */
    public function sort_posts_by_languages ( $posts = [] ) {

        if ( $this->is_multilang() ) {
            $new_order_posts = [];

            foreach ( $posts as $post ) {

                if ( isset($new_order_posts[$post->ID]) ) continue;

                $new_order_posts[$post->ID] = $post;

                $translations = $this->get_post_translations($post->ID);

                if ( empty($translations) )
                    continue;

                foreach ( $translations  as $translation ) {

                    foreach ( $posts as $_post ) {

                        if ( isset($new_order_posts[$_post->ID]) ) continue;

                        if ( $translation === $_post->ID ) {
                            $new_order_posts[$_post->ID] = $_post;
                            break;
                        }
                    }
                }
            }

            return $new_order_posts;
        }

        return $posts;
    }

    /**
     * Get languages as comma separated string for cURL param
     * @return string
     */
    public function filter_request_multilang ()
    {
        $__REQUEST = wp_unslash($_REQUEST); // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.NonceVerification.Missing
        $language = $this->get_selected_language();

        if (
            !$this->is_multilang()
            || empty($__REQUEST['seoaic_multilanguages'])
        ) {
            return $language;
        }

        $languages = $this->get_multilanguages();

        if ( empty($languages) ) {
            return $language;
        }

        $post_languages = [];
        $seoaicMultilanguages = is_string($__REQUEST['seoaic_multilanguages']) ? [$__REQUEST['seoaic_multilanguages']] : $__REQUEST['seoaic_multilanguages'];

        foreach ($languages as $language) {
            if (in_array($language['locale'], $seoaicMultilanguages)) {
                $post_languages[] = $language['name'];
            }
        }

        if ( empty($post_languages) ) {
            return $language;
        }

        return implode(',', $post_languages);
    }

    /**
     * Set post language
     * @param int $post_id
     * @param string $language
     */
    public function set_post_language ( $post_id, $language ) {

        switch ( $this->is_multilang() ) {
            case 'polylang':
                pll_set_post_language($post_id, $language);
                break;
            case 'wpml':

                break;
        }
    }

    /**
     * Set post translations
     * @param array $translations
     */
    public function save_post_translations ( $translations ) {

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

        switch ( $this->is_multilang() ) {
            case 'polylang':
                pll_save_post_translations($translations);
                break;
            case 'wpml':

                break;
        }
    }

    /**
     * Get WordPress active language
     * @return false|string
     */
    public function get_current_language($field = 'name')
    {
        switch ( $this->is_multilang() ) {
            case 'polylang':
                $current = pll_current_language();
                $language = $this->get_language_by($current, 'code');
                if (
                    'code' == $field
                    && !empty($language['code'])
                ) {
                    return $language['code'];
                }

                if ( !empty($language['name']) ) {
                    return $language['name'];
                }
                break;
            case 'wpml':
                $current = apply_filters( 'wpml_current_language', null );
                $language = $this->get_language_by($current, 'code');
                if (
                    'code' == $field
                    && !empty($language['code'])
                ) {
                    return $language['code'];
                }

                if ( !empty($language['name']) ) {
                    return $language['name'];
                }
                break;
        }

        return false;
    }

    /**
     * Update post args for get_posts
     * @param array $args
     * @return array $args
     */
    public function update_post_args ( $args ) {

        switch ( $this->is_multilang() ) {
            case 'polylang':
                $current = pll_current_language();
                if ( !empty($current) ) {
                    $args['lang'] = $current;
                }
                break;
            case 'wpml':

                break;
        }

        return $args;
    }

    /**
     * Get terms in WordPress default language
     * @return array $terms
     */
    public function get_terms ( $post_type = 'post' ) {

        $taxonomies = get_object_taxonomies(['post_type' => $post_type]);

        $args = [
            'hide_empty' => false,
            'taxonomy' => $taxonomies,
        ];

        $terms = false;

        switch ( $this->is_multilang() ) {
            case 'polylang':
                $args['lang'] = $this->get_default_language('code');
                $terms = get_terms($args);

                $new_terms = [];
                $default_language = $this->get_default_language('code');
                foreach ( $terms as $term ) {
                    if ( $term->taxonomy === 'language' ) continue;
                    if ( $term->taxonomy === 'post_translations' ) continue;

                    $term_language = pll_get_term_language( $term->term_id );
                    if ( false === $term_language || $term_language === $default_language ) {
                        $new_terms[] = $term;
                    }
                }
                $terms = $new_terms;
                break;
            case 'wpml':
                $default_language = $this->get_default_language('code');

                $terms = get_terms($args);

                $new_terms = [];
                foreach ( $terms as $term ) {
                    if ( $term->taxonomy === 'translation_priority' ) continue;

                    $term_info = apply_filters( 'wpml_element_language_details', null, ['element_id' => $term->term_id, 'element_type' => 'category'] );

                    if ( !empty($term_info->language_code) && $term_info->language_code === $default_language ) {
                        $new_terms[] = $term;
                    }
                }
                $terms = $new_terms;
                break;
            default:
                $terms = get_terms($args);
        }

        return $terms;
    }

    /**
     * Get term translation
     * @param int $term_id
     * @param string $language 2-letters code of the language (Polylang)
     * @return array $terms
     */
    public function get_term_translation($term_id, $language = false)
    {
        $term_id = intval($term_id);

        if ( empty($language) ) {
            return $term_id;
        }

        switch ( $this->is_multilang() ) {
            case 'polylang':
                $term_id = pll_get_term($term_id, $language);
                break;
            case 'wpml':
                return apply_filters( 'wpml_object_id', $term_id, 'category', false, $language );
                break;
        }

        return $term_id;
    }

    /**
     * Get term language
     * @param int $term_id
     * @return string $term_language
     */
    public function get_term_language( $term_id ) {
        $term_id = intval( $term_id );

        switch ( $this->is_multilang() ) {
            case 'polylang':
                $term_language = wp_get_object_terms( $term_id, 'term_language', [ 'fields' => 'names' ] );
                if ( ! is_wp_error( $term_language ) && ! empty( $term_language ) ) {
                    $term_language = is_array( $term_language ) ? $term_language[0] : $term_language;
                }
                break;

            case 'wpml':
                $term_language = get_term_meta( $term_id, 'language', true );
                break;

            default:
                $term_language = '';
                break;
        }

        return sanitize_text_field( $term_language );
    }

    /**
     * Construct buttons to control translations
     * @param int $post_id
     * @param array $posts
     * @return string
     */
    public function get_language_translations_control ( $post_id, $posts ) {
        if ( !$this->is_multilang() ) return '';

        $post_language = $this->get_post_language($post_id);
        $current_flag_safe = $this->get_language_flag_img($post_language);
        $translations = $this->get_post_translations($post_id);

        $languages = $this->get_multilanguages();

        if ( empty($post_language) ) return '';

        ?>
        <div class="seoic-translations-buttons">

            <span title="<?php esc_html_e('Current language', 'seoaic');?> (<?php echo esc_html($post_language);?>)"><?php echo $current_flag_safe?></span>

            <?php foreach ( $languages as $language ) : ?>
                <?php
                    if ( $post_language === $language['name'] ) continue;

                    $translation_flag_safe = $this->get_language_flag_img($language['name']);

                    if ( !empty($translations[$language['code']]) ) :
                        if ( isset($posts[$translations[$language['code']]]) ) :

                ?>
                        <button type="button" title="Edit <?php echo esc_attr($language['name']);?> translation"
                                class="seoaic-link-translation seoaic-button-link"
                                data-target="#edit-idea-button-<?php echo esc_attr($translations[$language['code']]);?>"
                        ><?php echo $translation_flag_safe;?></button>

                    <?php else : ?>
                        <a class="generated-post-link" target="_blank" title="<?php esc_html_e('This translation is already generated', 'seoaic');?>" href="<?php echo esc_attr(get_edit_post_link($translations[$language['code']]));?>"><?php echo $translation_flag_safe;?></a>
                    <?php endif; ?>
                <?php else : ?>

                    <button type="button" title="<?php esc_html_e('Add ' . esc_attr($language['name']) . ' translation', 'seoaic');?>"
                            class="seoaic-add-translation modal-button"
                            data-title="<?php esc_html_e('Add ' . esc_attr($language['name']) . ' translation', 'seoaic');?>"
                            data-modal="#add-idea-translation"
                            data-mode="add"
                            data-single="yes"
                            data-form-callback="window_reload"
                            data-language-parent-id="<?php echo esc_attr($post_id);?>"
                            data-languages="false"
                            data-language="<?php echo esc_attr($language['name']);?>"
                            data-language-code-for-locations="<?php echo esc_attr($language['code']);?>"
                    >
                        <?php
                            if (!empty($translation_flag_safe)) {
                                echo $translation_flag_safe;
                            } else {
                                echo esc_html(strtoupper($language['code']));
                            }
                        ?>

                        <div class="dn edit-form-items">
                            <input type="hidden" name="item_name" value="" data-label="<?php esc_html_e('Name', 'seoaic');?>">
                        </div>
                    </button>

                <?php endif; ?>
            <?php endforeach; ?>

        </div>
        <?php
    }

    /**
     * Construct post's language flag
     * @param int $post_id Post ID
     * @return string
     */
    public function getPostLanguageAndFlag($post_id)
    {
        $return = [
            'language' => '',
            'flag' => '',
        ];

        if (
            !$this->is_multilang()
            || empty($post_id)
            || !is_numeric($post_id)
        ) {
            return $return;
        }

        $post_language = $this->get_post_language($post_id);

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

        $return['language'] = $post_language;
        $return['flag'] = $this->get_language_flag_img($post_language);

        return $return;
    }

    public function displayPostLanguageFlag($post_id)
    {
        list('language' => $language, 'flag' => $flag) = $this->getPostLanguageAndFlag($post_id);
        ?>
        <div class="seoaic-post-lang d-flex">
            <span class="flex-align-center" title="<?php esc_html_e('Post language', 'seoaic');?>: <?php echo esc_attr($language);?>"><?php echo $flag;?></span>
        </div>
        <?php
    }

    public function getPostTranslationsLanguageAndFlag($postID): array
    {
        $return = [
            'done' => [],
            'in_progress' => [],
            'failed' => [],
        ];

        if (
            !$this->is_multilang()
            || empty($postID)
            || !is_numeric($postID)
        ) {
            return $return;
        }

        $translations = $this->get_post_translations($postID);
        if (!empty($translations)) {
            foreach ($translations as $code => $translationID) {
                if ($postID == $translationID) {
                    continue;
                }
                $doneLang = $this->get_language_by($code, 'code');
                $return['done'][] = [
                    'language'  => !empty($doneLang['name']) ? $doneLang['name'] : '',
                    'flag'      => !empty($doneLang['name']) ? $this->get_language_flag_img($doneLang['name']) : '',
                    'translation_id' => $translationID,
                ];
            }
        }

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

        if ($massTranslateInstance->isPostTranslating($postID)) {
            $inProgressLang = get_post_meta($postID, $massTranslateInstance->getLanguageField(), true);

            $return['in_progress'][] = [
                'language'  => !empty($inProgressLang['name']) ? $inProgressLang['name'] : '',
                'code'      => !empty($inProgressLang['code']) ? $inProgressLang['code'] : '',
                'flag'      => !empty($inProgressLang['name']) ? $this->get_language_flag_img($inProgressLang['name']) : '',
                'status'    => 'in-progress',
            ];

        } else if ($massTranslateInstance->isPostTranslateFailed($postID)) {
            $inProgressLang = get_post_meta($postID, $massTranslateInstance->getLanguageField(), true);
            $return['failed'][] = [
                'language'  => !empty($inProgressLang['name']) ? $inProgressLang['name'] : '',
                'flag'      => !empty($inProgressLang['name']) ? $this->get_language_flag_img($inProgressLang['name']) : ''
            ];
        }

        return $return;
    }

    public function displayPostTranslationsFlags($post_id)
    {
        list(
            'done' => $done,
            'in_progress' => $inProgress,
            'failed' => $failed
        ) = $this->getPostTranslationsLanguageAndFlag($post_id);

        if (
            !empty($done)
            || !empty($inProgress)
        ) {
            ?>
            <div class="langs-separator"></div>
            <div class="seoaic-post-translations d-flex">
                <?php
                if (
                    !empty($done)
                    && is_array($done)
                ) {
                    foreach ($done as $translation) {
                        $link = get_edit_post_link($translation['translation_id']);
                        ?>
                        <a
                            title="<?php esc_html_e('Post translation', 'seoaic');?>: <?php echo esc_attr($translation['language']);?>"
                            href="<?php echo esc_attr($link);?>"
                            target="_blank"
                            class="flex-align-center"
                        ><?php echo $translation['flag'];?></a>
                        <?php
                    }
                }

                if (!empty($inProgress)) {
                    ?>
                    <a
                        title="<?php esc_html_e('Post translation', 'seoaic');?>: <?php echo esc_attr($inProgress[0]['language']);?>"
                        class="translating flex-align-center language-<?php echo esc_attr($inProgress[0]['language']);?>"
                        href="#"
                        target="_blank"
                    ><?php echo $inProgress[0]['flag'];?></a>
                    <?php

                } else if (!empty($failed)) {
                    ?>
                    <span class="seoaic-translation-failed dashicons dashicons-warning" title="<?php esc_html_e('Post translation failed', 'seoaic');?>: <?php echo esc_attr($failed[0]['language']);?>"></span>
                    <?php
                }
                ?>
            </div>
            <?php
        }
    }

    /**
     * Construct input for translation parent post
     * @return string
     */
    public function get_translation_parent_input () {
        if ( !$this->is_multilang() ) return '';

        ?>
        <input type="hidden" class="seoaic-form-item seoaic-multilanguage-parent-id" name="seoaic-multilanguage-parent-id" value="">
        <?php
    }

    /**
     * Construct select with active languages
     */
    public function get_languages_select($fix_selected_language = '', $disabled = false) {
        if ($this->is_multilang()) {
            $languages = $this->get_multilanguages();
            $select_language = $this->get_current_language();

            if (empty($select_language)) {
                $select_language = $this->get_default_language();
            }

            if (!empty($fix_selected_language)) {
                $select_language = $fix_selected_language;
            }

            ?>
            <select class="seoaic-form-item form-select seoaic-language" name="seoaic_ml_language" required="" <?php echo $disabled ? 'disabled' : ''?>>
                <?php foreach ($languages as $language) : ?>
                    <option <?php echo ($select_language === $language['name']) ? 'selected' : '' ?> value="<?php echo esc_attr($language['name']);?>">
                        <?php echo esc_html($language['name']);?>
                    </option>
                <?php endforeach; ?>
            </select>
            <?php
        }
    }


    /**
     * Construct checkboxes with active languages
     * @param string $label
     * @param string $type 'checkbox' or 'radio'
     * @param bool $preselectDefault whether to select item from settings or not
     */
    public function get_multilang_checkboxes($label = 'Languages to generate', $type = 'checkbox', $preselectDefault = true)
    {
        global $SEOAIC_OPTIONS;

        if (
            $this->is_multilang()
            && seoaicIsUserLoggedIn()
        ) : ?>
            <div class="col-12 multilang-box">
                <label for="seoaic_server">
                    <?php esc_html_e($label, 'seoaic');?>
                    <span class="language-label-description
                        <?php
                        if (
                            isset($SEOAIC_OPTIONS['seoaic_multilanguages'])
                            && count($SEOAIC_OPTIONS['seoaic_multilanguages']) > 0
                        ){
                            ?>
                            language-label-description-hidden
                            <?php
                        }
                        ?>
                        "><?php esc_html_e('Will be used default language', 'seoaic');?> (<?php echo esc_html($this->get_selected_language());?>)</span>
                </label>
                <div class="toggle-choose-role">
                    <div class="checkbox-list">
                        <?php
                        $counter = rand(0, 10000000);

                        foreach ( $this->get_multilanguages() as $lang ) :
                            $locations = $this->getLanguageLocations($lang);
                            ?>
                            <div class="wrapper d-flex">
                                <div class="checkbox-wrapper-mc">
                                    <?php
                                    if (('checkbox' == $type)) {
                                        ?>
                                        <input id="seoaic_multilang-<?php echo esc_attr($counter); ?>-<?php echo esc_attr($lang['locale']);?>"
                                            class="seoaic-form-item seoaic_multilang-input"
                                            name="seoaic_multilanguages[]"
                                            type="checkbox"
                                            value="<?php echo esc_attr($lang['locale']);?>"
                                            <?php
                                                if (
                                                    $preselectDefault
                                                    && isset($SEOAIC_OPTIONS['seoaic_multilanguages'])
                                                    && in_array($lang['locale'], $SEOAIC_OPTIONS['seoaic_multilanguages'])
                                                ) {
                                                    echo ' checked ';
                                                }
                                            ?>
                                        />
                                        <?php
                                    } else if ('radio' == $type) {
                                        ?>
                                        <input id="seoaic_multilang-<?php echo esc_attr($counter); ?>-<?php echo esc_attr($lang['locale']);?>"
                                            class="seoaic-form-item seoaic_multilang-input"
                                            name="seoaic_multilanguages"
                                            type="radio"
                                            value="<?php echo esc_attr($lang['locale']);?>"
                                            <?php
                                                if (
                                                    $preselectDefault
                                                    && isset($SEOAIC_OPTIONS['seoaic_multilanguages'])
                                                    && in_array($lang['locale'], $SEOAIC_OPTIONS['seoaic_multilanguages'])
                                                ) {
                                                    echo ' checked ';
                                                }
                                            ?>
                                        />
                                        <?php
                                    }
                                    ?>

                                    <label for="seoaic_multilang-<?php echo esc_attr($counter++); ?>-<?php echo esc_attr($lang['locale']);?>" class="check">
                                        <svg width="18px" height="18px" viewBox="0 0 18 18">
                                            <path d="M1,9 L1,3.5 C1,2 2,1 3.5,1 L14.5,1 C16,1 17,2 17,3.5 L17,14.5 C17,16 16,17 14.5,17 L3.5,17 C2,17 1,16 1,14.5 L1,9 Z"></path>
                                            <polyline points="1 9 7 14 15 4"></polyline>
                                        </svg>
                                        <span>
                                            <?php if ( !empty($lang['flag']) ) : ?>
                                                <img src="<?php echo esc_attr($lang['flag']);?>" width="16" height="11" title="<?php echo esc_attr($lang['name']);?>" alt="<?php echo esc_attr($lang['name']);?>">
                                            <?php endif; ?>
                                        <?php echo esc_html($lang['name']) . ' (' . esc_html($lang['locale']) . ')';?>
                                        </span>
                                    </label>
                                </div>
                                <div class="location-wrapper-mc">
                                    <?php if (!empty($locations)) : ?>
                                        <select name="seoaic_language_locations-<?php echo esc_attr($lang['code']);?>" class="seoaic-language-locations seoaic-form-item">
                                            <?php foreach ($locations as $location) {
                                                $selected = !empty($SEOAIC_OPTIONS['language_locations']) && $SEOAIC_OPTIONS['language_locations'][$lang['code']] == $location['code'] ? 'selected' : '';
                                                echo '<option value="' . esc_attr($location['code']) . '" data-lang="' . esc_attr($lang['code']) . '" ' . esc_attr($selected) . '>' . esc_html($location['name']) . '</option>';
                                            } ?>
                                        </select>
                                    <?php else : ?>
                                        <p><?php echo sprintf(esc_html__('Unable to select a location for this language code (%s).', 'seoaic'), esc_html($lang['code'])); ?></p>
                                    <?php endif; ?>
                                </div>
                            </div>
                        <?php endforeach; ?>
                    </div>
                </div>
            </div>
        <?php
        endif;
    }

    /**
     * Get selected language
     */
    public function get_selected_language()
    {
        if ( $this->is_multilang() ) {
            $selected_language = $this->get_current_language();

            if ( empty($selected_language) ) {
                $selected_language = $this->get_default_language();
            }
        } else {
            global $SEOAIC_OPTIONS;
            $selected_language = !empty($SEOAIC_OPTIONS['seoaic_language']) ? $SEOAIC_OPTIONS['seoaic_language'] : 'English';
        }

        return $selected_language;
    }

    /**
     * Get selected location
     */
    public function get_selected_location($post_id, $lang_code) {
        $selected_location = get_post_meta($post_id, '_idea_language_location_code', true);

        if ( empty($selected_location) ) {
            $selected_location = $this->get_location_by_lang_code($lang_code);
        }

        return $selected_location;
    }

    /**
     * Get location be lang code
     */
    public function get_location_by_lang_code($lang_code = null) {
        global $SEOAIC_OPTIONS;

        if (!empty($SEOAIC_OPTIONS['language_locations']) && !empty($SEOAIC_OPTIONS['language_locations'][$lang_code])) {
            $selected_location = $SEOAIC_OPTIONS['language_locations'][$lang_code];
        }

        return $selected_location;
    }

    public function get_location_code_by_name($name = '') {
        $locations = $this->getLocationsWithLanguages();
        $locationCode = null;

        foreach ($locations as $location) {
            if ($location['name'] === $name) {
                $locationCode = $location['code'];
                break;
            }
        }

        return $locationCode;
    }

    public function get_language_code_by_name($name = '') {
        $locations = $this->getLocationsWithLanguages();
        $languageCode = null;

        foreach ($locations as $location) {
            foreach ($location['languages'] as $language) {
                if ($language['name'] === $name) {
                    $languageCode = $language['code'];
                    break 2;
                }
            }
        }

        return $languageCode;
    }

    public function get_location_iso_by_name(string $countryName = '')  {
        if( empty($countryName) ) {
            return null;
        }

        $locations = $this->getFallbackLocations();

        foreach ($locations as $location) {
            if (
                isset($location['name'], $location['iso']) &&
                mb_strtolower($location['name']) === mb_strtolower($countryName)
            ) {
                return $location['iso'];
            }
        }

        return null;
    }

    /**
     * @param int $post_id
     */
    public function setPostLanguage($post_id, $args, $force = false)
    {
        $multi = $this->is_multilang();

        if (
            $multi
            && !empty($args['language'])
            && (
                empty($this->get_post_language($post_id))
                || $force
            )
        ) {
            switch ($multi) {
                case 'polylang':
                    $language = sanitize_text_field($args['language']);
                    $language_code = $this->seoaic->multilang->get_language_info($language, 'code');
                    $this->seoaic->multilang->set_post_language($post_id, $language_code);
                    $translation = [
                        $language_code => $post_id
                    ];

                    if (!empty($args['parent_id'])) {
                        $parent_id = intval($args['parent_id']);
                        $parent_translations = $this->seoaic->multilang->get_post_translations($parent_id);
                        $translation = array_merge($translation, $parent_translations);
                    }
                    $this->seoaic->multilang->save_post_translations($translation);
                    break;

                case 'wpml':
                    $original_post_language_info =
                        !empty($args['parent_id'])
                        ? apply_filters('wpml_element_language_details', null, [
                            'element_id' => intval($args['parent_id']),
                            'element_type' => 'post_' . get_post_type(intval($args['parent_id']))
                        ])
                        : false;

                    $set_language_args = [
                        'element_id' => $post_id,
                        'element_type' => 'post_' . (!empty($args['post_type']) ? $args['post_type'] : 'post'),
                        'trid' => !empty($original_post_language_info) ? $original_post_language_info->trid : false,
                        'language_code' => $this->seoaic->multilang->get_language_info(sanitize_text_field($args['language']), 'code'),
                        'source_language_code' => !empty($original_post_language_info) ? $original_post_language_info->language_code : NULL,
                    ];

                    do_action('wpml_set_element_language_details', $set_language_args);

                break;
            }
        }
    }

    /**
     * Add new idea manually. Set translation.
     * @param int $post_id
     */
    public function add_new_idea_manually ($post_id, $args, $force = false)
    {
        $multi = $this->is_multilang();

        switch ( $multi ) {
            case 'polylang':
                if (
                    !empty($args['language'])
                    && (
                        false === $this->get_post_language($post_id)
                        || $force
                    )
                ) {
                    $language = sanitize_text_field($args['language']);
                    $language_code = $this->seoaic->multilang->get_language_info($language, 'code');
                    $this->seoaic->multilang->set_post_language($post_id, $language_code);
                    $translation = [
                        $language_code => $post_id
                    ];
                    if ( !empty($args['parent_id']) ) {
                        $parent_id = intval($args['parent_id']);
                        $parent_translations = $this->seoaic->multilang->get_post_translations($parent_id);
                        $translation = array_merge($translation, $parent_translations);
                    }
                    $this->seoaic->multilang->save_post_translations($translation);
                }
                break;
            case 'wpml':
                if (
                    !empty($args['language'])
                    && (
                        empty($this->get_post_language($post_id))
                        || $force
                    )
                ) {
                    $original_post_language_info = !empty($args['parent_id']) ? apply_filters('wpml_element_language_details', null, ['element_id' => intval($args['parent_id']), 'element_type' => 'post_' . get_post_type(intval($args['parent_id']))]) : false;

                    $set_language_args = [
                        'element_id' => $post_id,
                        'element_type' => 'post_' . $args['post_type'],
                        'trid' => !empty($original_post_language_info) ? $original_post_language_info->trid : false,
                        'language_code' => $this->seoaic->multilang->get_language_info(sanitize_text_field($args['language']), 'code'),
                        'source_language_code' => !empty($original_post_language_info) ? $original_post_language_info->language_code : NULL,
                    ];

                    do_action('wpml_set_element_language_details', $set_language_args);
                }
                break;
        }

        if (
            $multi
            && !empty($args['multi'])
            && $args['multi']
        ) {
            $translations = $this->get_post_translations($post_id);

            if ($translations) {
                foreach ($translations as $translation) {
                    $post_type = get_post_type($translation);
                    if ( 'seoaic-post' !== $post_type ) {
                        update_post_meta($translation, 'seoaic_ml_generated_data', []);
                        break;
                    }
                }
            }
        }
    }

    /**
     * Add new idea manually. Set translation.
     * @param array $ideas
     */
    public function add_new_ideas_generation ( array $ideas, $post_type = 'seoaic-post' ) {
        switch ( $this->is_multilang() ) {
            case 'polylang':
                foreach ($ideas as $key => $_idea) {
                    $this->seoaic->multilang->set_post_language($_idea['idea_id'], $_idea['language']['code']);
                }

                foreach ( $ideas as $key => $_idea ) {

                    if ( !$_idea['is_default'] ) continue;

                    $translations = [];

                    foreach ( $ideas as $idea_trans ) {
                        if ( empty($idea_trans['language']) ) continue;

                        if ( $idea_trans['key'] === $_idea['key'] ) {
                            $translations[$idea_trans['language']['code']] = $idea_trans['idea_id'];
                        }
                    }

                    $this->seoaic->multilang->save_post_translations($translations);
                }
                break;
            case 'wpml':
                $defaults = [];
                foreach ($ideas as $key => $_idea) {
                    if ( !$_idea['is_default'] ) continue;

                    $defaults[$_idea['key']] = $_idea['idea_id'];

                    $set_language_args = [
                        'element_id' => $_idea['idea_id'],
                        'element_type' => 'post_' . $post_type,
                        'trid' => false,
                        'language_code' => $_idea['language']['code'],
                        'source_language_code' => NULL,
                    ];

                    do_action('wpml_set_element_language_details', $set_language_args);
                }

                foreach ($ideas as $key => $_idea) {
                    if ( $_idea['is_default'] ) continue;

                    $original_post_language_info = [
                        'element_id' => $defaults[$_idea['key']],
                        'element_type' => 'post_' . $post_type,
                    ];
                    $original_post_language_info = apply_filters('wpml_element_language_details', null, $original_post_language_info);

                    $set_language_args = [
                        'element_id' => $_idea['idea_id'],
                        'element_type' => 'post_' . $post_type,
                        'trid' => !empty($original_post_language_info) ? $original_post_language_info->trid : false,
                        'language_code' => $_idea['language']['code'],
                        'source_language_code' => !empty($original_post_language_info) ? $original_post_language_info->language_code : NULL,
                    ];

                    do_action('wpml_set_element_language_details', $set_language_args);
                }
                break;
        }
    }

    /**
     *Get idea settings if WPML.
     * @param int $id
     * @param string $post_type
     * @return array
     */
    public function get_wpml_idea_settings ( $id, $post_type = 'post' ) {
        if ( $this->is_multilang() !== 'wpml' ) return false;

        global $wpdb;

        $sql = "SELECT `translation_id`, `trid`, `language_code`, `source_language_code`
                FROM `{$wpdb->prefix}icl_translations`
                WHERE `element_id` = %d AND `element_type` LIKE 'post_%'";
        $prepared_sql = $wpdb->prepare($sql, [
            $id
        ]);
        $settings = $wpdb->get_row($prepared_sql);

        if ($settings) {
            $wpdb->update(
                "{$wpdb->prefix}icl_translations",
                ['element_type' => 'post_' . $post_type],
                ['translation_id' => $settings->translation_id]
            );

            $settings->element_type = 'post_' . $post_type;
        }

        return $settings;
    }

    /**
     *Set idea settings if WPML.
     * @param int $id
     * @param array $settings
     */
    public function set_wpml_idea_settings ( $id, $settings ) {
        if ( $this->is_multilang() !== 'wpml' ) return false;

        global $wpdb;

        $sql = "UPDATE `{$wpdb->prefix}icl_translations`
                    SET `trid` = '{$settings->trid}',
                        `language_code` = '{$settings->language_code}',
                        `source_language_code` = '{$settings->source_language_code}'
                    WHERE `element_id` = {$id} AND `element_type` = '{$settings->element_type}'";
        $wpdb->query($sql);
    }

    public function getLocationsWithLanguages()
    {
        $locations = $this->getSavedLocations();

        if (
            empty($locations)
            || !$this->isValidLocations($locations)
        ) {
            $locations = $this->requestLocationsWithLanguages();
            $locations = array_values($locations);

            if ($this->isValidLocations($locations)) {
                usort($locations, function ($a, $b) {
                    return strcmp($a['name'], $b['name']);
                });
                $this->setSavedLocations($locations);

            } else {
                return $this->getFallbackLocations();
            }
        }

        return $locations;
    }

    private function isValidLocations($locations) {
        return !empty($locations)
        && is_array($locations)
        && !empty($locations[0])
        && !empty($locations[0]['name']);
    }

    private function getFallbackLocations() {
        ob_start();
        echo <<<END
[{"name":"Algeria","code":2012,"iso":"DZ","languages":{"French":{"name":"French","code":"fr"},"Arabic":{"name":"Arabic","code":"ar"}}},{"name":"Angola","code":2024,"iso":"AO","languages":{"Portuguese":{"name":"Portuguese","code":"pt"}}},{"name":"Azerbaijan","code":2031,"iso":"AZ","languages":{"Azeri":{"name":"Azeri","code":"az"}}},{"name":"Argentina","code":2032,"iso":"AR","languages":{"Spanish":{"name":"Spanish","code":"es"}}},{"name":"Australia","code":2036,"iso":"AU","languages":{"English":{"name":"English","code":"en"}}},{"name":"Austria","code":2040,"iso":"AT","languages":{"German":{"name":"German","code":"de"}}},{"name":"Bahrain","code":2048,"iso":"BH","languages":{"Arabic":{"name":"Arabic","code":"ar"}}},{"name":"Bangladesh","code":2050,"iso":"BD","languages":{"Bengali":{"name":"Bengali","code":"bn"}}},{"name":"Armenia","code":2051,"iso":"AM","languages":{"Armenian":{"name":"Armenian","code":"hy"}}},{"name":"Belgium","code":2056,"iso":"BE","languages":{"French":{"name":"French","code":"fr"},"Dutch":{"name":"Dutch","code":"nl"},"German":{"name":"German","code":"de"}}},{"name":"Bolivia","code":2068,"iso":"BO","languages":{"Spanish":{"name":"Spanish","code":"es"}}},{"name":"Bosnia and Herzegovina","code":2070,"iso":"BA","languages":{"Bosnian":{"name":"Bosnian","code":"bs"}}},{"name":"Brazil","code":2076,"iso":"BR","languages":{"Portuguese":{"name":"Portuguese","code":"pt"}}},{"name":"Bulgaria","code":2100,"iso":"BG","languages":{"Bulgarian":{"name":"Bulgarian","code":"bg"}}},{"name":"Myanmar (Burma)","code":2104,"iso":"MM","languages":{"English":{"name":"English","code":"en"}}},{"name":"Cambodia","code":2116,"iso":"KH","languages":{"English":{"name":"English","code":"en"}}},{"name":"Cameroon","code":2120,"iso":"CM","languages":{"French":{"name":"French","code":"fr"}}},{"name":"Canada","code":2124,"iso":"CA","languages":{"English":{"name":"English","code":"en"},"French":{"name":"French","code":"fr"}}},{"name":"Sri Lanka","code":2144,"iso":"LK","languages":{"English":{"name":"English","code":"en"}}},{"name":"Chile","code":2152,"iso":"CL","languages":{"Spanish":{"name":"Spanish","code":"es"}}},{"name":"Taiwan","code":2158,"iso":"TW","languages":{"Chinese (Traditional)":{"name":"Chinese (Traditional)","code":"zh-TW"}}},{"name":"Colombia","code":2170,"iso":"CO","languages":{"Spanish":{"name":"Spanish","code":"es"}}},{"name":"Costa Rica","code":2188,"iso":"CR","languages":{"Spanish":{"name":"Spanish","code":"es"}}},{"name":"Croatia","code":2191,"iso":"HR","languages":{"Croatian":{"name":"Croatian","code":"hr"}}},{"name":"Cyprus","code":2196,"iso":"CY","languages":{"Greek":{"name":"Greek","code":"el"},"English":{"name":"English","code":"en"}}},{"name":"Czechia","code":2203,"iso":"CZ","languages":{"Czech":{"name":"Czech","code":"cs"}}},{"name":"Denmark","code":2208,"iso":"DK","languages":{"Danish":{"name":"Danish","code":"da"}}},{"name":"Ecuador","code":2218,"iso":"EC","languages":{"Spanish":{"name":"Spanish","code":"es"}}},{"name":"El Salvador","code":2222,"iso":"SV","languages":{"Spanish":{"name":"Spanish","code":"es"}}},{"name":"Estonia","code":2233,"iso":"EE","languages":{"Estonian":{"name":"Estonian","code":"et"}}},{"name":"Finland","code":2246,"iso":"FI","languages":{"Finnish":{"name":"Finnish","code":"fi"}}},{"name":"France","code":2250,"iso":"FR","languages":{"French":{"name":"French","code":"fr"}}},{"name":"Germany","code":2276,"iso":"DE","languages":{"German":{"name":"German","code":"de"}}},{"name":"Ghana","code":2288,"iso":"GH","languages":{"English":{"name":"English","code":"en"}}},{"name":"Greece","code":2300,"iso":"GR","languages":{"Greek":{"name":"Greek","code":"el"},"English":{"name":"English","code":"en"}}},{"name":"Guatemala","code":2320,"iso":"GT","languages":{"Spanish":{"name":"Spanish","code":"es"}}},{"name":"Hong Kong","code":2344,"iso":"HK","languages":{"English":{"name":"English","code":"en"},"Chinese (Traditional)":{"name":"Chinese (Traditional)","code":"zh-TW"}}},{"name":"Hungary","code":2348,"iso":"HU","languages":{"Hungarian":{"name":"Hungarian","code":"hu"}}},{"name":"India","code":2356,"iso":"IN","languages":{"English":{"name":"English","code":"en"},"Hindi":{"name":"Hindi","code":"hi"}}},{"name":"Indonesia","code":2360,"iso":"ID","languages":{"English":{"name":"English","code":"en"},"Indonesian":{"name":"Indonesian","code":"id"}}},{"name":"Ireland","code":2372,"iso":"IE","languages":{"English":{"name":"English","code":"en"}}},{"name":"Israel","code":2376,"iso":"IL","languages":{"Hebrew":{"name":"Hebrew","code":"he"},"Arabic":{"name":"Arabic","code":"ar"}}},{"name":"Italy","code":2380,"iso":"IT","languages":{"Italian":{"name":"Italian","code":"it"}}},{"name":"Cote d'Ivoire","code":2384,"iso":"CI","languages":{"French":{"name":"French","code":"fr"}}},{"name":"Japan","code":2392,"iso":"JP","languages":{"Japanese":{"name":"Japanese","code":"ja"}}},{"name":"Kazakhstan","code":2398,"iso":"KZ","languages":{"Russian":{"name":"Russian","code":"ru"}}},{"name":"Jordan","code":2400,"iso":"JO","languages":{"Arabic":{"name":"Arabic","code":"ar"}}},{"name":"Kenya","code":2404,"iso":"KE","languages":{"English":{"name":"English","code":"en"}}},{"name":"South Korea","code":2410,"iso":"KR","languages":{"Korean":{"name":"Korean","code":"ko"}}},{"name":"Latvia","code":2428,"iso":"LV","languages":{"Latvian":{"name":"Latvian","code":"lv"}}},{"name":"Lithuania","code":2440,"iso":"LT","languages":{"Lithuanian":{"name":"Lithuanian","code":"lt"}}},{"name":"Malaysia","code":2458,"iso":"MY","languages":{"English":{"name":"English","code":"en"},"Malay":{"name":"Malay","code":"ms"}}},{"name":"Malta","code":2470,"iso":"MT","languages":{"English":{"name":"English","code":"en"}}},{"name":"Mexico","code":2484,"iso":"MX","languages":{"Spanish":{"name":"Spanish","code":"es"}}},{"name":"Moldova","code":2498,"iso":"MD","languages":{"Romanian":{"name":"Romanian","code":"ro"}}},{"name":"Morocco","code":2504,"iso":"MA","languages":{"Arabic":{"name":"Arabic","code":"ar"},"French":{"name":"French","code":"fr"}}},{"name":"Netherlands","code":2528,"iso":"NL","languages":{"Dutch":{"name":"Dutch","code":"nl"}}},{"name":"New Zealand","code":2554,"iso":"NZ","languages":{"English":{"name":"English","code":"en"}}},{"name":"Nicaragua","code":2558,"iso":"NI","languages":{"Spanish":{"name":"Spanish","code":"es"}}},{"name":"Nigeria","code":2566,"iso":"NG","languages":{"English":{"name":"English","code":"en"}}},{"name":"Norway","code":2578,"iso":"NO","languages":{"Norwegian (Bokm\u00e5l)":{"name":"Norwegian (Bokm\u00e5l)","code":"nb"}}},{"name":"Pakistan","code":2586,"iso":"PK","languages":{"English":{"name":"English","code":"en"},"Urdu":{"name":"Urdu","code":"ur"}}},{"name":"Panama","code":2591,"iso":"PA","languages":{"Spanish":{"name":"Spanish","code":"es"}}},{"name":"Paraguay","code":2600,"iso":"PY","languages":{"Spanish":{"name":"Spanish","code":"es"}}},{"name":"Peru","code":2604,"iso":"PE","languages":{"Spanish":{"name":"Spanish","code":"es"}}},{"name":"Philippines","code":2608,"iso":"PH","languages":{"English":{"name":"English","code":"en"},"Tagalog":{"name":"Tagalog","code":"tl"}}},{"name":"Poland","code":2616,"iso":"PL","languages":{"Polish":{"name":"Polish","code":"pl"}}},{"name":"Portugal","code":2620,"iso":"PT","languages":{"Portuguese":{"name":"Portuguese","code":"pt"}}},{"name":"Romania","code":2642,"iso":"RO","languages":{"Romanian":{"name":"Romanian","code":"ro"}}},{"name":"Saudi Arabia","code":2682,"iso":"SA","languages":{"Arabic":{"name":"Arabic","code":"ar"}}},{"name":"Senegal","code":2686,"iso":"SN","languages":{"French":{"name":"French","code":"fr"}}},{"name":"Serbia","code":2688,"iso":"RS","languages":{"Serbian":{"name":"Serbian","code":"sr"}}},{"name":"Singapore","code":2702,"iso":"SG","languages":{"English":{"name":"English","code":"en"},"Chinese (Simplified)":{"name":"Chinese (Simplified)","code":"zh-CN"}}},{"name":"Slovakia","code":2703,"iso":"SK","languages":{"Slovak":{"name":"Slovak","code":"sk"}}},{"name":"Vietnam","code":2704,"iso":"VN","languages":{"English":{"name":"English","code":"en"},"Vietnamese":{"name":"Vietnamese","code":"vi"}}},{"name":"Slovenia","code":2705,"iso":"SI","languages":{"Slovenian":{"name":"Slovenian","code":"sl"}}},{"name":"South Africa","code":2710,"iso":"ZA","languages":{"English":{"name":"English","code":"en"}}},{"name":"Spain","code":2724,"iso":"ES","languages":{"Spanish":{"name":"Spanish","code":"es"}}},{"name":"Sweden","code":2752,"iso":"SE","languages":{"Swedish":{"name":"Swedish","code":"sv"}}},{"name":"Switzerland","code":2756,"iso":"CH","languages":{"German":{"name":"German","code":"de"},"French":{"name":"French","code":"fr"},"Italian":{"name":"Italian","code":"it"}}},{"name":"Thailand","code":2764,"iso":"TH","languages":{"Thai":{"name":"Thai","code":"th"}}},{"name":"United Arab Emirates","code":2784,"iso":"AE","languages":{"Arabic":{"name":"Arabic","code":"ar"},"English":{"name":"English","code":"en"}}},{"name":"Tunisia","code":2788,"iso":"TN","languages":{"Arabic":{"name":"Arabic","code":"ar"}}},{"name":"Turkiye","code":2792,"iso":"TR","languages":{"Turkish":{"name":"Turkish","code":"tr"}}},{"name":"Ukraine","code":2804,"iso":"UA","languages":{"Ukrainian":{"name":"Ukrainian","code":"uk"},"Russian":{"name":"Russian","code":"ru"}}},{"name":"North Macedonia","code":2807,"iso":"MK","languages":{"Macedonian":{"name":"Macedonian","code":"mk"}}},{"name":"Egypt","code":2818,"iso":"EG","languages":{"Arabic":{"name":"Arabic","code":"ar"},"English":{"name":"English","code":"en"}}},{"name":"United Kingdom","code":2826,"iso":"GB","languages":{"English":{"name":"English","code":"en"}}},{"name":"United States","code":2840,"iso":"US","languages":{"English":{"name":"English","code":"en"},"Spanish":{"name":"Spanish","code":"es"}}},{"name":"Burkina Faso","code":2854,"iso":"BF","languages":{"French":{"name":"French","code":"fr"}}},{"name":"Uruguay","code":2858,"iso":"UY","languages":{"Spanish":{"name":"Spanish","code":"es"}}},{"name":"Venezuela","code":2862,"iso":"VE","languages":{"Spanish":{"name":"Spanish","code":"es"}}}]
END;
        return json_decode(ob_get_clean(), true);
    }

    public function getLanguagesWithLocations()
    {
        $locations = $this->getLocationsWithLanguages();

        if (
            empty($locations)
            || !is_array($locations)
        ) {
            SEOAICAjaxResponse::error('No locations')->wpSend();
        }

        foreach ($locations as $country) {
            foreach ($country['languages'] as $language) {
                if (!isset($reversed[$language['code']])) {
                    $reversed[$language['code']] = [
                        "name" => $language['name'],
                        "code" => $language['code'],
                        "locations" => []
                    ];
                }

                $reversed[$language['code']]['locations'][$country['name']] = [
                    "name" => $country['name'],
                    "code" => $country['code']
                ];
            }
        }

        $this->setSavedLanguagues($reversed);

        return $reversed;
    }

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

	    global $SEOAIC_OPTIONS;

        if (empty($SEOAIC_OPTIONS['seoaic_api_token'])) {
            wp_die();
        }

        $locations = $this->getLocationsWithLanguages();

        if (
            empty($locations)
            || !is_array($locations)
        ) {
            SEOAICAjaxResponse::error('No locations')->wpSend();
        }

        if (!empty($_REQUEST['search'])) {
            $search = mb_strtolower(trim($_REQUEST['search']));
            $locations = array_filter($locations, function ($location) use ($search) {
                return !empty($location['name']) && stripos($location['name'], $search) !== false;
            });
        }

        $fields = [
            'locations' => array_map(function ($location) {
                return $location['name'];
            }, $locations),
        ];

        if (
            !empty($_REQUEST['options_html'])
            && 1 == $_REQUEST['options_html']
        ) {
            $selected = $this->getLastSelectedLocation();
            $fields['options_html'] = self::makeLocationsOptions($locations, $selected);
        }

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

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

        if (empty($_REQUEST['location'])) {
            SEOAICAjaxResponse::error('Empty location')->wpSend();
        }

        $locations = $this->getLocationsWithLanguages();

        if (
            empty($locations)
            || !is_array($locations)
        ) {
            SEOAICAjaxResponse::error('No locations')->wpSend();
        }

        $responseFields = [
            'languages' => [],
        ];

        foreach ($locations as $location) {
            if (
                $location['name'] == $_REQUEST['location']
                && !empty($location['languages'])
            ) {
                $this->setLastSelectedLocation($location);
                $responseFields['languages'] = $location['languages'];

                if (
                    !empty($_REQUEST['options_html'])
                    && 1 == $_REQUEST['options_html']
                ) {
                    $responseFields['options_html'] = self::makeLocationLanguagesOptions($location);
                }

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

        SEOAICAjaxResponse::success('Nothing here')->addFields($responseFields)->wpSend();
    }

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

        if (empty($_REQUEST['language'])) {
            SEOAICAjaxResponse::error('Empty language')->wpSend();
        }

        $languages = $this->getLanguagesWithLocations();
        $lang = $this->get_language_by($_REQUEST['language'], 'locale');
        $langCode = $lang['code'];

        if (
            empty($languages)
            || !is_array($languages)
        ) {
            SEOAICAjaxResponse::error('No locations')->wpSend();
        }

        if ($langCode === 'zh') {
            $langCode = str_replace('_', '-', $lang['locale']);
        }

        if (empty($languages[$langCode])) {
            SEOAICAjaxResponse::error('No locations')->wpSend();
        }

        $responseFields['language'] = $lang;

        $html = '';

        foreach ($languages[$langCode]['locations'] as $location) {
            $html .= '<option value="' . esc_attr($location['code']) . '">' . esc_html($location['name']) . '</option>';
        }

        $responseFields['options_html'] = $html;

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

    public function getLanguageLocations($lang)
    {
        if (!current_user_can('seoaic_edit_plugin')) {
            wp_die();
        }

        $langCode = $lang['code'];
        $languages = $this->getLanguagesWithLocations();

        if (
            empty($languages)
            || !is_array($languages)
        ) {
            SEOAICAjaxResponse::error('No locations')->wpSend();
        }

        if ($langCode === 'zh') {
            $langCode = str_replace('_', '-', $lang['locale']);
        }

        /**
         * Filter the language code used to determine language locations.
         *
         * @since 2.16.10
         *
         * @param string $langCode The language code to use for location fetching.
         */
        $langCode = apply_filters('seoaic_language_locations_lang_code', $langCode);

        if (!empty($languages[$langCode])) {
            return $languages[$langCode]['locations'];
        }

        return false;
    }

    private function requestLocationsWithLanguages()
    {
        global $SEOAIC;

        $result = $SEOAIC->curl->setMethodGet()->setTimeout(5)->initWithReturn('/api/ai/locations-and-languages', [], false, true);

        if (
            !empty($result['status'])
            && 'success' == $result['status']
            && !empty($result['data'])
        ) {
            return $result['data'];
        }

        return [];
    }

    public static function makeLocationsOptions($locationsWithLanguages = [], $default = null): string
    {
        $html = '';
        if (!empty($locationsWithLanguages)) {
            foreach ($locationsWithLanguages as $location) {
                $selected = !empty($default) && $location['name'] == $default['name'] ? ' selected' : '';
                $html .= '<option value="' . esc_attr($location['name']) . '"' . esc_attr($selected) . '>' . esc_html($location['name']) . '</option>';
            }
        }

        return $html;
    }

    public static function makeLocationLanguagesOptions($location = null, $selected = null)
    {
        $html = '';
        if (
            !empty($location)
            && !empty($location['languages'])
        ) {
            $languages = $location['languages'];
            usort($languages, function($a, $b) {
                return strcmp($a['name'], $b['name']);
            });

            foreach ($languages as $lang) {
                $selected = !empty($selected) && $lang['name'] == $selected ? ' selected' : '';
                $html .= '<option value="' . esc_attr($lang['name']) . '"' . esc_attr($selected) . '>' . esc_html($lang['name']) . '</option>';
            }
        }

        return $html;
    }

    public function getFirstLanguageByLocationName($locationName = null)
    {
        if (!empty($locationName)) {
            $locations = $this->getLocationsWithLanguages();
            foreach ($locations as $location) {
                if (
                    $locationName == $location['name']
                    && !empty($location['languages'])
                ) {
                    return array_values($location['languages'])[0];
                }
            }
        }

        return false;
    }

    public function getSavedLocations()
    {
        return get_transient(self::TRANSIENT_LOCATIONS_FIELD);
    }

    public function setSavedLocations($locations, $time = 6 * HOUR_IN_SECONDS)
    {
        set_transient(self::TRANSIENT_LOCATIONS_FIELD, $locations, $time);
    }

    public function getSavedLanguagues()
    {
        return get_transient(self::TRANSIENT_LANGUAGES_LOCATIONS_FIELD);
    }

    public function setSavedLanguagues($languagues = [])
    {
        set_transient(self::TRANSIENT_LANGUAGES_LOCATIONS_FIELD, $languagues, 2 * MINUTE_IN_SECONDS);
    }

    public function getLastSelectedLocation()
    {
        return get_transient(self::TRANSIENT_LAST_LOCATION_FIELD);
    }

    public function setLastSelectedLocation($location): void
    {
        set_transient(self::TRANSIENT_LAST_LOCATION_FIELD, $location);
    }

    function countPostsMapLang(string $lang, $dateQueryCallback, $callback)
    {
        $langArg = 'all' == $lang ? '' : $lang;
        $otherStatuses = seoaicGetOtherStatuses();

        switch ($this->is_multilang()) {
            case 'polylang':
                $args = array(
                    'posts_per_page'    => -1,
                    'post_type'         => 'any',
                    'post_status'       => array_merge($this->seoaic->posts::ANY_STATUS, array_keys($otherStatuses)),
                    'meta_key'          => 'seoaic_posted',
                    'meta_value'        => '1',
                    'date_query'        => $dateQueryCallback(),
                    'lang'              => $langArg,
                    'cache_results'     => false,
                );

                if (is_callable($callback)) {
                    $callback($args);
                }

                $posts_query = new WP_Query($args);

                return $posts_query->post_count;

            case 'wpml':
                $multilangCurrentLang = $this->get_current_language('code');
                $args = array(
                    'posts_per_page'    => -1,
                    'post_type'         => 'any',
                    'post_status'       => array_merge($this->seoaic->posts::ANY_STATUS, array_keys($otherStatuses)),
                    'meta_key'          => 'seoaic_posted',
                    'meta_value'        => '1',
                    'date_query'        => $dateQueryCallback(),
                    'cache_results'     => false,
                    'seoai_lang'        => $lang
                );

                $this->SEOAIC_addTitleQuery($args);
                if (empty($langArg) && empty($_REQUEST['seoaic_title'])) {
                    $args['suppress_filters'] = true;
                } else {
                    do_action('wpml_switch_language', $langArg);
                }

                if (is_callable($callback)) {
                    $callback($args);
                }

                $postsQuery = new WP_Query($args);
                $count = $postsQuery->post_count;
                do_action('wpml_switch_language', $multilangCurrentLang);

                return $count;
        }
    }

    public function SEOAIC_addTitleQuery(&$args)
    {
        $__GET = wp_unslash($_GET); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        if (!empty($__GET['seoaic_title'])) {
            $args['post_title_like'] = $__GET['seoaic_title'];
        }
    }

    public function preProcessPostsMainQuery(&$args = [], $lang = '')
    {
        $langArg = 'all' == $lang ? '' : $lang;

        switch ($this->is_multilang()) {
            case 'polylang':
                $args['lang'] = $langArg;
                break;

            case 'wpml':
                $args['seoai_lang'] = ($lang === '') ? 'all' : $lang;
                $defaultLangCode = $this->get_default_language('code');
                $args['default_lang_code'] = $defaultLangCode;

                if (
                    empty($langArg)
                    && empty($_REQUEST['seoaic_title'])
                    && !isset($_REQUEST['seoai-faq'])
                    && !isset($_REQUEST['seoai-lead'])
                    && !isset($_REQUEST['seoai-interactive'])
                ) {
                    $args['suppress_filters'] = true;
                } else {
                    do_action('wpml_switch_language', $langArg);
                }
                break;
        }
    }

    public function postProcessPostsMainQuery($lang)
    {
        switch ($this->is_multilang()) {
            case 'polylang':
                break;
            case 'wpml':
                do_action('wpml_switch_language', $lang);
                break;
        }
    }

    public function getBaseUrl()
    {
        switch ($this->is_multilang()) {
            case 'polylang':
                return pll_home_url();
            case 'wpml':
                return apply_filters('wpml_home_url', get_home_url(), NULL, 'default');
            default:
                return get_home_url();
        }
    }
}
