<?php
/**
 * Theme widget string helpers and runtime filters.
 *
 * @package WPR_Translate
 */
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}
/**
 * Normalize widget string paths so they match sanitized widget identifiers.
 *
 * @param string $path Original path.
 *
 * @return string
 */
function wpr_translate_admin_normalize_widget_string_path( $path ) {
    if ( '' === $path ) {
        // Empty paths cannot be normalized.
        return '';
    }
    $segments = explode( '.', $path );
    $cleaned  = array();
    foreach ( $segments as $index => $segment ) {
        $value = is_string( $segment ) ? $segment : '';
        if ( '' === $value ) {
            // Invalid path segment means the path is unusable.
            return '';
        }
        // Sanitize each segment to match widget identifiers.
        $cleaned[] = ( 0 === $index ) ? sanitize_key( $value ) : sanitize_key( $value );
    }
    return implode( '.', $cleaned );
}
/**
 * Retrieve translated widget strings for the active language.
 *
 * @param string $language_code Optional language code override.
 *
 * @return array
 */
function wpr_translate_widget_get_translation_map( $language_code = '' ) {
    static $cache = array();
    // Normalize the provided language code.
    $language_code = strtolower( sanitize_key( $language_code ) );
    if ( '' === $language_code && function_exists( 'wpr_translate_get_active_language_code' ) ) {
        // Use the active language code by default.
        $language_code = wpr_translate_get_active_language_code();
    }
    if ( '' === $language_code && function_exists( 'wpr_translate_return_current_language_admin' ) ) {
        // Fall back to the admin-selected language when present.
        $language_code = wpr_translate_return_current_language_admin();
    }
    $language_code = strtolower( sanitize_key( $language_code ) );
    if ( '' === $language_code ) {
        // No language means no translation map.
        return array();
    }
    $default_code = '';
    if ( function_exists( 'wpr_translation_get_active_languages' ) && function_exists( 'wpr_translation_get_default_language_code' ) ) {
        $languages    = wpr_translation_get_active_languages();
        $default_code = strtolower( sanitize_key( wpr_translation_get_default_language_code( $languages ) ) );
    }
    if ( '' !== $default_code && $language_code === $default_code ) {
        // Default language does not need widget translations.
        $cache[ $language_code ] = array();
        return $cache[ $language_code ];
    }
    if ( isset( $cache[ $language_code ] ) ) {
        // Return cached translations for this language.
        return $cache[ $language_code ];
    }
    global $wpdb;
    $table  = $wpdb->prefix . 'wpestate_translation_strings';
    $exists = ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) ) === $table );
    if ( ! $exists ) {
        // Skip when the strings table does not exist.
        $cache[ $language_code ] = array();
        return $cache[ $language_code ];
    }
    $domain = get_option( 'wpr_translate_theme_widget_strings_domain', '' );
    $domain = sanitize_key( $domain );
    if ( '' === $domain ) {
        // Widget translations are disabled when no domain is configured.
        $cache[ $language_code ] = array();
        return $cache[ $language_code ];
    }
    $rows = $wpdb->get_results(
        $wpdb->prepare(
            "SELECT name, translation FROM {$table} WHERE context = %s AND language_code = %s",
            $domain,
            $language_code
        ),
        ARRAY_A
    );
    $translations = array();
    foreach ( $rows as $row ) {
        $name        = isset( $row['name'] ) ? (string) $row['name'] : '';
        $translation = isset( $row['translation'] ) ? (string) $row['translation'] : '';
        $clean_name  = wpr_translate_admin_normalize_widget_string_path( $name );
        $clean_value = trim( wp_strip_all_tags( $translation ) );
        if ( '' === $clean_name || '' === $clean_value ) {
            // Skip empty or invalid translations.
            continue;
        }
        // Store the translation keyed by normalized path.
        $translations[ $clean_name ] = $translation;
    }
    // Cache the translation map for this language.
    $cache[ $language_code ] = $translations;
    return $translations;
}
/**
 * Apply widget translations to an instance payload.
 *
 * @param array  $instance     Original widget instance.
 * @param string $widget_key   Sanitized widget key.
 * @param array  $translations Translation map keyed by normalized paths.
 *
 * @return array
 */
function wpr_translate_widget_apply_translations_to_instance( $instance, $widget_key, $translations ) {
    if ( ! is_array( $instance ) || '' === $widget_key || empty( $translations ) ) {
        // No work needed when inputs are missing.
        return $instance;
    }
    foreach ( $translations as $path => $translation ) {
        $segments = explode( '.', $path );
        if ( count( $segments ) < 2 ) {
            // Paths must include widget and field segments.
            continue;
        }
        $path_widget = array_shift( $segments );
        if ( $path_widget !== $widget_key ) {
            // Skip translations for other widgets.
            continue;
        }
        $relative_path = implode( '.', $segments );
        if ( '' === $relative_path ) {
            continue;
        }
        wpr_translate_widget_set_value_by_path( $instance, $relative_path, $translation );
    }
    return $instance;
}
/**
 * Check if the translation map includes entries for a widget key.
 *
 * @param array  $translations Translation map keyed by path.
 * @param string $widget_key   Widget identifier.
 *
 * @return bool
 */
