<?php

if ( !defined( 'ABSPATH' ) ) {
    exit;
}
class polylai_Translator {
    var $ai_engine;

    public function __construct( $ai_engine = null ) {
        if ( $ai_engine == null ) {
            $ai_engine = polylai_Utils::get_ai_engine();
        }
        // free version
        $this->ai_engine = new polylai_ChatGPT();
    }

    public function make_post(
        $from_post_id,
        $title,
        $text,
        $excerpt,
        $meta,
        $status
    ) {
        $oldpost = get_post( $from_post_id );
        $post = [
            'post_author'    => $oldpost->post_author,
            'post_date'      => $oldpost->post_date,
            'post_date_gmt'  => $oldpost->post_date_gmt,
            'post_content'   => $text,
            'post_title'     => $title,
            'post_excerpt'   => $excerpt,
            'post_status'    => $status,
            'comment_status' => $oldpost->comment_status,
            'ping_status'    => $oldpost->ping_status,
            'post_password'  => $oldpost->post_password,
            'post_name'      => sanitize_title( $title ),
            'to_ping'        => $oldpost->to_ping,
            'post_type'      => $oldpost->post_type,
        ];
        $new_post_id = wp_insert_post( $post );
        $all_meta = get_post_meta( $from_post_id );
        foreach ( $all_meta as $key => $item ) {
            if ( substr( $key, 0, strlen( '_ez-toc' ) ) == '_ez-toc' || substr( $key, 0, strlen( '_yoast' ) ) == '_yoast' ) {
                foreach ( $item as $value ) {
                    update_post_meta( $new_post_id, $key, maybe_unserialize( $value ) );
                }
            }
        }
        foreach ( $meta as $key => $value ) {
            update_post_meta( $new_post_id, $key, $value );
        }
        return $new_post_id;
    }

    public function create_translation(
        $from_post_id,
        $new_post_id,
        $locale,
        $meta = []
    ) {
        pll_set_post_language( $new_post_id, $locale );
        $translations = pll_get_post_translations( $from_post_id );
        $translations[$locale] = $new_post_id;
        pll_save_post_translations( $translations );
        // Get locale names for translation - using consistent mapping
        $language_mapping = array(
            'en' => 'English',
            'es' => 'Spanish',
            'it' => 'Italian',
            'fr' => 'French',
            'de' => 'German',
            'pt' => 'Portuguese',
            'ru' => 'Russian',
            'ja' => 'Japanese',
            'zh' => 'Chinese',
            'ar' => 'Arabic',
            'nl' => 'Dutch',
            'pl' => 'Polish',
            'tr' => 'Turkish',
        );
        // Get current locale slug for mapping
        $current_locale_slug = pll_get_post_language( $from_post_id, 'slug' );
        $current_locale_name = ( isset( $language_mapping[$current_locale_slug] ) ? $language_mapping[$current_locale_slug] : $current_locale_slug );
        $locale_name = ( isset( $language_mapping[$locale] ) ? $language_mapping[$locale] : $locale );
        $taxonomies = get_post_taxonomies( $from_post_id );
        if ( $taxonomies ) {
            foreach ( $taxonomies as $taxonomy ) {
                if ( $taxonomy == 'language' ) {
                    continue;
                }
                if ( $taxonomy == 'post_translations' ) {
                    continue;
                }
                $terms = wp_get_object_terms( $from_post_id, $taxonomy, [
                    'fields' => 'ids',
                ] );
                if ( count( $terms ) == 0 ) {
                    continue;
                }
                foreach ( $terms as $k => $term_id ) {
                    $new_tx_id = pll_get_term( $terms[$k], $locale );
                    if ( $new_tx_id == $term_id ) {
                        // Same term, skip
                        unset($terms[$k]);
                        continue;
                    }
                    if ( $new_tx_id == 0 ) {
                        // No translation found, create one
                        $new_tx_id = $this->create_translated_term(
                            $terms[$k],
                            $taxonomy,
                            $locale,
                            $current_locale_name,
                            $locale_name
                        );
                        if ( $new_tx_id > 0 ) {
                            $terms[$k] = $new_tx_id;
                        } else {
                            unset($terms[$k]);
                        }
                        continue;
                    }
                    $terms[$k] = $new_tx_id;
                }
                wp_set_object_terms( $new_post_id, $terms, $taxonomy );
            }
        }
        $acf_fields = [];
        if ( isset( $meta[polylai_ACF::META_KEY] ) && is_array( $meta[polylai_ACF::META_KEY] ) ) {
            $acf_fields = $meta[polylai_ACF::META_KEY];
            unset($meta[polylai_ACF::META_KEY]);
        }
        foreach ( $meta as $key => $value ) {
            add_post_meta( $new_post_id, $key, $value );
        }
        if ( function_exists( 'update_field' ) ) {
            foreach ( $acf_fields as $field ) {
                if ( !is_array( $field ) || !isset( $field['selector'] ) ) {
                    continue;
                }
                $updated = update_field( $field['selector'], $field['value'], $new_post_id );
                if ( $updated === false && isset( $field['name'] ) && $field['name'] !== $field['selector'] ) {
                    $updated = update_field( $field['name'], $field['value'], $new_post_id );
                }
                if ( $updated === false ) {
                    $field_name = ( isset( $field['name'] ) ? $field['name'] : $field['selector'] );
                    polylai_Utils::db_log(
                        'error',
                        'ACF translate',
                        'Unable to update ACF/SCF field ' . $field_name,
                        $new_post_id
                    );
                }
            }
        } else {
            if ( count( $acf_fields ) > 0 ) {
                polylai_Utils::db_log(
                    'error',
                    'ACF translate',
                    'update_field() is not available while saving translated ACF/SCF fields',
                    $new_post_id
                );
            }
        }
        return $new_post_id;
    }

