<?php

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

use ATFPP\AI_Translate\Services\API\Enums\AI_Capability;
use ATFPP\AI_Translate\Services\API\Helpers;

if (!class_exists('ATFP_Register_Route')):
    /**
     * ATFP_Register_Route
     *
     * @package ATFPP\AI_Translate\Services\API\Helpers
     */
    class ATFP_Register_Route
    {

        /**
         * The base name of the route.
         *
         * @var string
         */
        private $base_name;

        /**
         * Constructor
         *
         * @param string $base_name The base name of the route.
         */
        public function __construct($base_name)
        {
            $this->base_name = $base_name;
            add_action('rest_api_init', array($this, 'register_routes'));
        }

        /**
         * Register the routes
         */
        public function register_routes()
        {
            register_rest_route($this->base_name, '/(?P<slug>[\w-]+):translate-text', array(
                'methods' => 'POST',
                'callback' => array($this, 'ai_translation'),
                'permission_callback' => array($this, 'permission_only_admins'),
                'args' => array(
                    'slug' => array(
                        'type' => 'string',
                        'required' => true,
                        'sanitize_callback' => 'sanitize_key',
                    ),
                    'atfp_nonce' => array(
                        'type' => 'string',
                        'required' => true,
                        'sanitize_callback' => 'sanitize_text_field',
                        'validate_callback' => array($this, 'validate_atfp_ai_translate_nonce'),
                    ),
                    'strings' => array(
                        'type' => 'string',
                        'required' => true,
                    ),
                    'target_language' => array(
                        'type' => 'string',
                        'required' => true,
                        'sanitize_callback' => 'sanitize_text_field',
                    ),
                ),
            ));

            register_rest_route($this->base_name, '/(?P<slug>[\w-]+):bulk-translate-entries', array(
                'methods' => 'POST',
                'callback' => array($this, 'bulk_translate_entries'),
                'permission_callback' => array($this, 'permission_only_admins'),
                'args' => array(
                    'ids' => array(
                        'type' => 'string',
                        'required' => true,
                    ),
                    'lang' => array(
                        'type' => 'string', 
                        'required' => true,
                    ),
                    'privateKey' => array(
                        'type' => 'string',
                        'required' => true,
                        'sanitize_callback' => 'sanitize_text_field',
                        'validate_callback' => array($this, 'validate_atfpp_bulk_nonce'),
                    ),
                ),
            ));

            register_rest_route($this->base_name, '/(?P<slug>[\w-]+):bulk-translate-taxonomy-entries', array(
                'methods' => 'POST',
                'callback' => array($this, 'bulk_translate_taxonomy_entries'),
                'permission_callback' => array($this, 'permission_only_admins'),
                'args' => array(
                    'taxonomy' => array(
                        'type' => 'string',
                        'required' => true,
                    ),
                    'lang' => array(
                        'type' => 'string',
                        'required' => true,
                    ),
                    'privateKey' => array(
                        'type' => 'string',
                        'required' => true,
                        'sanitize_callback' => 'sanitize_text_field',
                        'validate_callback' => array($this, 'validate_atfpp_bulk_nonce'),
                    ),
                    'ids' => array(
                        'type' => 'string',
                        'required' => true,
                    ),
                ),
            ));

            register_rest_route($this->base_name, '/(?P<post_id>[\w-]+):create-translate-post', array(
                'methods' => 'POST',
                'callback' => array($this, 'create_translate_post'),
                'permission_callback' => array($this, 'permission_only_admins'),
                'args' => array(
                    'privateKey' => array(
                        'type' => 'string',
                        'required' => true,
                        'sanitize_callback' => 'sanitize_text_field',
                        'validate_callback' => array($this, 'validate_atfpp_create_post_nonce'),
                    ),
                    'post_id' => array(
                        'type' => 'integer',
                        'required' => true,
                        'sanitize_callback' => 'absint',
                    ),
                    'target_language' => array(
                        'type' => 'string',
                        'required' => true,
                        'sanitize_callback' => 'sanitize_text_field',
                    ),
                    'editor_type' => array(
                        'type' => 'string',
                        'required' => false,
                        'sanitize_callback' => 'sanitize_text_field',
                    ),
                    'source_language' => array(
                        'type' => 'string',
                        'required' => true,
                        'sanitize_callback' => 'sanitize_text_field',
                    ),
                    'post_title' => array(
                        'type' => 'string',
                        'required' => false,
                        'sanitize_callback' => 'sanitize_text_field',
                    ),
                    'post_content' => array(
                        'type' => 'string',
                        'required' => false,
                    ),
                ),
            ));

            register_rest_route($this->base_name, '/(?P<term_id>[\w-]+):create-translate-taxonomy', array(
                'methods' => 'POST',
                'callback' => array($this, 'create_translate_taxonomy'),
                'permission_callback' => array($this, 'permission_only_admins'),
                'args' => array(
                    'term_id' => array(
                        'required' => true,
                        'type' => 'integer',
                        'required' => true,
                        'sanitize_callback' => 'absint',
                    ),
                    'privateKey' => array(
                        'type' => 'string',
                        'required' => true,
                        'sanitize_callback' => 'sanitize_text_field',
                        'validate_callback' => array($this, 'validate_atfpp_create_term_nonce'),
                    ),
                    'target_language' => array(
                        'required' => true,
                        'type' => 'string',
                        'required' => true,
                        'sanitize_callback' => 'sanitize_text_field',
                    ),
                    'source_language' => array(
                        'required' => true,
                        'type' => 'string',
                        'required' => true,
                        'sanitize_callback' => 'sanitize_text_field',
                    ),
                    'taxonomy' => array(
                        'required' => true,
                        'type' => 'string',
                        'required' => true,
                        'sanitize_callback' => 'sanitize_text_field',
                    ),
                    'taxonomy_name' => array(
                        'required' => true,
                        'type' => 'string',
                        'sanitize_callback' => 'sanitize_text_field',
                    ),
                    'taxonomy_slug' => array(
                        'type' => 'string',
                        'sanitize_callback' => 'sanitize_text_field',
                    ),
                    'taxonomy_description' => array(
                        'required' => true,
                        'type' => 'string',
                        'sanitize_callback' => 'wp_kses_post',
                    ),
                ),
            ));
           
        }

        public function permission_only_admins( $request ){
            $nonce = $request->get_header( 'X-WP-Nonce' );

            if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
                return new WP_Error( 'rest_forbidden', __( 'Invalid nonce.', 'autopoly-ai-translation-for-polylang-pro' ), array( 'status' => 403 ) );
            }
            
            if ( ! is_user_logged_in() ) {
                return new \WP_Error( 'rest_forbidden', __( 'You are not authorized to perform this action.', 'autopoly-ai-translation-for-polylang-pro' ), array( 'status' => 401 ) );
            }
            if ( ! current_user_can( 'edit_posts' ) ) {
                return new \WP_Error( 'rest_forbidden', __( 'You are not authorized to perform this action.', 'autopoly-ai-translation-for-polylang-pro' ), array( 'status' => 403 ) );
            }
            return true;
        }

        public function validate_atfp_ai_translate_nonce( $value, $request, $param ){
            return wp_verify_nonce( $value, 'atfp_ai_translate_nonce' ) ? true : new \WP_Error( 'rest_invalid_param', __( 'Invalid security token sent.', 'autopoly-ai-translation-for-polylang-pro' ), array( 'status' => 403 ) );
        }

        public function validate_atfpp_bulk_nonce( $value, $request, $param ){
            return wp_verify_nonce( $value, 'atfpp_bulk_translate_entries_nonce' ) ? true : new \WP_Error( 'rest_invalid_param', __( 'You are not authorized to perform this action.', 'autopoly-ai-translation-for-polylang-pro' ), array( 'status' => 403 ) );
        }

        public function validate_atfpp_create_post_nonce( $value, $request, $param ){
            return wp_verify_nonce( $value, 'atfpp_create_translate_post_nonce' ) ? true : new \WP_Error( 'rest_invalid_param', __( 'You are not authorized to perform this action.', 'autopoly-ai-translation-for-polylang-pro' ), array( 'status' => 403 ) );
        }

        public function validate_atfpp_create_term_nonce( $value, $request, $param ){
            return wp_verify_nonce( $value, 'atfpp_create_translate_taxonomy_nonce' ) ? true : new \WP_Error( 'rest_invalid_param', __( 'You are not authorized to perform this action.', 'autopoly-ai-translation-for-polylang-pro' ), array( 'status' => 403 ) );
        }

        /**
         * AI Translation
         *
         * @param WP_REST_Request $params The request parameters.
         * @return WP_REST_Response The response.
         */
        public function ai_translation($params)
        {
            // Check if the user is logged in and has the necessary capabilities
            if (!is_user_logged_in()) wp_send_json_error('You are not authorized to perform this action.');
            if (!current_user_can('edit_posts')) wp_send_json_error('You are not authorized to perform this action.');
            
            // Get the parameters from the request
            $params = $params->get_params();

            // Get the service slug
            $service_slug = $params['slug'];
            
            // Verify the nonce
            if (!wp_verify_nonce($params['atfp_nonce'], 'atfp_ai_translate_nonce')) wp_send_json_error('You are not authorized to perform this action.');

            // Check if the user has the necessary capabilities
            if (wp_get_current_user()->has_cap('edit_posts')) {
                // Check if the service is available
                if (atfpp_ai_services()->is_service_available($params['slug'])) {

                    // Get the selected model
                    $selected_model = '';
                    if ( $params['slug'] === 'google' ) {
                        $selected_model = get_option('atfpp_selected_google_model', '');
                    } elseif ( $params['slug'] === 'openai' ) {
                        $selected_model = get_option('atfpp_selected_openai_model', '');
                    }
                    
                    // Get the service
                    $service = atfpp_ai_services()->get_available_service($params['slug']);

                    // Get the strings  
                    $strings = $params['strings'];
                    
                    // Convert strings to array if it's a JSON string
                    $string_array = is_string($strings) ? json_decode($strings, true) : $strings;

                    if(strpos($strings, '&lt;') !== false && strpos($strings, '&gt;') !== false){
                        $strings = html_entity_decode($strings);
                    }

                    // Get the target language
                    $target_language = $params['target_language'];

                    // Use the source language from params
                    $source_language = $params['source_language'];

                    $glossary_data = get_option('atfpp_glossary_data', []);
                    $glossary_instructions = '';
                    $matched_terms = [];
                    $has_glossary_terms = false;

                    if (!empty($glossary_data) && is_array($glossary_data)) {
                        // First, check if any strings contain glossary terms
                        foreach ($string_array as $string) {
                            foreach ($glossary_data as $entry) {
                                if (
                                    is_array($entry) &&
                                    !empty($entry['original_term']) &&
                                    $entry['original_language_code'] === $source_language &&
                                    stripos($string, $entry['original_term']) !== false
                                ) {
                                    $has_glossary_terms = true;
                                    break 2; // Break both loops if we find a match
                                }
                            }
                        }

                        // Only process glossary terms if we found matches
                        if ($has_glossary_terms) {
                            // If strings parameter exists, decode it and check each string
                            $strings_to_check = [];
                            if (isset($params['strings'])) {
                                $decoded_strings = json_decode($params['strings'], true);
                                if (is_array($decoded_strings)) {
                                    $strings_to_check = array_values($decoded_strings);
                                }
                            }

                            foreach ($glossary_data as $entry) {
                                // Skip invalid entries early
                                if (
                                    !is_array($entry) ||
                                    empty($entry['original_language_code']) ||
                                    empty($entry['original_term']) ||
                                    empty($entry['translations']) ||
                                    $entry['original_language_code'] !== $source_language
                                ) {
                                    continue;
                                }

                                // Use array_column for faster lookup if translations is an array of arrays
                                $translations_by_code = [];
                                foreach ($entry['translations'] as $translation) {
                                    if (
                                        is_array($translation) &&
                                        !empty($translation['target_language_code']) &&
                                        !empty($translation['translated_term'])
                                    ) {
                                        $translations_by_code[$translation['target_language_code']] = $translation['translated_term'];
                                    }
                                }

                                // Check if the term exists in any of the strings
                                $term_found = false;
                                if (!empty($strings_to_check)) {
                                    foreach ($strings_to_check as $string) {
                                        if (stripos($string, $entry['original_term']) !== false) {
                                            $term_found = true;
                                            break;
                                        }
                                    }
                                } else {
                                    // If no strings parameter, treat as found (original behavior)
                                    $term_found = true;
                                }

                                if ($term_found && isset($translations_by_code[$target_language])) {
                                    $matched_terms[] = [
                                        'term' => $entry['original_term'],
                                        'translation' => $translations_by_code[$target_language],
                                        'description' => $entry['description'] ?? ''
                                    ];
                                }
                            }
                        }
                    }

                    // Build glossary instructions string only if we found matches
                    if ($has_glossary_terms && !empty($matched_terms)) {
                        $glossary_instructions = "Please use the following glossary terms in your translation:\n";
                    
                        foreach ($matched_terms as $term) {
                            $src_term     = isset($term['term']) ? (string) $term['term'] : '';
                            $translation  = isset($term['translation']) ? (string) $term['translation'] : '';
                            $description  = isset($term['description']) ? (string) $term['description'] : '';
                    
                            $glossary_instructions .= "- \"{$src_term}\" → \"{$translation}\"";
                    
                            if ($description !== '') {
                                $glossary_instructions .= " — Note: {$description}";
                            }
                    
                            $glossary_instructions .= "\n";
                        }
                    } else {
                        $glossary_instructions = "";
                    }

                    // Get the custom prompt
                    $custom_prompt = get_option('atfp_context_aware', '');

                    $ai_request_timeout = get_option('atfp_ai_request_timeout', 120);

                    // Only return the translation in the format of a JSON object with the keys being numeric values (matching the source keys), and the values being the translated strings
                    $content = sprintf(
                    'Instruction 1: Translate visible text content semantically into %s language. Provide a proper meaning-based translation.  
				    Instruction 2: Do not translate or modify any content inside square brackets []. These are shortcodes or dynamic placeholders and must remain exactly as they are.
				    Instruction 3: Preserve all HTML tags and their attributes such as class, id, data-*, etc. Do not alter any part of the HTML structure.
				    Instruction 4: Return the translation in the format of a JSON object with the keys being numeric values (matching the source keys), and the values being the translated strings.
				    Instruction 5: Do not escape double quotes with backslashes. Output must be valid JSON without extra slashes.
				    Instruction 6: Translate the provided JSON array into %s language, regardless of whether the values are the same and Ensure the JSON is well-formed and complete.
                    Instruction 7: Decode any &lt; and &gt; HTML entities back to < and > symbols in the output & preserve and maintain whitespace.
				    Instruction 8: Return the output as a valid JSON object. Do not wrap the output in a string or markdown code block. Ensure the JSON is clean, parseable, and properly formatted. Please ensure that the output follows the format: {"key(numeric value)": "(translations of the strings in %s language)}" Strings are :- %s',
                    $target_language,
                    $target_language,
                    $target_language,
                    json_encode($strings)
                    );

                    // If the custom prompt is not empty, add it to the content
                    if ($custom_prompt && !empty($custom_prompt)) {
                        $content .= 'Instruction 9: ' . sanitize_text_field($custom_prompt);
                    }

                    if($service_slug === 'deepl'){
                        $data = array();

                        $strings=str_replace('\\n', '<ATFPP_NEW_L>', $strings);
                        $strings=str_replace('\\r', '<ATFPP_NEW_R>', $strings);

                        $data['text'] = json_decode($strings, true);
                        $data['target_lang'] = $target_language;
                        $data['tag_handling'] = 'html';

                        // Get DeepL API key from options
                        $deepl_api_key = get_option('Atfpp_Ai_Translate_deepl_api_key');

                        // var_dump($deepl_api_key);

                        // If we have glossary terms, create/use DeepL glossary
                        if ($has_glossary_terms && !empty($matched_terms)) {
                            // Format glossary entries for DeepL TSV format
                            $entries = '';
                            foreach ($matched_terms as $term) {
                                $entries .= $term['term'] . "\t" . $term['translation'] . "\n";
                            }

                            // Create glossary in DeepL
                            $glossary_response = wp_remote_post('https://api-free.deepl.com/v3/glossaries', [
                                'headers' => [
                                    'Authorization' => 'DeepL-Auth-Key ' . $deepl_api_key,
                                    'Content-Type'  => 'application/json'
                                ],
                                'body' => wp_json_encode([
                                    'name' => 'AutoPoly Glossary ' . current_time('timestamp'),
                                    'source_lang' => $source_language,
                                    'target_lang' => $target_language,
                                    'entries' => $entries,
                                    'entries_format' => 'tsv'
                                ]),
                                'timeout' => 20
                            ]);

                            if (!is_wp_error($glossary_response)) {
                                $glossary_data = json_decode(wp_remote_retrieve_body($glossary_response), true);
                                if (isset($glossary_data['glossary_id'])) {
                                    $data['glossary_id'] = $glossary_data['glossary_id'];
                                }
                            }

                        }

                        if(isset($custom_prompt) && !empty($custom_prompt)){
                            $data['context'] = $custom_prompt;
                        }

                        $content = json_encode($data);
                    }


                    // If glossary instructions are present, add them as a separate instruction
                    if ($glossary_instructions && !empty($glossary_instructions) && $service_slug !== 'deepl') {
                        $instruction_number = ($custom_prompt && !empty($custom_prompt)) ? 9 : 8;
                        $content .= 'Instruction ' . $instruction_number . ': ' . $glossary_instructions;
                    }


                    // Try to generate the text
                    try {
                        $model_params = array(
                            'feature'      => 'my-test-feature',
                            'capabilities' => array(AI_Capability::TEXT_GENERATION),
                        );

                        if ( !empty($selected_model) ) {
                            $model_params['model'] = $selected_model;
                        }

                        $candidates = $service
                            ->get_model($model_params, array('timeout' => (int) $ai_request_timeout))
                            ->generate_text($content);

                        // Get the text from the candidates
                        $text = Helpers::get_text_from_contents(
                            Helpers::get_candidate_contents($candidates)
                        );
                        
                        // Clean the text
                        $cleanText = preg_replace('/(^```json\n|```$)/', '', $text);

                        $cleanText=str_replace('<ATFPP_NEW_L>', '\n', $cleanText);
                        $cleanText=str_replace('<ATFPP_NEW_R>', '\r', $cleanText);
                        
                        // Replace the double backslashes with a single backslash
                        $final_text = preg_replace('/\\\\{2,}([\'"n])/', '\\\$1', $cleanText);

                        $translated_text=json_decode($final_text, true);

                        if(is_array($translated_text) && count($translated_text) === 1){
                            $key=array_keys($translated_text)[0];
                            $orignal_string=json_decode($translated_text[$key], true);
                            if(isset($translated_text[$key]) && json_decode($translated_text[$key]) !== null && isset($orignal_string[$key]) && json_decode($orignal_string[$key]) === null){
                                $translated_text[$key]=json_decode($translated_text[$key], true)[$key];
                               
                                $final_text=json_encode($translated_text);
                            }
                        }

                        // Return the data
                        $data = array('translate_data' => json_decode($final_text), 'text' => $cleanText);

                        // If we created a DeepL glossary, clean it up
                        if ($service_slug === 'deepl' && isset($glossary_data['glossary_id'])) {
                            wp_remote_request('https://api.deepl.com/v3/glossaries/' . $glossary_data['glossary_id'], [
                                'method' => 'DELETE',
                                'headers' => [
                                    'Authorization' => 'DeepL-Auth-Key ' . $deepl_api_key
                                ]
                            ]);
                        }

                        // // Convert object to array for easier handling
                        // $translated_array = (array) $data['translate_data'];

                        // $string_array=json_decode($strings,true);

                        // global $wpdb;
                        // $table_name = $wpdb->prefix . 'atfpp_translations';

                        // // 1. Add the language column if it doesn't exist
                        // $column_exists = $wpdb->get_var(
                        //     $wpdb->prepare("SHOW COLUMNS FROM `$table_name` LIKE %s", $target_language)
                        // );
                        // if (!$column_exists) {
                        //     $wpdb->query("ALTER TABLE `$table_name` ADD COLUMN `$target_language` VARCHAR(255)");
                        // }

                        // // 2. Add the source language column if it doesn't exist (for original strings)
                        // $source_column_exists = $wpdb->get_var(
                        //     $wpdb->prepare("SHOW COLUMNS FROM `$table_name` LIKE %s", $source_language)
                        // );
                        // if (!$source_column_exists) {
                        //     $wpdb->query("ALTER TABLE `$table_name` ADD COLUMN `$source_language` VARCHAR(255)");
                        // }

                        // // 3. Insert or update each translation
                        // foreach ($string_array as $index => $original) {
                        //     $translation = isset($translated_array[$index]) ? $translated_array[$index] : '';

                        //     // Check if a row exists for this id (index+1)
                        //     $row = $wpdb->get_row(
                        //         $wpdb->prepare("SELECT id FROM `$table_name` WHERE `$source_language` = %s", $original)
                        //     );

                        //     if ($row) {
                        //         // Update the translation in the language column
                        //         $wpdb->update(
                        //             $table_name,
                        //             array(
                        //                 $target_language => $translation
                        //             ),
                        //             array($source_language => $original)
                        //         );
                        //     } else {
                        //         // Insert a new row with the original string and the translation
                        //         $wpdb->insert(
                        //             $table_name,
                        //             array(
                        //                 $source_language => $original,
                        //                 $target_language => $translation
                        //             )
                        //         );
                        //     }
                        // }

                        wp_send_json_success($data);
                    } catch (Exception $e) {
                        wp_send_json_error('Error during text generation: ' . $e->getMessage());
                    }
                } else {
                    wp_send_json_error(sprintf(
                        '%s service is not available.',
                        $service_slug === 'google' ? 'GeminiAI' : ucfirst($service_slug)
                    ));
                }
            }

            wp_send_json_error('You are not authorized to perform this action.');
        }

        public function bulk_translate_entries($params)
        {
            // Check if the user is logged in and has the necessary capabilities
            if (!is_user_logged_in()) wp_send_json_error('You are not authorized to perform this action.');
            if (!current_user_can('edit_posts')) wp_send_json_error('You are not authorized to perform this action.');
            
            // Verify the nonce
            if (!wp_verify_nonce($params['privateKey'], 'atfpp_bulk_translate_entries_nonce')) wp_send_json_error('You are not authorized to perform this action.');
                
            global $polylang;

            $slug_translation_option = get_option('atfp_slug_translation_option','title_translate');

            // check language exists or not
            $translate_lang = json_decode($params['lang']);
           
            $post_ids=json_decode($params['ids']);
            $posts_translate=array();
            $gutenberg_block=false;


            $post_meta_sync = true;
            if (!isset(PLL()->options['sync']) || (isset(PLL()->options['sync']) && !in_array('post_meta', PLL()->options['sync']))) {
                $post_meta_sync = false;
            }

            if(count($translate_lang) > 0 && !(count($post_ids) < 1)){
                $pll_langs=$polylang->model->get_languages_list();
                $pll_langs_slugs=array_column($pll_langs, 'slug');
                $allowed_meta_fields=ATFPP_Helper::get_instance()->get_allowed_custom_fields();

                foreach($post_ids as $postId){
                    if(!current_user_can('edit_post', $postId)) continue;

                    $posts_translate[$postId]['sourceLanguage']=$polylang->model->post->get_language($postId)->slug;
                    $post_data=get_post($postId);

                    if(!$posts_translate[$postId]['sourceLanguage']){
                        $posts_translate[$postId]['sourceLanguage']=false;
                        $posts_translate[$postId]['title']=$post_data->post_title;
                        $posts_translate[$postId]['editor_type']=has_blocks($post_data->post_content) ? 'block' : 'classic';
                        $posts_translate[$postId]['post_link']=html_entity_decode( get_edit_post_link( $postId ) );
                        continue;
                    }

                    $elementor_enabled=get_post_meta($postId,'_elementor_edit_mode', true);

                    if(!$post_data) continue;

                    if($slug_translation_option === 'slug_translate'){
                        $posts_translate[$postId]['post_name']=urldecode(get_post_field('post_name', $postId));
                    }

                    $posts_translate[$postId]['title']=$post_data->post_title;
                    $posts_translate[$postId]['content']=has_blocks($post_data->post_content) ? parse_blocks($post_data->post_content) : $post_data->post_content;
                    $posts_translate[$postId]['content']=has_blocks($post_data->post_content) ? parse_blocks($post_data->post_content) : $post_data->post_content;
                    $posts_translate[$postId]['editor_type']=has_blocks($post_data->post_content) ? 'block' : 'classic';

                    if(isset($post_data->post_excerpt) && !empty($post_data->post_excerpt)){
                        $posts_translate[$postId]['excerpt']=$post_data->post_excerpt;
                    }

                    $posts_translate[$postId]['sourceLanguage']=!isset($posts_translate[$postId]['sourceLanguage']) ? pll_default_language() : $posts_translate[$postId]['sourceLanguage'];

                    if(!$post_meta_sync){
                        $post_meta_fields=get_post_meta($postId);
                        $existed_meta_fields=array_intersect(array_keys($post_meta_fields), array_keys($allowed_meta_fields));
            
                        foreach($existed_meta_fields as $key){
                            if(isset($post_meta_fields[$key]) && !empty($post_meta_fields[$key]) && isset($allowed_meta_fields[$key]['status']) && true === $allowed_meta_fields[$key]['status']){
                                $value=$allowed_meta_fields[$key]['type'] && is_array($post_meta_fields[$key]) ? maybe_unserialize($post_meta_fields[$key][0]) : maybe_unserialize($post_meta_fields[$key]);
                                $posts_translate[$postId]['metaFields'][$key]=$value;
                            }
                        }
                    }

                    $posts_translate[$postId]['post_link']=get_the_permalink($postId);

                    if($elementor_enabled && 'builder' === $elementor_enabled && defined('ELEMENTOR_VERSION')){
                        $elementor_data=get_post_meta($postId,'_elementor_data', true);

                        if($elementor_data && '' !== $elementor_data){
                            $posts_translate[$postId]['editor_type']='elementor';
                            $elementor_data = array();

                            if(class_exists('\Elementor\Plugin') && property_exists('\Elementor\Plugin', 'instance') ){
                                $elementor_data=\Elementor\Plugin::$instance->documents->get($postId)->get_elements_data();
                            }
                            
                            $posts_translate[$postId]['content']=$elementor_data;
                            unset($posts_translate[$postId]['metaFields']['_elementor_data']);
                        }
                    }

                    if($posts_translate[$postId]['editor_type'] === 'block' && !$gutenberg_block){
                        $gutenberg_block=true;
                    }

                    foreach($translate_lang as $lang){
                        if(in_array($lang, $pll_langs_slugs)){
                            $post_translate_status = $polylang->model->post->get_translation( $postId, $lang );
                            if(!$post_translate_status){
                                $posts_translate[$postId]['languages'][]=$lang;
                            }else{
                                $posts_translate[$postId]['postExists'][$lang]=array(
                                    'post_title'=>get_the_title($post_translate_status),
                                    'post_url'=>get_the_permalink($post_translate_status)
                                );
                            }
                        }   
                    }
                }
            }

            $data=array('posts'=>$posts_translate, 'CreateTranslatePostNonce'=>wp_create_nonce('atfpp_create_translate_post_nonce'));
            if(!$post_meta_sync){
                $data['allowedMetaFields']=json_encode($allowed_meta_fields);
            }

            if($gutenberg_block){
                $block_parse_rules = ATFPP_Helper::get_instance()->get_block_parse_rules();
                $data['blockParseRules']=json_encode($block_parse_rules);
            }

            if(count($posts_translate) > 0){
                wp_send_json_success($data);
            }else{
                wp_send_json_error('No posts to translate');
            };
        }

        public function create_translate_post($params){
            if(!isset($params['source_language']) || empty($params['source_language'])) wp_send_json_error('Invalid source language');
            if(!isset($params['post_id']) || !isset($params['target_language']) || (!isset($params['post_title']) && !isset($params['post_content']))) wp_send_json_error('Invalid request'); 
            if(!isset($params['target_language']) && empty($params['target_language'])) wp_send_json_error('Invalid target language');
            if(!wp_verify_nonce($params['privateKey'], 'atfpp_create_translate_post_nonce')) wp_send_json_error('You are not authorized to perform this action.');
            if(empty($params['post_title']) && empty($params['post_content'])) wp_send_json_error('Invalid request content & title empty');

            $params = $params->get_params();
            
            $post_id=intval(sanitize_text_field($params['post_id']));
            $target_language=sanitize_text_field($params['target_language']);
            $editor_type=sanitize_text_field($params['editor_type']);
            $source_language=sanitize_text_field($params['source_language']);

            $title=isset($params['post_title']) ? sanitize_text_field($params['post_title']) : '';

            $slug=isset($params['post_name']) && !empty($params['post_name']) ? sanitize_text_field($params['post_name']) : false;

            $excerpt=isset($params['post_excerpt']) ? sanitize_text_field($params['post_excerpt']) : '';

            $content=isset($params['post_content']) ? $params['post_content'] : '';

            $meta_fields=isset($params['post_meta_fields']) ? $params['post_meta_fields'] : '';

            if(!current_user_can('edit_post', $post_id)) wp_send_json_error('You are not authorized to perform this action.');

            $post_data=array(
                'post_title'=>sanitize_text_field($title),
                'post_content'=>$content,
            );

            if($excerpt && !empty($excerpt)){
                $post_data['post_excerpt']=sanitize_text_field($excerpt);
            }

            if($meta_fields && !empty($meta_fields)){
                $post_data['post_meta_fields']=json_decode($meta_fields, true);
            }

            $slug_translation_option = get_option('atfp_slug_translation_option','title_translate');

            if($slug_translation_option === 'slug_translate' && $slug && !empty($slug)){
                $post_data['post_name']=sanitize_title($slug);
            }else if($slug_translation_option === 'slug_keep'){
                $post_data['post_name']=sanitize_text_field(get_post_field('post_name', $post_id));
            }else{
                $post_data['post_name']=sanitize_title($title);
            };

            if($editor_type === 'elementor'){
                $post_data['meta_fields']['_elementor_data']=$content;
                unset($post_data['post_content']);
            }else if($editor_type === 'block'){
                $post_data['post_content']=serialize_blocks(json_decode($post_data['post_content'], true));
            }else if($editor_type === 'classic'){
                $post_data['post_content']=wp_kses_post(json_decode($params['post_content'], true));
            }else{
                $post_data['post_content']=wp_kses_post($post_data['post_content']);
            }

            global $polylang;
            $post_clone = new ATFP_Posts_Clone($polylang);
            $post_id = $post_clone->copy_post( $post_id, $source_language, $target_language, false, $post_data, $editor_type );

           if(!$post_id){
            wp_send_json_error('Unable to create the translated post for parent post ID ' . $post_id . ' in ' . $target_language . '.');
           }else{
            
            $post_link=html_entity_decode(get_the_permalink($post_id));
            $post_title=html_entity_decode(get_the_title($post_id));
            $post_edit_link=html_entity_decode(get_edit_post_link($post_id));

            wp_send_json_success(array('post_id'=>$post_id, 'target_language'=>$target_language, 'post_link'=>$post_link, 'post_title'=>$post_title, 'post_edit_link'=>$post_edit_link, 'update_translate_data_nonce'=>wp_create_nonce('atfp_translate_nonce')));
           }
        }

        public function bulk_translate_taxonomy_entries($params){
            if(!isset($params['taxonomy']) || empty($params['taxonomy'])) wp_send_json_error('Invalid taxonomy');
            if(!isset($params['lang']) || empty($params['lang'])) wp_send_json_error('Invalid language');
            if(!isset($params['privateKey']) || empty($params['privateKey'])) wp_send_json_error('Invalid private key');
            if(!isset($params['ids']) || empty($params['ids'])) wp_send_json_error('Invalid ids');
            
            // Check if the user is logged in and has the necessary capabilities
            if (!is_user_logged_in()) wp_send_json_error('You are not authorized to perform this action.');
            if (!current_user_can('edit_posts')) wp_send_json_error('You are not authorized to perform this action.');
            
            $params = $params->get_params();
            $slug_translation_option = get_option('atfp_slug_translation_option','title_translate');

            // Verify the nonce
            if (!wp_verify_nonce($params['privateKey'], 'atfpp_bulk_translate_entries_nonce')) wp_send_json_error('You are not authorized to perform this action.');

            $translate_lang=json_decode($params['lang']);
            
            $taxonomy_translate=array();

            if($translate_lang && count($translate_lang) > 0){
                global $polylang;
                $pll_langs=$polylang->model->get_languages_list();
                $pll_langs_slugs=array_column($pll_langs, 'slug');

                $taxonomy=sanitize_text_field($params['taxonomy']);
                $taxonomy_ids=json_decode($params['ids']);
    
                foreach($taxonomy_ids as $taxonomy_id){
                    $taxonomy_translate[$taxonomy_id]['sourceLanguage']=pll_get_term_language($taxonomy_id);
                    $taxonomy_data=get_term($taxonomy_id, $taxonomy);

                    if(!$taxonomy_translate[$taxonomy_id]['sourceLanguage']){
                        $taxonomy_translate[$taxonomy_id]['sourceLanguage']=false;
                        $taxonomy_translate[$taxonomy_id]['title']=$taxonomy_data->name;
                        $taxonomy_translate[$taxonomy_id]['editor_type']='taxonomy';
                        $taxonomy_translate[$taxonomy_id]['post_link']=html_entity_decode(get_edit_term_link($taxonomy_data->term_id, $taxonomy_data->taxonomy));
                        continue;
                    }
    
                    $taxonomy_translate[$taxonomy_id]['title']=$taxonomy_data->name;
                    
                    
                    if($slug_translation_option === 'slug_translate'){
                        $taxonomy_translate[$taxonomy_id]['post_name']=urldecode($taxonomy_data->slug);
                    }

                    $taxonomy_translate[$taxonomy_id]['editor_type']='taxonomy';

                    if($taxonomy_data->description && !empty($taxonomy_data->description)){
                        $taxonomy_translate[$taxonomy_id]['content']=$taxonomy_data->description;
                    }

                    foreach($translate_lang as $lang){
                        if(in_array($lang, $pll_langs_slugs)){
                            $post_translate_status = pll_get_term( $taxonomy_id, $lang );
    
                            if(!$post_translate_status){
                                $taxonomy_translate[$taxonomy_id]['languages'][]=$lang;
                            }else{
                                $term = get_term( $post_translate_status, $taxonomy );

                                $title=isset($term->name) ? $term->name : '';
                                $slug=get_term_link($post_translate_status, $taxonomy);

                                if(is_wp_error($slug) || empty($slug)){
                                    $slug='';
                                }

                                $taxonomy_translate[$taxonomy_id]['postExists'][$lang]=array(
                                    'post_title'=>$title,
                                    'post_url'=>$slug,
                                );
                            }
                        }   
                    }
                }
            }

            $data=array('posts'=>$taxonomy_translate, 'CreateTranslatePostNonce'=>wp_create_nonce('atfpp_create_translate_taxonomy_nonce'));

            if(count($taxonomy_translate) > 0){
                wp_send_json_success($data);
            }else{
                wp_send_json_error('No taxonomy posts to translate');
            };
        }

        public function create_translate_taxonomy($params){
            if(!isset($params['term_id']) || empty($params['term_id'])) wp_send_json_error('Invalid term id');
            if(!isset($params['target_language']) || empty($params['target_language'])) wp_send_json_error('Invalid target language');
            if(!isset($params['taxonomy']) || empty($params['taxonomy'])) wp_send_json_error('Invalid taxonomy');
            if(!isset($params['source_language']) || empty($params['source_language'])) wp_send_json_error('Invalid source language');
            if(!wp_verify_nonce($params['privateKey'], 'atfpp_create_translate_taxonomy_nonce')) wp_send_json_error('You are not authorized to perform this action.');
        
            $params = $params->get_params();

            $term_id=intval(sanitize_text_field($params['term_id']));
            $target_language=isset($params['target_language']) ? sanitize_text_field($params['target_language']) : '';
            $taxonomy=isset($params['taxonomy']) ? sanitize_text_field($params['taxonomy']) : '';
            $taxonomy_name=isset($params['taxonomy_name']) ? sanitize_text_field($params['taxonomy_name']) : '';
            $taxonomy_slug=isset($params['taxonomy_slug']) ? sanitize_title($params['taxonomy_slug']) : '';
            $taxonomy_description=isset($params['taxonomy_description']) ? wp_kses_post($params['taxonomy_description']) : '';
            $slug_translation_option = get_option('atfp_slug_translation_option','title_translate');

            if(!$target_language) wp_send_json_error('Invalid target language');
            if(!$taxonomy) wp_send_json_error('Invalid taxonomy');

            $get_term=get_term($term_id, $taxonomy);

            $translations=new Translations();

            if($taxonomy_name && !empty($taxonomy_name)){
                $entry = $this->create_translation_entry($get_term->name, $taxonomy_name, 'name');
                $translations->add_entry($entry);
            }

            if($taxonomy_description && !empty($taxonomy_description)){
                $entry = $this->create_translation_entry($get_term->description, $taxonomy_description, 'description');
                $translations->add_entry($entry);
            }

            if($slug_translation_option === 'slug_translate' && $taxonomy_slug && !empty($taxonomy_slug)){
                $taxonomy_slug=sanitize_title($taxonomy_slug);
            }else if($slug_translation_option === 'slug_keep'){
                $taxonomy_slug=sanitize_text_field($get_term->slug);
            }else{
                $taxonomy_slug=sanitize_title($taxonomy_name);
            };
            
            
            if($taxonomy_slug && !empty($taxonomy_slug)){
                $entry = $this->create_translation_entry($get_term->slug, $taxonomy_slug, 'slug');
                $translations->add_entry($entry);
            }

            global $polylang;

            $target_language_object = $polylang->model->get_language($target_language);
            $post_clone = new ATFP_Term_Clone($polylang);

            $term_id = $post_clone->translate( array('id'=>$term_id, 'data'=>$translations), $target_language_object );

            if(!$term_id){
                wp_send_json_error('Unable to create the translated post for parent post ID ' . $term_id . ' in ' . $target_language_object . '.');
                exit;
            }

            $term_url=get_term_link($term_id, $taxonomy);
            $term = get_term( $term_id, $taxonomy );
            $term_title=html_entity_decode($term->name);
            $term_link=$term_url && is_string($term_url) ? html_entity_decode($term_url) : '';
            $term_edit_link=html_entity_decode(get_edit_term_link($term_id, $taxonomy));
                
            wp_send_json_success(array('post_id'=>$term_id, 'target_language'=>$target_language, 'post_link'=>$term_link, 'post_title'=>$term_title, 'post_edit_link'=>$term_edit_link, 'update_translate_data_nonce'=>wp_create_nonce('atfp_translate_nonce')));
        }

        public function create_translation_entry($singular, $translation, $context){
            $entry = new Translation_Entry(
                array(
                    'singular'=>$singular,
                    'translation'=>array($translation),
                    'context'=>$context,
                )
            );
            return $entry;
        }
    }
endif;