function wpr_translate_widget_has_translations_for_widget( $translations, $widget_key ) {
    if ( empty( $translations ) || '' === $widget_key ) {
        return false;
    }
    foreach ( $translations as $path => $value ) {
        if ( 0 === strpos( (string) $path, $widget_key . '.' ) ) {
            return true;
        }
    }
    return false;
}
/**
 * Set a nested widget value when the path exists.
 *
 * @param array  $target Target instance array passed by reference.
 * @param string $path   Dot-delimited path inside the instance.
 * @param string $value  Translation to apply.
 */
function wpr_translate_widget_set_value_by_path( &$target, $path, $value ) {
    if ( ! is_array( $target ) || '' === $path ) {
        // Invalid target or path.
        return;
    }
    $segments = explode( '.', $path );
    $current  =& $target;
    foreach ( $segments as $segment ) {
        if ( ! is_array( $current ) || ! array_key_exists( $segment, $current ) ) {
            // Path does not exist in the instance.
            return;
        }
        $current =& $current[ $segment ];
    }
    if ( is_array( $current ) ) {
        // Do not overwrite nested arrays.
        return;
    }
    $clean_value = wp_kses_post( $value );
    if ( '' === trim( wp_strip_all_tags( $clean_value ) ) ) {
        // Skip empty translations.
        return;
    }
    // Apply the translated value.
    $current = $clean_value;
}
/**
 * Filter widget instances before they render so translations are applied.
 *
 * @param array      $instance Current widget settings.
 * @param WP_Widget  $widget   Widget object.
 * @param array      $args     Display arguments.
 *
 * @return array
 */
function wpr_translate_widget_filter_widget_instance( $instance, $widget, $args ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
    $widget_id   = '';
    $widget_base = '';
    if ( is_object( $widget ) && isset( $widget->id ) ) {
        // Use the widget instance ID when available.
        $widget_id = sanitize_key( (string) $widget->id );
    }
    if ( is_object( $widget ) && isset( $widget->id_base ) ) {
        // Capture the widget base ID as a fallback.
        $widget_base = sanitize_key( (string) $widget->id_base );
    }
    if ( '' === $widget_id && '' === $widget_base ) {
        // No widget key means no translation.
        return $instance;
    }
    $translations = wpr_translate_widget_get_translation_map();
    if ( empty( $translations ) ) {
        // No translations to apply.
        return $instance;
    }
    if ( '' !== $widget_id && wpr_translate_widget_has_translations_for_widget( $translations, $widget_id ) ) {
        return wpr_translate_widget_apply_translations_to_instance( $instance, $widget_id, $translations );
    }
    if ( '' !== $widget_base ) {
        return wpr_translate_widget_apply_translations_to_instance( $instance, $widget_base, $translations );
    }
    return $instance;
}
/**
 * Filter widget titles to swap translated values when available.
 *
 * @param string     $title    Current widget title.
 * @param array      $instance Widget instance data.
 * @param string     $id_base  Widget identifier.
 *
 * @return string
 */
function wpr_translate_widget_filter_widget_title( $title, $instance = array(), $id_base = '' ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
    // Normalize the widget identifier.
    $widget_key = sanitize_key( (string) $id_base );
    if ( '' === $widget_key ) {
        // No widget key means no translation.
        return $title;
    }
    $translations = wpr_translate_widget_get_translation_map();
    if ( empty( $translations ) ) {
        // No translations available.
        return $title;
    }
    $path = $widget_key . '.title';
    if ( isset( $translations[ $path ] ) && '' !== trim( wp_strip_all_tags( $translations[ $path ] ) ) ) {
        // Return the translated title when available.
        return $translations[ $path ];
    }
    return $title;
}
/**
 * Register the widget translation filters when translations exist.
 */
function wpr_translate_bootstrap_theme_widget_strings() {
    // Check the configured widget strings domain.
    $domain = get_option( 'wpr_translate_theme_widget_strings_domain', '' );
    if ( '' === $domain ) {
        // No domain means no widget strings to translate.
        return;
    }
    // Attach widget translation filters.
    add_filter( 'widget_display_callback', 'wpr_translate_widget_filter_widget_instance', 10, 3 );
    add_filter( 'widget_title', 'wpr_translate_widget_filter_widget_title', 10, 3 );
}