    /**
     * Create a translated term (category or tag) when no translation exists
     * 
     * @param int $original_term_id Original term ID
     * @param string $taxonomy Taxonomy type (category, post_tag, etc.)
     * @param string $target_locale Target locale code
     * @param string $source_locale_name Source locale name
     * @param string $target_locale_name Target locale name
     * @return int New translated term ID or 0 if failed
     */
    private function create_translated_term(
        $original_term_id,
        $taxonomy,
        $target_locale,
        $source_locale_name,
        $target_locale_name
    ) {
        // Get original term data
        $original_term = get_term( $original_term_id, $taxonomy );
        if ( is_wp_error( $original_term ) || !$original_term ) {
            polylai_Utils::db_log( 'error', 'create_translated_term', 'Failed to get original term: ' . $original_term_id );
            return 0;
        }
        try {
            // Translate term name
            $translated_name_result = $this->ai_engine->translate(
                $original_term->name,
                $source_locale_name,
                $target_locale_name,
                null,
                true
            );
            // Handle the new return format (array with content and tokens)
            if ( is_array( $translated_name_result ) ) {
                $translated_name = $translated_name_result['content'];
            } else {
                // Fallback for backward compatibility
                $translated_name = $translated_name_result;
            }
            // Translate description if it exists
            $translated_description = '';
            if ( !empty( $original_term->description ) ) {
                $translated_desc_result = $this->ai_engine->translate(
                    $original_term->description,
                    $source_locale_name,
                    $target_locale_name,
                    null,
                    true
                );
                // Handle the new return format
                if ( is_array( $translated_desc_result ) ) {
                    $translated_description = $translated_desc_result['content'];
                } else {
                    $translated_description = $translated_desc_result;
                }
            }
            // Create new term
            $new_term_args = array(
                'description' => $translated_description,
                'slug'        => sanitize_title( $translated_name ),
            );
            // Handle parent for hierarchical taxonomies (categories)
            if ( is_taxonomy_hierarchical( $taxonomy ) && $original_term->parent > 0 ) {
                $parent_term_translation = pll_get_term( $original_term->parent, $target_locale );
                if ( $parent_term_translation > 0 ) {
                    $new_term_args['parent'] = $parent_term_translation;
                }
            }
            $new_term = wp_insert_term( $translated_name, $taxonomy, $new_term_args );
            if ( is_wp_error( $new_term ) ) {
                polylai_Utils::db_log( 'error', 'create_translated_term', 'Failed to create term: ' . $new_term->get_error_message() );
                return 0;
            }
            $new_term_id = $new_term['term_id'];
            // Set language for the new term
            pll_set_term_language( $new_term_id, $target_locale );
            // Link the translation
            $translations = pll_get_term_translations( $original_term_id );
            if ( !$translations ) {
                $translations = array();
            }
            $translations[$target_locale] = $new_term_id;
            pll_save_term_translations( $translations );
            polylai_Utils::db_log( 'info', 'create_translated_term', "Created translated term: '{$translated_name}' (ID: {$new_term_id}) for taxonomy '{$taxonomy}' in locale '{$target_locale}'" );
            return $new_term_id;
        } catch ( Exception $e ) {
            polylai_Utils::db_log( 'error', 'create_translated_term', 'Exception: ' . $e->getMessage() );
            return 0;
        }
    }

