<?php
/**
 * Admin UI helpers for taxonomy translation management.
 *
 * Registers admin columns, renders translation links, and handles requests to
 * create new term translations from the taxonomy screens.
 *
 * @package WPR_Translate
 */

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

/**
 * Register admin hooks responsible for taxonomy translation management.
 *
 * @return void
 */
function wpr_translation_bootstrap_taxonomy_admin() {
    // Only run in the admin dashboard.
    if ( ! is_admin() ) {
        return;
    }
    // Register handlers that enhance the taxonomy screens once the admin loads.
    add_action( 'admin_init', 'wpr_translation_setup_taxonomy_columns' );
    add_action( 'admin_init', 'wpr_translation_handle_add_term_translation_request' );
    add_action( 'current_screen', 'wpr_translation_register_taxonomy_language_filter_hooks' );
    add_action( 'edit_term_form', 'wpr_translation_render_term_language_panel', 10, 2 );
}
add_action( 'init', 'wpr_translation_bootstrap_taxonomy_admin' );

/**
 * Register language filter hooks for taxonomy list screens.
 *
 * @param WP_Screen $screen Current admin screen object.
 *
 * @return void
 */
function wpr_translation_register_taxonomy_language_filter_hooks( $screen ) {
    if ( ! $screen instanceof WP_Screen ) {
        return;
    }

    if ( 'edit-tags' !== $screen->base ) {
        return;
    }

    $taxonomy = ! empty( $screen->taxonomy ) ? sanitize_key( $screen->taxonomy ) : '';

    if ( '' === $taxonomy || ! wpr_translation_is_taxonomy_translatable( $taxonomy ) ) {
        return;
    }

    add_filter( 'views_' . $screen->id, 'wpr_translation_add_taxonomy_language_filter_views' );
    add_filter( 'get_terms', 'wpr_translation_filter_admin_taxonomy_terms_by_language', 30, 4 );
}

/**
 * Retrieve selected language filter value for taxonomy list screen.
 *
 * @return string Language code or empty string for all.
 */
