<?php
/**
 * Language switcher displayed in the WordPress admin bar.
 *
 * Provides a user-scoped language toggle that filters admin content without
 * altering the admin UI language.
 *
 * @package WPR_Translate
 */

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

/**
 * Register the admin bar language switcher hooks.
 */
function wpr_translate_bootstrap_admin_bar_language_switcher() {
    // Persist the requested language early during the admin request lifecycle.
    add_action( 'admin_init', 'wpr_translate_handle_admin_language_switch' );

    // Inject the language dropdown into the admin bar for eligible users.
    add_action( 'admin_bar_menu', 'wpr_translate_register_admin_bar_language_switcher', 90 );
}

/**
 * Determine the current user's selected admin language code.
 *
 * @return string Selected language code or an empty string when no preference exists.
 */
function wpr_translate_get_admin_selected_language_code() {
    if ( ! is_user_logged_in() ) {
        // Only logged-in users can have preferences.
        return '';
    }

    // Load stored user preference.
    $language_code = get_user_meta( get_current_user_id(), 'wpr_translate_admin_language', true );

    if ( ! is_string( $language_code ) || '' === $language_code ) {
        // No preference stored.
        return '';
    }

    // Sanitize and validate against active languages.
    $language_code = sanitize_key( $language_code );
    $languages     = wpr_translation_get_active_languages();
    $valid_codes   = wp_list_pluck( $languages, 'code' );

    if ( ! in_array( $language_code, $valid_codes, true ) ) {
        return '';
    }

    return $language_code;
}

/**
 * Build a nonce-protected URL that records the desired admin language.
 *
 * @param string $language_code Target language code.
 *
 * @return string URL pointing to the current admin page with switch parameters.
 */
function wpr_translate_get_admin_language_switch_url( $language_code ) {
    // Normalize the requested language code.
    $language_code = sanitize_key( $language_code );

    $current_url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';

    if ( '' === $current_url ) {
        // Fall back to the admin home when the current URL is empty.
        $current_url = admin_url();
    }

    // Add switch parameters to the current URL.
    $switch_url = add_query_arg(
        array(
            'wpr_translate_admin_language' => $language_code,
        ),
        $current_url
    );

    return wp_nonce_url( $switch_url, 'wpr_translate_switch_admin_language' );
}

/**
 * Handle incoming language switch requests from the admin bar dropdown.
 */
function wpr_translate_handle_admin_language_switch() {
    if ( ! is_admin() || ! isset( $_GET['wpr_translate_admin_language'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        // Only handle explicit switch requests in admin.
        return;
    }

    if ( ! current_user_can( 'edit_posts' ) ) {
        // Require edit permission for language switch.
        return;
    }

    if ( ! wp_verify_nonce( wp_unslash( $_GET['_wpnonce'] ?? '' ), 'wpr_translate_switch_admin_language' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        // Invalid nonce; abort.
        return;
    }

    $language_code = sanitize_key( wp_unslash( $_GET['wpr_translate_admin_language'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
    $languages     = wpr_translation_get_active_languages();
    $valid_codes   = wp_list_pluck( $languages, 'code' );

    if ( '' !== $language_code && in_array( $language_code, $valid_codes, true ) ) {
        // Store the selected language.
        update_user_meta( get_current_user_id(), 'wpr_translate_admin_language', $language_code );
    } else {
        // Clear the preference when invalid or empty.
        delete_user_meta( get_current_user_id(), 'wpr_translate_admin_language' );
    }

    $redirect_url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';

    if ( '' === $redirect_url ) {
        // Fallback to the admin home URL.
        $redirect_url = admin_url();
    }

    // Remove switch parameters before redirecting.
    $redirect_url = remove_query_arg( array( 'wpr_translate_admin_language', '_wpnonce' ), $redirect_url );

    wp_safe_redirect( $redirect_url );
    exit;
}

/**
 * Add the language selector to the WordPress admin bar.
 *
 * @param WP_Admin_Bar $wp_admin_bar Admin bar instance.
 */
function wpr_translate_register_admin_bar_language_switcher( $wp_admin_bar ) {
    if ( ! is_admin() || ! $wp_admin_bar instanceof WP_Admin_Bar ) {
        // Only run for valid admin bar instances.
        return;
    }

    if ( ! current_user_can( 'edit_posts' ) || ! is_admin_bar_showing() ) {
        // Respect permissions and admin bar visibility.
        return;
    }

    $languages = wpr_translation_get_active_languages();

    if ( count( $languages ) < 2 ) {
        // No switcher needed for a single language.
        return;
    }

    $current_code = wpr_translate_get_admin_selected_language_code();

    if ( '' === $current_code ) {
        // Fall back to the default language.
        $current_code = wpr_translation_get_default_language_code( $languages );
    }

    $current_label = $current_code;

    foreach ( $languages as $language ) {
        if ( isset( $language['code'] ) && strtolower( $language['code'] ) === strtolower( $current_code ) ) {
            // Use the current language name as the label.
            $current_label = ! empty( $language['name'] ) ? $language['name'] : $current_code;
            break;
        }
    }

    $wp_admin_bar->add_node(
        array(
            'id'    => 'wpr-translate-admin-language',
            'title' => esc_html( sprintf( __( 'Content language: %s', 'wpr-translate' ), $current_label ) ),
            'href'  => false,
            'meta'  => array(
                'class' => 'wpr-translate-admin-language',
                'title' => esc_attr__( 'Switch the language of translated content in admin screens.', 'wpr-translate' ),
            ),
        )
    );

    foreach ( $languages as $language ) {
        $code  = isset( $language['code'] ) ? sanitize_key( $language['code'] ) : '';
        $label = isset( $language['name'] ) && '' !== $language['name'] ? $language['name'] : $code;

        if ( '' === $code ) {
            // Skip invalid language entries.
            continue;
        }

        $wp_admin_bar->add_node(
            array(
                'id'     => 'wpr-translate-admin-language-' . $code,
                'parent' => 'wpr-translate-admin-language',
                'title'  => esc_html( $label ),
                'href'   => wpr_translate_get_admin_language_switch_url( $code ),
                'meta'   => array(
                    'class' => $code === $current_code ? 'wpr-translate-admin-language-current' : 'wpr-translate-admin-language-option',
                ),
            )
        );
    }
}