    private function translate_block(
        $id,
        $block,
        $locale_from,
        $locale_to,
        $tot_blocks,
        $locale
    ) {
        foreach ( $block['innerBlocks'] as $i => $innerBlock ) {
            $block['innerBlocks'][$i] = $this->translate_block(
                $id,
                $block['innerBlocks'][$i],
                $locale_from,
                $locale_to,
                $tot_blocks,
                $locale
            );
        }
        $html = ( $block['innerHTML'] == null ? '' : $block['innerHTML'] );
        $cleanText = trim( strip_tags( $html ) );
        // cannot use wp_strip_all_tags here
        $total_tokens = 0;
        if ( strlen( $cleanText ) > 0 ) {
            foreach ( $block['innerContent'] as $i => $c ) {
                $splitted_text = polylai_Utils::split_text( $block['innerContent'][$i], 500 );
                $block['innerContent'][$i] = '';
                foreach ( $splitted_text as $ii => $s ) {
                    $translation_result = $this->ai_engine->translate(
                        $s,
                        $locale_from,
                        $locale_to,
                        null
                    );
                    // Handle the new return format (array with content and tokens)
                    if ( is_array( $translation_result ) ) {
                        $translated_text = $translation_result['content'];
                        $total_tokens += $translation_result['tokens'];
                    } else {
                        // Fallback for backward compatibility
                        $translated_text = $translation_result;
                    }
                    $block['innerContent'][$i] .= $translated_text . " ";
                    if ( $tot_blocks == 1 ) {
                        // update_post_meta($id, POLYLAI_KEY, ["locale" => $locale, "perc" => ceil($ii / count($splitted_text) * 100)]);
                    }
                }
                // $block['innerContent'][$i] = $this->ai_engine->translate($block['innerContent'][$i], $locale_from, $locale_to, null);
            }
        }
        return $block;
    }

    private function translate_meta( $id, $current_locale_name, $locale_name ) {
        $meta_to_translate = [];
        $meta = [];
        $total_tokens = 0;
        $meta_yoast = polylai_Yoast::translate_meta(
            $id,
            $current_locale_name,
            $locale_name,
            $this->ai_engine
        );
        $meta_elementor = polylai_Elementor::translate_meta(
            $id,
            $current_locale_name,
            $locale_name,
            $this->ai_engine
        );
        $meta_acf = polylai_ACF::translate_meta(
            $id,
            $current_locale_name,
            $locale_name,
            $this->ai_engine
        );
        $meta = array_merge( $meta, $meta_yoast );
        $meta = array_merge( $meta, $meta_elementor );
        $meta = array_merge( $meta, $meta_acf );
        foreach ( $meta_to_translate as $key ) {
            $item = get_post_meta( $id, $key, true );
            if ( $item ) {
                $translation_result = $this->ai_engine->translate(
                    $item,
                    $current_locale_name,
                    $locale_name,
                    $id,
                    true
                );
                // Handle the new return format (array with content and tokens)
                if ( is_array( $translation_result ) ) {
                    $meta[$key] = $translation_result['content'];
                    $total_tokens += $translation_result['tokens'];
                } else {
                    // Fallback for backward compatibility
                    $meta[$key] = $translation_result;
                }
            }
        }
        return $meta;
    }

