<?php
/**
 * Widget instance string helpers for the Strings admin screen.
 * @package WPR_Translate
 */
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}
require_once WPR_TRANSLATE_PATH . 'includes/admin/string-storage.php';
/**
 * Collect widget instances assigned to active sidebars.
 * @return array<int, array> Widget instance payloads.
 */
function wpr_translate_admin_collect_active_widget_instances() {
    $sidebars = wp_get_sidebars_widgets();
    if ( ! is_array( $sidebars ) ) {
        return array();
    }
    $instances      = array();
    $options_cache  = array();
    $inactive_keys  = array( 'wp_inactive_widgets', 'array_version' );
    // Walk active sidebars and capture assigned widgets.
    foreach ( $sidebars as $sidebar_id => $widget_ids ) {
        if ( in_array( $sidebar_id, $inactive_keys, true ) ) {
            continue;
        }
        if ( empty( $widget_ids ) || ! is_array( $widget_ids ) ) {
            continue;
        }
        foreach ( $widget_ids as $widget_id ) {
            $widget_id = sanitize_text_field( (string) $widget_id );
            if ( '' === $widget_id ) {
                continue;
            }
            if ( ! preg_match( '/^(.+)-(\d+)$/', $widget_id, $matches ) ) {
                continue;
            }
            $id_base = sanitize_key( $matches[1] );
            $number  = absint( $matches[2] );
            if ( '' === $id_base || 0 === $number ) {
                continue;
            }
            if ( ! isset( $options_cache[ $id_base ] ) ) {
                $options_cache[ $id_base ] = get_option( 'widget_' . $id_base, array() );
            }
            $widget_options = $options_cache[ $id_base ];
            if ( ! is_array( $widget_options ) || ! isset( $widget_options[ $number ] ) || ! is_array( $widget_options[ $number ] ) ) {
                continue;
            }
            $instances[] = array( 'id' => $widget_id, 'id_base' => $id_base, 'number' => $number, 'sidebar_id' => sanitize_key( (string) $sidebar_id ), 'instance' => $widget_options[ $number ] );
        }
    }
    return $instances;
}
/**
 * Extract translatable widget fields from widget instances.
 * @param array<int, array> $instances Widget instance payloads.
 * @return array{values:array<string,string>,sidebars:array<string,string>} Map of widget strings and sidebar IDs.
 */
function wpr_translate_admin_extract_widget_instance_strings( $instances ) {
    // Limit extraction to translatable widget fields.
    $strings        = array();
    $sidebar_map    = array();
    $allowed_fields = array( 'title', 'text', 'content' );
    foreach ( $instances as $instance_data ) {
        $widget_id  = isset( $instance_data['id'] ) ? sanitize_key( (string) $instance_data['id'] ) : '';
        $sidebar_id = isset( $instance_data['sidebar_id'] ) ? sanitize_key( (string) $instance_data['sidebar_id'] ) : '';
        $instance   = isset( $instance_data['instance'] ) && is_array( $instance_data['instance'] ) ? $instance_data['instance'] : array();
        if ( '' === $widget_id || '' === $sidebar_id || empty( $instance ) ) {
            continue;
        }
        foreach ( $allowed_fields as $field ) {
            if ( ! array_key_exists( $field, $instance ) ) {
                continue;
            }
            $value = $instance[ $field ];
            if ( is_array( $value ) || is_object( $value ) ) {
                continue;
            }
            $clean_value = wp_kses_post( (string) $value );
            if ( '' === trim( wp_strip_all_tags( $clean_value ) ) ) {
                continue;
            }
            $path = wpr_translate_admin_normalize_widget_string_path( $widget_id . '.' . $field );
            if ( '' === $path ) {
                continue;
            }
            $strings[ $path ] = $clean_value;
            $sidebar_map[ $path ] = $sidebar_id;
        }
        $taxonomy = isset( $instance['taxonomy'] ) ? sanitize_key( (string) $instance['taxonomy'] ) : '';
        if ( '' !== $taxonomy && taxonomy_exists( $taxonomy ) ) {
            $term_fields = array( 'term_id', 'term_ids', 'terms', 'include', 'exclude', 'category', 'categories' );
            foreach ( $term_fields as $field ) {
                if ( ! array_key_exists( $field, $instance ) ) {
                    continue;
                }
                $term_values = $instance[ $field ];
                $term_values = is_array( $term_values ) ? $term_values : explode( ',', (string) $term_values );
                $term_ids    = array_filter( array_map( 'absint', $term_values ) );
                foreach ( $term_ids as $term_id ) {
                    $term = get_term( $term_id, $taxonomy );
                    if ( ! ( $term instanceof WP_Term ) ) {
                        continue;
                    }
                    $path = wpr_translate_admin_normalize_widget_string_path( $widget_id . '.term.' . $taxonomy . '.' . $term_id );
                    if ( '' === $path ) {
                        continue;
                    }
                    $strings[ $path ] = wp_kses_post( (string) $term->name );
                    $sidebar_map[ $path ] = $sidebar_id;
                }
            }
        }
        if ( isset( $instance_data['id_base'] ) && 'nav_menu' === $instance_data['id_base'] && isset( $instance['nav_menu'] ) ) {
            $menu_id = absint( $instance['nav_menu'] );
            if ( $menu_id ) {
                $menu = get_term( $menu_id, 'nav_menu' );
                if ( $menu instanceof WP_Term ) {
                    $path = wpr_translate_admin_normalize_widget_string_path( $widget_id . '.term.nav_menu.' . $menu_id );
                    if ( '' !== $path ) {
                        $strings[ $path ] = wp_kses_post( (string) $menu->name );
                        $sidebar_map[ $path ] = $sidebar_id;
                    }
                }
            }
        }
    }
    ksort( $strings );
    return array(
        'values'   => $strings,
        'sidebars' => $sidebar_map,
    );
}
/**
 * Load existing translations for a set of widget strings.
 * @param string   $domain         Widget strings domain.
 * @param string[] $names          Widget string names.
 * @param string[] $language_codes Active language codes.
 * @return array<string, array<string, string>> Translation map.
 */