function wpr_translation_get_admin_taxonomy_language_filter_value() {
    $requested_language = isset( $_GET['wpr_term_language'] ) ? sanitize_key( wp_unslash( $_GET['wpr_term_language'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended

    if ( '' === $requested_language || 'all' === $requested_language ) {
        return '';
    }

    return $requested_language;
}

/**
 * Add language filter links to taxonomy list table views.
 *
 * @param array $views Existing views list.
 *
 * @return array
 */
function wpr_translation_add_taxonomy_language_filter_views( $views ) {
    $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;

    if ( ! $screen instanceof WP_Screen || 'edit-tags' !== $screen->base ) {
        return $views;
    }

    $taxonomy = ! empty( $screen->taxonomy ) ? sanitize_key( $screen->taxonomy ) : '';

    if ( '' === $taxonomy || ! wpr_translation_is_taxonomy_translatable( $taxonomy ) ) {
        return $views;
    }

    $languages = wpr_translation_get_active_languages();

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

    $selected_language = wpr_translation_get_admin_taxonomy_language_filter_value();
    $post_type         = isset( $_GET['post_type'] ) ? sanitize_key( wp_unslash( $_GET['post_type'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $search_term       = isset( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $base_args         = array(
        'taxonomy' => $taxonomy,
    );

    if ( '' !== $post_type ) {
        $base_args['post_type'] = $post_type;
    }

    if ( '' !== $search_term ) {
        $base_args['s'] = $search_term;
    }

    $all_url = add_query_arg( $base_args, admin_url( 'edit-tags.php' ) );
    $all_css = '' === $selected_language ? ' class="current"' : '';

    $views['wpr_term_language_all'] = sprintf(
        '<a href="%1$s"%2$s>%3$s</a>',
        esc_url( $all_url ),
        $all_css,
        esc_html__( 'All languages', 'wpr-translate' )
    );

    foreach ( $languages as $language ) {
        if ( ! is_array( $language ) || empty( $language['code'] ) ) {
            continue;
        }

        $language_code = sanitize_key( $language['code'] );
        $language_name = ! empty( $language['name'] ) ? sanitize_text_field( $language['name'] ) : strtoupper( $language_code );

        if ( '' === $language_code ) {
            continue;
        }

        $language_args                       = $base_args;
        $language_args['wpr_term_language'] = $language_code;
        $language_url                        = add_query_arg( $language_args, admin_url( 'edit-tags.php' ) );
        $language_css                        = ( $selected_language === $language_code ) ? ' class="current"' : '';

        $views[ 'wpr_term_language_' . $language_code ] = sprintf(
            '<a href="%1$s"%2$s>%3$s</a>',
            esc_url( $language_url ),
            $language_css,
            esc_html( $language_name )
        );
    }

    return $views;
}

/**
 * Resolve language code for a term from translation mappings.
 *
 * @param int    $term_id   Term ID.
 * @param string $taxonomy  Taxonomy slug.
 * @param array  $languages Active languages list.
 *
 * @return string
 */
function wpr_translation_get_term_language_code( $term_id, $taxonomy, $languages = array() ) {
    $term_id  = absint( $term_id );
    $taxonomy = sanitize_key( $taxonomy );

    if ( $term_id <= 0 || '' === $taxonomy ) {
        return '';
    }

    if ( empty( $languages ) ) {
        $languages = wpr_translation_get_active_languages();
    }

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

    $element_type  = wpr_translation_get_taxonomy_element_type( $taxonomy );
    $group         = wpr_translation_get_translation_group( $term_id, $element_type );
    $translations  = isset( $group['translations'] ) && is_array( $group['translations'] ) ? $group['translations'] : array();
    $language_code = '';

    foreach ( $translations as $code => $translated_term_id ) {
        if ( (int) $translated_term_id === $term_id ) {
            $language_code = sanitize_key( $code );
            break;
        }
    }

    if ( '' === $language_code ) {
        $language_code = wpr_translation_resolve_term_language_from_meta( $term_id, $taxonomy, $languages );
    }

    if ( '' === $language_code && ! empty( $group['source_language'] ) ) {
        $language_code = sanitize_key( $group['source_language'] );
    }

    if ( '' === $language_code ) {
        $language_code = sanitize_key( wpr_translation_get_default_language_code( $languages ) );
    }

    return $language_code;
}

/**
 * Resolve a term language code using translation meta mappings.
 *
 * This fallback keeps admin taxonomy filtering working when term relationships
 * are present in term meta but missing from the translation table.
 *
 * @param int    $term_id   Term ID.
 * @param string $taxonomy  Taxonomy slug.
 * @param array  $languages Active languages list.
 *
 * @return string
 */
function wpr_translation_resolve_term_language_from_meta( $term_id, $taxonomy, $languages = array() ) {
    $term_id  = absint( $term_id );
    $taxonomy = sanitize_key( $taxonomy );

    if ( $term_id <= 0 || '' === $taxonomy ) {
        return '';
    }

    if ( empty( $languages ) ) {
        $languages = wpr_translation_get_active_languages();
    }

    if ( empty( $languages ) || ! is_array( $languages ) ) {
        return '';
    }

    $canonical_term_id = $term_id;

    if ( function_exists( 'wpr_translate_resolve_original_term_id' ) ) {
        $resolved_term_id = absint( wpr_translate_resolve_original_term_id( $term_id, $taxonomy ) );

        if ( $resolved_term_id > 0 ) {
            $canonical_term_id = $resolved_term_id;
        }
    } else {
        $maybe_original = absint( get_term_meta( $term_id, 'wpr_original_term_id', true ) );

        if ( $maybe_original > 0 ) {
            $canonical_term_id = $maybe_original;
        }
    }

    if ( $canonical_term_id <= 0 || $canonical_term_id === $term_id ) {
        return '';
    }

    foreach ( $languages as $language ) {
        if ( ! is_array( $language ) || empty( $language['code'] ) ) {
            continue;
        }

        $language_code = sanitize_key( $language['code'] );

        if ( '' === $language_code ) {
            continue;
        }

        $meta_key = function_exists( 'wpr_translate_get_translated_term_meta_key' )
            ? wpr_translate_get_translated_term_meta_key( $language_code )
            : 'wpr_translated_term_' . $language_code;
        $mapped_term_id = absint( get_term_meta( $canonical_term_id, $meta_key, true ) );

        if ( $mapped_term_id > 0 && $mapped_term_id === $term_id ) {
            return $language_code;
        }
    }

    return '';
}
/**
 * Filter taxonomy list table terms by selected language.
 *
 * @param array         $terms      Retrieved terms.
 * @param array|string  $taxonomies Taxonomies in query.
 * @param array         $args       Query args.
 * @param WP_Term_Query $query      Query object.
 *
 * @return array
 */
function wpr_translation_filter_admin_taxonomy_terms_by_language( $terms, $taxonomies, $args, $query ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found
    if ( ! is_admin() || empty( $terms ) || is_wp_error( $terms ) ) {
        return $terms;
    }

    $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;

    if ( ! $screen instanceof WP_Screen || 'edit-tags' !== $screen->base ) {
        return $terms;
    }

    $taxonomy = ! empty( $screen->taxonomy ) ? sanitize_key( $screen->taxonomy ) : '';

    if ( '' === $taxonomy || ! wpr_translation_is_taxonomy_translatable( $taxonomy ) ) {
        return $terms;
    }

    $selected_language = wpr_translation_get_admin_taxonomy_language_filter_value();
    $orderby           = isset( $_GET['orderby'] ) ? sanitize_key( wp_unslash( $_GET['orderby'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $order             = isset( $_GET['order'] ) ? strtolower( sanitize_key( wp_unslash( $_GET['order'] ) ) ) : 'asc'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $sort_by_language  = ( 'wpr_term_language' === $orderby );
    $order_desc        = ( 'desc' === $order );

    if ( '' === $selected_language && ! $sort_by_language ) {
        return $terms;
    }

    $languages = wpr_translation_get_active_languages();

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

    $valid_language_codes = array();

    foreach ( $languages as $language ) {
        if ( is_array( $language ) && ! empty( $language['code'] ) ) {
            $valid_language_codes[] = sanitize_key( $language['code'] );
        }
    }

    $valid_language_codes = array_filter( array_unique( $valid_language_codes ) );

    if ( '' !== $selected_language && ! in_array( $selected_language, $valid_language_codes, true ) ) {
        return $terms;
    }

    $filtered_terms = $terms;

    if ( '' !== $selected_language ) {
        $filtered_terms = array();

        foreach ( $terms as $term ) {
            if ( ! ( $term instanceof WP_Term ) ) {
                $filtered_terms[] = $term;
                continue;
            }

            if ( sanitize_key( $term->taxonomy ) !== $taxonomy ) {
                $filtered_terms[] = $term;
                continue;
            }

            $term_language = wpr_translation_get_term_language_code( (int) $term->term_id, $taxonomy, $languages );

            if ( $selected_language === $term_language ) {
                $filtered_terms[] = $term;
            }
        }
    }

    if ( $sort_by_language ) {
        $language_labels = array();

        foreach ( $languages as $language ) {
            if ( ! is_array( $language ) || empty( $language['code'] ) ) {
                continue;
            }

            $language_code = sanitize_key( $language['code'] );
            $language_name = ! empty( $language['name'] ) ? sanitize_text_field( $language['name'] ) : strtoupper( $language_code );

            if ( '' !== $language_code ) {
                $language_labels[ $language_code ] = $language_name;
            }
        }

        usort(
            $filtered_terms,
            static function( $left_term, $right_term ) use ( $taxonomy, $languages, $language_labels, $order_desc ) {
                if ( ! ( $left_term instanceof WP_Term ) || ! ( $right_term instanceof WP_Term ) ) {
                    return 0;
                }

                $left_code   = wpr_translation_get_term_language_code( (int) $left_term->term_id, $taxonomy, $languages );
                $right_code  = wpr_translation_get_term_language_code( (int) $right_term->term_id, $taxonomy, $languages );
                $left_label  = isset( $language_labels[ $left_code ] ) ? $language_labels[ $left_code ] : strtoupper( $left_code );
                $right_label = isset( $language_labels[ $right_code ] ) ? $language_labels[ $right_code ] : strtoupper( $right_code );
                $comparison  = strcasecmp( $left_label, $right_label );

                if ( 0 === $comparison ) {
                    $comparison = strcasecmp( (string) $left_term->name, (string) $right_term->name );
                }

                if ( $order_desc ) {
                    return $comparison * -1;
                }

                return $comparison;
            }
        );
    }

    return $filtered_terms;
}

/**
 * Add the translation column to each translatable taxonomy list screen.
 *
 * @return void
 */
function wpr_translation_setup_taxonomy_columns() {
    // Load all registered taxonomies for evaluation.
    $taxonomies = get_taxonomies( array(), 'names' );
    if ( empty( $taxonomies ) ) {
        return;
    }
    foreach ( $taxonomies as $taxonomy ) {
        // Skip taxonomies that are not configured for translation.
        if ( ! wpr_translation_is_taxonomy_translatable( $taxonomy ) ) {
            continue;
        }
        // Attach both the column headers and the content renderer for each taxonomy.
        add_filter( 'manage_edit-' . $taxonomy . '_columns', 'wpr_translation_add_taxonomy_translations_column' );
        add_filter( 'manage_edit-' . $taxonomy . '_sortable_columns', 'wpr_translation_add_taxonomy_sortable_columns' );
        add_filter( 'manage_' . $taxonomy . '_custom_column', 'wpr_translation_render_taxonomy_translations_column', 10, 3 );
    }
}

/**
 * Register sortable taxonomy admin columns used by translation UI.
 *
 * @param array $columns Existing sortable columns.
 *
 * @return array
 */
function wpr_translation_add_taxonomy_sortable_columns( $columns ) {
    // Allow term list sorting by the custom language column.
    $columns['wpr_term_language'] = 'wpr_term_language';

    return $columns;
}

/**
 * Insert the language column header when missing.
 *
 * @param array $columns Existing columns.
 *
 * @return array Modified columns.
 */
function wpr_translation_add_taxonomy_translations_column( $columns ) {
    if ( isset( $columns['wpr_term_translations'] ) ) {
        unset( $columns['wpr_term_translations'] );
    }

    if ( isset( $columns['wpr_term_language'] ) ) {
        return $columns;
    }

    $columns['wpr_term_language'] = __( 'Language', 'wpr-translate' );

    return $columns;
}

/**
 * Render translation links and badges inside the translations column.
 *
 * @param string $content Existing column output.
 * @param string $column  Column identifier.
 * @param int    $term_id Current term ID.
 *
 * @return string Column HTML.
 */
function wpr_translation_render_taxonomy_translations_column( $content, $column, $term_id ) {
    // Resolve the current taxonomy from the screen context.
    $screen   = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
    $taxonomy = $screen && ! empty( $screen->taxonomy ) ? $screen->taxonomy : '';

    if ( 'wpr_term_language' !== $column ) {
        return $content;
    }

    // Render the language badge for the current term.
    if ( '' === $taxonomy || ! wpr_translation_is_taxonomy_translatable( $taxonomy ) ) {
        return esc_html__( '—', 'wpr-translate' );
    }

    $languages = wpr_translation_get_active_languages();

    if ( empty( $languages ) ) {
        return esc_html__( '—', 'wpr-translate' );
    }

    $language_code = wpr_translation_get_term_language_code( $term_id, $taxonomy, $languages );

    if ( '' === $language_code ) {
        return esc_html__( '—', 'wpr-translate' );
    }

    $language_name = '';
    $flag_code     = '';

    if ( function_exists( 'wpr_translate_get_language' ) ) {
        $language_data = wpr_translate_get_language( $language_code );

        if ( is_array( $language_data ) ) {
            if ( ! empty( $language_data['name'] ) ) {
                $language_name = sanitize_text_field( $language_data['name'] );
            }

            if ( ! empty( $language_data['flag'] ) ) {
                $flag_code = sanitize_key( $language_data['flag'] );
            }
        }
    }

    if ( '' === $language_name || '' === $flag_code ) {
        foreach ( $languages as $language ) {
            $code = isset( $language['code'] ) ? sanitize_key( $language['code'] ) : '';

            if ( $code !== $language_code ) {
                continue;
            }

            if ( '' === $language_name && ! empty( $language['name'] ) ) {
                $language_name = sanitize_text_field( $language['name'] );
            }

            if ( '' === $flag_code && ! empty( $language['flag'] ) ) {
                $flag_code = sanitize_key( $language['flag'] );
            }

            break;
        }
    }

    if ( '' === $flag_code ) {
        $flag_code = $language_code;
    }

    if ( '' === $language_name ) {
        $language_name = strtoupper( $language_code );
    }

    $flag_url = '';

    // Build the flag URL when available.
    if ( '' !== $flag_code && defined( 'WPR_TRANSLATE_URL' ) ) {
        $flag_url = esc_url_raw( WPR_TRANSLATE_URL . 'assets/img/flags/4x3/' . $flag_code . '.svg' );
    }

    $flag_markup = '';

    if ( '' !== $flag_url ) {
        /* translators: %s: Language name. */
        $flag_alt    = sprintf( __( '%s flag', 'wpr-translate' ), $language_name );
        $flag_markup = sprintf(
            '<div class="wpr-term-language-flag"><img src="%1$s" alt="%2$s" width="18" height="14" loading="lazy" decoding="async" /></div>',
            esc_url( $flag_url ),
            esc_attr( $flag_alt )
        );
    }

    $language_header_markup = sprintf(
        '<div class="wpr-term-language-top">%1$s<div class="wpr-term-language-name">%2$s</div></div>',
        $flag_markup,
        esc_html( $language_name )
    );

    // Resolve the translation group for this term.
    $element_type = wpr_translation_get_taxonomy_element_type( $taxonomy );
    $group        = wpr_translation_get_translation_group( $term_id, $element_type );
    $map          = is_array( $group['translations'] ) ? $group['translations'] : array();

    // Ensure the map always references the current term ID when applicable.
    foreach ( $map as $code => $translated_term_id ) {
        if ( (int) $translated_term_id === (int) $term_id ) {
            $map[ $code ] = (int) $term_id;
        }
    }

    $default_language = wpr_translation_get_default_language_code( $languages );

    // Ensure the default language is present in the map.
    if ( ! in_array( $term_id, $map, true ) && $default_language ) {
        $map[ $default_language ] = (int) $term_id;
    }

    $items     = array();
    $post_type = $screen && ! empty( $screen->post_type ) ? sanitize_key( $screen->post_type ) : '';

    // Build translation action links for each language.
    foreach ( $languages as $language ) {
        $code       = isset( $language['code'] ) ? sanitize_key( $language['code'] ) : '';
        $label_name = ! empty( $language['name'] ) ? sanitize_text_field( $language['name'] ) : strtoupper( $code );

        if ( '' === $label_name && '' !== $code ) {
            $label_name = strtoupper( $code );
        }

        if ( '' === $code ) {
            continue;
        }

        if ( isset( $map[ $code ] ) && $map[ $code ] ) {
            $target_term_id = (int) $map[ $code ];
            $edit_link      = get_edit_term_link( $target_term_id, $taxonomy );

            if ( $edit_link ) {
                $link = sprintf(
                    '<a href="%1$s" class="wpr-translation-link wpr-translation-link-edit" title="%3$s">%2$s</a>',
                    esc_url( $edit_link ),
                    esc_html( sprintf( __( 'Edit %s', 'wpr-translate' ), strtolower( $code ) ) ),
                    esc_attr( $label_name )
                );
                $items[] = '<div class="wpr-translation-item">' . $link . '</div>';
            }

            continue;
        }

        // Build the "Add" action that redirects users to a new translation screen.
        $query_args = array(
            'action'   => 'wpr_add_term_translation',
            'taxonomy' => $taxonomy,
            'term_id'  => $term_id,
            'language' => $code,
        );

        if ( '' !== $post_type ) {
            $query_args['post_type'] = $post_type;
        }

        $url = wp_nonce_url(
            add_query_arg( $query_args, admin_url( 'edit-tags.php' ) ),
            wpr_translation_get_term_translation_nonce_action( $term_id, $taxonomy, $code )
        );

        $items[] = sprintf(
            '<div class="wpr-translation-item"><a href="%1$s" class="wpr-translation-link wpr-translation-link-add">%2$s</a></div>',
            esc_url( $url ),
            esc_html( sprintf( __( 'Add %s', 'wpr-translate' ), strtolower( $code ) ) )
        );
    }

    $reference_items = array();
    $original_term_id = (int) $term_id;
    $current_language = wpr_translation_get_term_language_code( $term_id, $taxonomy, $languages );

    if ( function_exists( 'wpr_translate_resolve_original_term_id' ) ) {
        $resolved_original_term = absint( wpr_translate_resolve_original_term_id( $term_id, $taxonomy ) );

        if ( $resolved_original_term > 0 ) {
            $original_term_id = $resolved_original_term;
        }
    }

    // Show target rows for original terms and a source row for translated terms.
    if ( $original_term_id === (int) $term_id ) {
        foreach ( $languages as $language ) {
            $code = isset( $language['code'] ) ? sanitize_key( $language['code'] ) : '';

            if ( '' === $code || $code === $current_language ) {
                continue;
            }

            $translated_term_id = 0;

            if ( function_exists( 'wpr_translate_read_translated_term_id_from_meta' ) ) {
                $translated_term_id = absint( wpr_translate_read_translated_term_id_from_meta( $original_term_id, $taxonomy, $code ) );
            }

            if ( $translated_term_id <= 0 && ! empty( $map[ $code ] ) ) {
                $translated_term_id = absint( $map[ $code ] );
            }

            if ( $translated_term_id <= 0 || $translated_term_id === $term_id ) {
                continue;
            }

            $translated_term = get_term( $translated_term_id, $taxonomy );

            if ( ! ( $translated_term instanceof WP_Term ) ) {
                continue;
            }

            $translated_label = strtolower( $code ) . ': ' . $translated_term->name;
            $translated_link  = get_edit_term_link( $translated_term_id, $taxonomy );

            if ( $translated_link ) {
                $reference_items[] = sprintf(
                    '<div class="wpr-translation-item"><a href="%1$s" class="wpr-translation-link wpr-translation-link-related">%2$s</a></div>',
                    esc_url( $translated_link ),
                    esc_html( $translated_label )
                );
            } else {
                $reference_items[] = sprintf(
                    '<div class="wpr-translation-item">%1$s</div>',
                    esc_html( $translated_label )
                );
            }
        }
    } elseif ( $original_term_id > 0 ) {
        $source_term = get_term( $original_term_id, $taxonomy );

        if ( $source_term instanceof WP_Term ) {
            $source_label = 'source: ' . $source_term->name;
            $source_link  = get_edit_term_link( $original_term_id, $taxonomy );

            if ( $source_link ) {
                $reference_items[] = sprintf(
                    '<div class="wpr-translation-item"><a href="%1$s" class="wpr-translation-link wpr-translation-link-related">%2$s</a></div>',
                    esc_url( $source_link ),
                    esc_html( $source_label )
                );
            } else {
                $reference_items[] = sprintf(
                    '<div class="wpr-translation-item">%1$s</div>',
                    esc_html( $source_label )
                );
            }
        }
    }

    $items               = array_merge( $items, $reference_items );
    $translations_markup = '';

    if ( ! empty( $items ) ) {
        $translations_markup = '<div class="wpr-translation-links">' . implode( '', $items ) . '</div>';
    }

    return '<div class="wpr-term-language">' . $language_header_markup . $translations_markup . '</div>';
}
/**
 * Handle requests triggered by clicking "Add" links in the translations column.
 *
 * @return void
 */
function wpr_translation_handle_add_term_translation_request() {
    // Only handle explicit add translation requests.
    $action = isset( $_GET['action'] ) ? sanitize_key( wp_unslash( $_GET['action'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    if ( 'wpr_add_term_translation' !== $action ) {
        return;
    }
    // Read request parameters from the query string.
    $term_id   = isset( $_GET['term_id'] ) ? absint( $_GET['term_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $taxonomy  = isset( $_GET['taxonomy'] ) ? sanitize_key( wp_unslash( $_GET['taxonomy'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $language  = isset( $_GET['language'] ) ? sanitize_text_field( wp_unslash( $_GET['language'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $post_type = isset( $_GET['post_type'] ) ? sanitize_key( wp_unslash( $_GET['post_type'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    if ( ! $term_id || '' === $taxonomy || '' === $language ) {
        wp_die( esc_html__( 'Invalid translation request.', 'wpr-translate' ) );
    }
    // Validate the request nonce and user permissions.
    check_admin_referer( wpr_translation_get_term_translation_nonce_action( $term_id, $taxonomy, $language ) );
    $taxonomy_obj = get_taxonomy( $taxonomy );
    if ( ! $taxonomy_obj || ! current_user_can( $taxonomy_obj->cap->edit_terms ) ) {
        wp_die( esc_html__( 'You are not allowed to translate this term.', 'wpr-translate' ) );
    }
    if ( ! wpr_translation_is_taxonomy_translatable( $taxonomy ) ) {
        wp_die( esc_html__( 'This taxonomy is not configured for translation.', 'wpr-translate' ) );
    }
    $languages = wpr_translation_get_active_languages();
    if ( empty( $languages ) ) {
        wp_die( esc_html__( 'No languages available for translation.', 'wpr-translate' ) );
    }
    $language_codes = wp_list_pluck( $languages, 'code' );
    if ( ! in_array( $language, $language_codes, true ) ) {
        wp_die( esc_html__( 'Invalid target language.', 'wpr-translate' ) );
    }
    $language         = strtolower( sanitize_key( $language ) );
    $element_type     = wpr_translation_get_taxonomy_element_type( $taxonomy );
    $translations     = wpr_translation_get_translation_group( $term_id, $element_type );
    $translation_map  = is_array( $translations['translations'] ) ? $translations['translations'] : array();
    $default_language = wpr_translation_get_default_language_code( $languages );
    $existing_translation_id = 0;

    if ( function_exists( 'wpr_translate_lookup_translated_term_id_strict' ) ) {
        $resolved_existing_term = wpr_translate_lookup_translated_term_id_strict( $term_id, $taxonomy, $language );

        if ( is_numeric( $resolved_existing_term ) ) {
            $resolved_existing_term = absint( $resolved_existing_term );

            if ( $resolved_existing_term > 0 && $resolved_existing_term !== $term_id ) {
                $existing_translation_id = $resolved_existing_term;
            }
        }
    }

    if ( 0 === $existing_translation_id && isset( $translation_map[ $language ] ) && $translation_map[ $language ] ) {
        $existing_translation_id = absint( $translation_map[ $language ] );
    }

    if ( $existing_translation_id > 0 ) {
        // If the translation already exists simply redirect to its edit screen.
        $redirect = get_edit_term_link( $existing_translation_id, $taxonomy );

        if ( $redirect ) {
            wp_safe_redirect( $redirect );
            exit;
        }
    }

    $trid            = isset( $translations['trid'] ) ? (int) $translations['trid'] : 0;
    $source_language = isset( $translations['source_language'] ) ? sanitize_key( $translations['source_language'] ) : '';
    // Ensure a translation group exists for the term.
    if ( ! $trid && function_exists( 'wpr_translation_generate_trid' ) ) {
        $trid = wpr_translation_generate_trid();
        $current_language = $source_language ? $source_language : $default_language;
        if ( $current_language ) {
            $is_original = ( '' !== $default_language && $current_language === $default_language );
            wpr_translation_insert_translation_record(
                $term_id,
                $element_type,
                $trid,
                $current_language,
                $is_original ? null : $default_language,
                'publish',
                $is_original
            );
            $source_language = $current_language;
        }
    }
    // Determine which term should act as the source for duplication.
    $source_term_id = $term_id;
    if ( $source_language && isset( $translation_map[ $source_language ] ) ) {
        $source_term_id = (int) $translation_map[ $source_language ];
    } elseif ( $default_language && isset( $translation_map[ $default_language ] ) ) {
        $source_term_id = (int) $translation_map[ $default_language ];
        $source_language = $default_language;
    }
    $source_term = get_term( $source_term_id, $taxonomy );
    if ( ! $source_term || is_wp_error( $source_term ) ) {
        $source_term_id = $term_id;
        $source_term    = get_term( $term_id, $taxonomy );
    }
    if ( ! $source_term || is_wp_error( $source_term ) ) {
        wp_die( esc_html__( 'Source term not found.', 'wpr-translate' ) );
    }
    if ( ! $source_language ) {
        $source_language = $default_language;
    }

    // Duplicate the term into the requested language.
    $duplication = wpr_translation_duplicate_term_for_language(
        $source_term_id,
        $taxonomy,
        $language,
        array(
            'trid'            => $trid,
            'source_language' => $source_language,
        )
    );

    if ( is_wp_error( $duplication ) ) {
        wp_die( esc_html( $duplication->get_error_message() ) );
    }

    if ( empty( $duplication['term_id'] ) ) {
        wp_die( esc_html__( 'Could not create translation term.', 'wpr-translate' ) );
    }

    $new_term_id = (int) $duplication['term_id'];
    $redirect = get_edit_term_link( $new_term_id, $taxonomy );
    if ( ! $redirect ) {
        $redirect = add_query_arg(
            array(
                'taxonomy'  => $taxonomy,
                'post_type' => $post_type,
            ),
            admin_url( 'edit-tags.php' )
        );
    }
    wp_safe_redirect( $redirect );
    exit;
}

/**
 * Output the language selector panel on the term edit form.
 *
 * @param WP_Term $term     The term being edited.
 * @param string  $taxonomy Taxonomy slug.
 *
 * @return void
 */
function wpr_translation_render_term_language_panel( $term, $taxonomy ) {
    // Validate the term and user capabilities before output.
    if ( ! $term instanceof WP_Term ) {
        return;
    }
    $taxonomy     = sanitize_key( $taxonomy );
    $taxonomy_obj = get_taxonomy( $taxonomy );
    if ( ! $taxonomy_obj || ! current_user_can( $taxonomy_obj->cap->edit_terms ) ) {
        return;
    }
    if ( ! wpr_translation_is_taxonomy_translatable( $taxonomy ) ) {
        return;
    }
    $languages = wpr_translation_get_active_languages();
    if ( empty( $languages ) ) {
        return;
    }
    // Resolve the current term language and translation map.
    $element_type = wpr_translation_get_taxonomy_element_type( $taxonomy );
    $group        = wpr_translation_get_translation_group( $term->term_id, $element_type );
    $translations = is_array( $group['translations'] ) ? $group['translations'] : array();
    $current_language = '';
    foreach ( $translations as $code => $translated_term_id ) {
        if ( (int) $translated_term_id === (int) $term->term_id ) {
            $current_language = sanitize_key( $code );
        }
    }
    if ( '' === $current_language && ! empty( $group['source_language'] ) ) {
        $current_language = sanitize_key( $group['source_language'] );
    }
    if ( '' === $current_language ) {
        $current_language = wpr_translation_get_default_language_code( $languages );
    }
    $source_selected = 0;
    if ( ! empty( $group['source_language'] ) && isset( $translations[ $group['source_language'] ] ) ) {
        $candidate = (int) $translations[ $group['source_language'] ];
        if ( $candidate !== (int) $term->term_id ) {
            $source_selected = $candidate;
        }
    }
    // Build source term options for the dropdown.
    $options = array();
    foreach ( $translations as $code => $translated_term_id ) {
        $translated_term_id = (int) $translated_term_id;
        if ( $translated_term_id === (int) $term->term_id ) {
            continue;
        }
        $other_term = get_term( $translated_term_id, $taxonomy );
        if ( $other_term && ! is_wp_error( $other_term ) ) {
            $options[] = array(
                'id'    => $translated_term_id,
                'label' => $other_term->name,
            );
        }
    }
    // Render a lightweight flex layout so the language selector mirrors project style guidance.
    wp_nonce_field( 'wpr_translation_term_language_' . $term->term_id, 'wpr_translation_term_language_nonce' );
    echo '<div class="wpr-translate-term-language-panel">';
    echo '<div class="wpr-translate-term-language">';
    echo '<label for="wpr-translation-term-language"><strong>' . esc_html__( 'Language', 'wpr-translate' ) . '</strong></label>';
    echo '<select id="wpr-translation-term-language" name="wpr_translation_term_language">';
    foreach ( $languages as $language ) {
        $code  = isset( $language['code'] ) ? sanitize_key( $language['code'] ) : '';
        if ( '' === $code ) {
            continue;
        }
        $label = ! empty( $language['name'] ) ? $language['name'] : strtoupper( $code );
        printf( '<option value="%1$s" %2$s>%3$s</option>', esc_attr( $code ), selected( $current_language, $code, false ), esc_html( $label ) );
    }
    echo '</select>';
    echo '</div>';
    echo '<div class="wpr-translate-term-source">';
    echo '<label for="wpr-translation-term-source"><strong>' . esc_html__( 'Source term', 'wpr-translate' ) . '</strong></label>';
    echo '<select id="wpr-translation-term-source" name="wpr_translation_term_source">';
    echo '<option value="0">' . esc_html__( 'None', 'wpr-translate' ) . '</option>';
    foreach ( $options as $option ) {
        printf( '<option value="%1$s" %2$s>%3$s</option>', esc_attr( $option['id'] ), selected( $source_selected, $option['id'], false ), esc_html( $option['label'] ) );
    }
    echo '</select>';
    echo '</div>';
    echo '</div>';
}