    public function translate(
        $id,
        $locale,
        $locale_name,
        $status
    ) {
        $post = get_post( $id );
        $current_locale = pll_get_post_language( $id, 'slug' );
        $current_locale_name = pll_get_post_language( $id, 'name' );
        $total_tokens = 0;
        $content = $post->post_content;
        $translation_result = $this->ai_engine->translate(
            $content,
            $current_locale,
            $locale,
            $id,
            $this->is_plain_text( $content )
        );
        // Handle the new return format (array with content and tokens)
        if ( is_array( $translation_result ) ) {
            $translated_text = $translation_result['content'];
            $total_tokens += $translation_result['tokens'];
        } else {
            // Fallback for backward compatibility
            $translated_text = $translation_result;
        }
        $translated_text = $this->translate_links( $translated_text, $locale, $current_locale );
        try {
            $title_result = $this->ai_engine->translate(
                $post->post_title,
                $current_locale_name,
                $locale_name,
                $id,
                true
            );
            // Handle the new return format for title
            if ( is_array( $title_result ) ) {
                $title = $title_result['content'];
                $total_tokens += $title_result['tokens'];
            } else {
                // Fallback for backward compatibility
                $title = $title_result;
            }
            if ( str_ends_with( $title, "." ) ) {
                $title = substr( $title, 0, strlen( $title ) - 1 );
            }
            $meta = $this->translate_meta( $id, $current_locale_name, $locale_name );
            $excerpt = get_the_excerpt( $id );
            if ( trim( $excerpt ) ) {
                $excerpt_result = $this->ai_engine->translate(
                    $excerpt,
                    $current_locale_name,
                    $locale_name,
                    $id,
                    $this->is_plain_text( $excerpt )
                );
                // Handle the new return format for excerpt
                if ( is_array( $excerpt_result ) ) {
                    $excerpt = $excerpt_result['content'];
                    $total_tokens += $excerpt_result['tokens'];
                } else {
                    // Fallback for backward compatibility
                    $excerpt = $excerpt_result;
                }
            }
            $elementor_data = polylai_Elementor::translate_data(
                $id,
                $current_locale_name,
                $locale_name,
                $this->ai_engine
            );
            if ( $elementor_data ) {
                $meta['_elementor_data'] = $elementor_data;
            }
            $duplicator = new polylai_Duplicator();
            $new_post_id = $duplicator->duplicate(
                $id,
                $title,
                $translated_text,
                $excerpt,
                $status,
                $meta
            );
            //$new_post_id = $this->create_translation($id, $title, $translated_text, $excerpt, $meta, $current_locale, $locale, $status);
            $this->create_translation(
                $id,
                $new_post_id,
                $locale,
                $meta
            );
            // Get the translation ID from Manager and update with token count
            $translations = polylai_Manager::getInstance()->list_pending_translating();
            foreach ( $translations as $translation ) {
                if ( $translation->source_post_id == $id && $translation->locale_to == $locale ) {
                    polylai_Manager::getInstance()->set_status(
                        $translation->id,
                        'complete',
                        null,
                        $total_tokens
                    );
                    polylai_Utils::db_log(
                        'info',
                        "translate",
                        "complete {$locale}",
                        $id
                    );
                    break;
                }
            }
        } catch ( Exception $e ) {
            polylai_Utils::db_log( 'error', 'translate', $e->getMessage() );
        }
    }