function wpr_translate_admin_get_widget_instance_translations( $domain, $names, $language_codes ) {
    global $wpdb;
    $translations = array();
    $domain       = sanitize_key( $domain );
    if ( '' === $domain || empty( $names ) || empty( $language_codes ) ) {
        return $translations;
    }
    if ( ! wpr_translate_admin_strings_table_exists() ) {
        return $translations;
    }
    $table = $wpdb->prefix . 'wpestate_translation_strings';
    foreach ( array_chunk( $names, 50 ) as $chunk ) {
        $name_placeholders     = implode( ',', array_fill( 0, count( $chunk ), '%s' ) );
        $language_placeholders = implode( ',', array_fill( 0, count( $language_codes ), '%s' ) );
        $sql                   = "SELECT name, language_code, translation FROM {$table} WHERE context = %s AND name IN ({$name_placeholders}) AND language_code IN ({$language_placeholders})";
        $prepared              = $wpdb->prepare( $sql, array_merge( array( $domain ), $chunk, $language_codes ) );
        $rows                  = $wpdb->get_results( $prepared, ARRAY_A );
        foreach ( $rows as $row ) {
            $name        = isset( $row['name'] ) ? (string) $row['name'] : '';
            $language    = isset( $row['language_code'] ) ? (string) $row['language_code'] : '';
            $translation = isset( $row['translation'] ) ? (string) $row['translation'] : '';
            if ( '' === $name || '' === $language ) {
                continue;
            }
            if ( ! isset( $translations[ $name ] ) ) {
                $translations[ $name ] = array();
            }
            $translations[ $name ][ $language ] = $translation;
        }
    }
    return $translations;
}
/**
 * Build widget instance strings for the Strings admin view.
 * @param array $filters    Filters from the request.
 * @param array $pagination Pagination configuration.
 * @return array
 */