    private function translate_links( $html, $locale, $current_locale ) {
        $pattern = '/href="([^"]*)"/';
        if ( preg_match_all( $pattern, $html, $matches ) ) {
            foreach ( $matches[1] as $href ) {
                $postID = url_to_postid( $href );
                //print_r("POST ID $href $postID\n");
                if ( $postID > 0 ) {
                    $translatedPost = pll_get_post( $postID, $locale );
                    if ( $translatedPost ) {
                        $link = get_permalink( $translatedPost );
                        if ( $link ) {
                            $html = str_replace( $href, $link, $html );
                        }
                    }
                } else {
                    $cat_id = $this->get_category_id_by_url( $href, $current_locale );
                    if ( $cat_id > 0 ) {
                        $term_id = pll_get_term( $cat_id, $locale );
                        //print_r("CAT ID $href $term_id $link\n");
                        if ( $term_id > 0 ) {
                            $link = get_category_link( $term_id );
                            $html = str_replace( $href, $link, $html );
                        }
                    }
                }
            }
        }
        return $html;
    }

    private function is_plain_text( $string ) {
        return strip_tags( $string ) === $string;
    }

    private function translate_blocks( $id, $locale, $locale_name ) {
        $post = get_post( $id );
        $current_locale = pll_get_post_language( $id, 'slug' );
        $current_locale_name = pll_get_post_language( $id, 'name' );
        $blocks = parse_blocks( $post->post_content );
        $tot_blocks = count( $blocks );
        polylai_Utils::db_log(
            'info',
            "translate",
            count( $blocks ) . " blocks {$locale}",
            $id
        );
        $tr_blocks = [];
        update_post_meta( $id, POLYLAI_KEY, [
            "locale" => $locale,
            "perc"   => 0,
        ] );
        foreach ( $blocks as $i => $block ) {
            $tr_blocks[] = $this->translate_block(
                $id,
                $block,
                $current_locale_name,
                $locale_name,
                $tot_blocks,
                $locale
            );
            if ( count( $blocks ) > 1 ) {
                update_post_meta( $id, POLYLAI_KEY, [
                    "locale" => $locale,
                    "perc"   => ceil( $i / $tot_blocks * 100 ),
                ] );
            }
        }
        $translated_text = serialize_blocks( $tr_blocks );
        $translated_text = $this->translate_links( $translated_text, $locale, $current_locale );
        try {
            $title = $this->ai_engine->translate(
                $post->post_title,
                $current_locale_name,
                $locale_name,
                $id
            );
            if ( str_ends_with( $title, "." ) ) {
                $title = substr( $title, 0, strlen( $title ) - 1 );
            }
            $meta = $this->translate_meta( $id, $current_locale_name, $locale_name );
            $excerpt = get_the_excerpt( $id );
            if ( !empty( trim( $excerpt ) ) ) {
                $excerpt = $this->ai_engine->translate(
                    $excerpt,
                    $current_locale_name,
                    $locale_name,
                    $id
                );
            }
            $newId = $this->create_translation(
                $id,
                $title,
                $translated_text,
                $excerpt,
                $meta,
                $current_locale,
                $locale
            );
            $newPost = get_post( $newId );
            do_action(
                'save_post',
                $newId,
                $newPost,
                false
            );
            if ( class_exists( '\\Elementor\\Plugin' ) ) {
                $post_css = new \Elementor\Core\Files\CSS\Post($newId);
                $post_css->update();
                \Elementor\Plugin::$instance->files_manager->clear_cache();
                polylai_Utils::db_log( 'debug', 'translate', "clear elementor cache" );
            }
        } catch ( Exception $e ) {
            polylai_Utils::db_log( 'error', 'translate', $e->getMessage() );
        }
    }

    private function translate_categories() {
        $italian_language = 'it';
        // Ottiene le categorie con il filtro della lingua italiana
        $args = array(
            'taxonomy'   => 'category',
            'lang'       => $italian_language,
            'hide_empty' => false,
        );
        $categories = get_terms( $args );
        // Ottiene le categorie
    }

    private function get_category_id_by_url( $category_url, $locale ) {
        //print_r(pll_home_url($locale) . "\n");
        $path = str_replace( pll_home_url( $locale ), '', $category_url );
        $path = trim( $path, '/' );
        $slug = array_filter( explode( '/', $path ) );
        $category_slug = end( $slug );
        $category = get_term_by( 'slug', $category_slug, 'category' );
        if ( $category ) {
            return $category->term_id;
        } else {
            return 0;
        }
    }

}