function wpr_translate_admin_get_widget_instance_strings_for_view( $filters, $pagination ) {
    $languages = get_option( 'wpr_translate_languages', array() );
    $domain    = get_option( 'wpr_translate_theme_widget_strings_domain', '' );
    $domain    = sanitize_key( (string) $domain );
    $default_response = array(
        'strings'    => array(),
        'domains'    => function_exists( 'wpr_translate_admin_get_string_domains' ) ? wpr_translate_admin_get_string_domains() : array(),
        'pagination' => array( 'current_page' => isset( $pagination['current_page'] ) ? max( 1, (int) $pagination['current_page'] ) : 1, 'per_page' => isset( $pagination['per_page'] ) ? max( 1, (int) $pagination['per_page'] ) : 20, 'total_pages' => 1, 'total' => 0 ),
    );
    if ( '' === $domain || empty( $languages ) || ! wpr_translate_admin_strings_table_exists() ) {
        return $default_response;
    }
    $instances   = wpr_translate_admin_collect_active_widget_instances();
    $widget_data = wpr_translate_admin_extract_widget_instance_strings( $instances );
    $strings     = isset( $widget_data['values'] ) && is_array( $widget_data['values'] ) ? $widget_data['values'] : array();
    $sidebar_map = isset( $widget_data['sidebars'] ) && is_array( $widget_data['sidebars'] ) ? $widget_data['sidebars'] : array();
    if ( empty( $strings ) ) {
        return $default_response;
    }
    // Resolve sidebar IDs to labels for UI display.
    $sidebar_labels = array();
    if ( isset( $GLOBALS['wp_registered_sidebars'] ) && is_array( $GLOBALS['wp_registered_sidebars'] ) ) {
        foreach ( $GLOBALS['wp_registered_sidebars'] as $sidebar_id => $sidebar_data ) {
            $label = isset( $sidebar_data['name'] ) ? (string) $sidebar_data['name'] : '';
            $sidebar_labels[ sanitize_key( (string) $sidebar_id ) ] = '' === $label ? sanitize_key( (string) $sidebar_id ) : sanitize_text_field( $label );
        }
    }
    $language_codes = array();
    foreach ( $languages as $language ) {
        if ( isset( $language['code'] ) && '' !== $language['code'] ) {
            $language_codes[] = (string) $language['code'];
        }
    }
    if ( empty( $language_codes ) ) {
        return $default_response;
    }
    $existing_translations = wpr_translate_admin_get_widget_instance_translations( $domain, array_keys( $strings ), $language_codes );
    $default_code          = function_exists( 'wpr_translate_admin_get_default_language_code' ) ? wpr_translate_admin_get_default_language_code( $languages ) : '';
    $storage_payload       = array();
    foreach ( $strings as $name => $value ) {
        $hash_key               = md5( $domain . '|' . $name );
        $storage_payload[ $hash_key ] = array(
            'context'      => $domain,
            'name'         => $name,
            'value'        => $value,
            'md5'          => md5( $value ),
            'translations' => isset( $existing_translations[ $name ] ) ? $existing_translations[ $name ] : array(),
        );
    }
    wpr_translate_admin_persist_detected_strings( $storage_payload, $languages, $default_code );
    $results      = array();
    $search_term  = isset( $filters['search'] ) ? strtolower( (string) $filters['search'] ) : '';
    $status_filter = isset( $filters['status'] ) ? (string) $filters['status'] : 'all';
    foreach ( $strings as $name => $value ) {
        $translations = isset( $existing_translations[ $name ] ) ? $existing_translations[ $name ] : array();
        if ( '' !== $search_term ) {
            $matches = false;
            $source  = strtolower( wp_strip_all_tags( (string) $value ) );
            if ( false !== strpos( $source, $search_term ) ) {
                $matches = true;
            } else {
                foreach ( $translations as $translation_value ) {
                    $candidate = strtolower( wp_strip_all_tags( (string) $translation_value ) );
                    if ( '' !== $candidate && false !== strpos( $candidate, $search_term ) ) {
                        $matches = true;
                        break;
                    }
                }
            }
            if ( ! $matches ) {
                continue;
            }
        }
        $status = function_exists( 'wpr_translate_admin_evaluate_translation_status' )
            ? wpr_translate_admin_evaluate_translation_status( $translations, $languages, $default_code )
            : 'untranslated';
        if ( 'translated' === $status_filter && 'translated' !== $status ) {
            continue;
        }
        if ( 'untranslated' === $status_filter && 'untranslated' !== $status ) {
            continue;
        }
        $sidebar_id    = isset( $sidebar_map[ $name ] ) ? sanitize_key( (string) $sidebar_map[ $name ] ) : '';
        $sidebar_label = '';
        if ( '' !== $sidebar_id ) {
            $sidebar_label = isset( $sidebar_labels[ $sidebar_id ] ) ? $sidebar_labels[ $sidebar_id ] : $sidebar_id;
        }
        $results[] = array(
            'context'      => $domain,
            'domain_label' => function_exists( 'wpr_translate_admin_format_domain_label' ) ? wpr_translate_admin_format_domain_label( $domain ) : $domain,
            'name'         => $name,
            'value'        => $value,
            'sidebar_label' => $sidebar_label,
            'translations' => $translations,
            'status'       => $status,
        );
    }
    $per_page   = isset( $pagination['per_page'] ) ? max( 1, (int) $pagination['per_page'] ) : 20;
    $total      = count( $results );
    $total_page = max( 1, (int) ceil( $total / $per_page ) );
    $current    = isset( $pagination['current_page'] ) ? max( 1, (int) $pagination['current_page'] ) : 1;
    if ( $current > $total_page ) {
        $current = $total_page;
    }
    $offset = ( $current - 1 ) * $per_page;
    $items  = array_slice( $results, $offset, $per_page );
    $domains = function_exists( 'wpr_translate_admin_get_string_domains' ) ? wpr_translate_admin_get_string_domains() : array();
    if ( ! isset( $domains[ $domain ] ) ) {
        $domains[ $domain ] = function_exists( 'wpr_translate_admin_format_domain_label' ) ? wpr_translate_admin_format_domain_label( $domain ) : $domain;
    }
    return array(
        'strings'    => array_values( $items ),
        'domains'    => $domains,
        'pagination' => array( 'current_page' => $current, 'per_page' => $per_page, 'total_pages' => $total_page, 'total' => $total ),
    );
}


