<?php
/**
 * Helper utilities for theme admin string translation.
 *
 * @package WPR_Translate
 */

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

/**
 * Expand wildcard theme admin strings based on current option values.
 *
 * @param array  $flattened Flattened string paths.
 * @param string $domain    Option name for the theme settings.
 *
 * @return array
 */
function wpr_translate_admin_expand_theme_admin_wildcards( $flattened, $domain ) {
    if ( empty( $flattened ) || '' === $domain ) {
        return $flattened;
    }

    // Pull the stored theme options so wildcard entries can be expanded.
    $options = get_option( $domain, array() );

    if ( ! is_array( $options ) ) {
        return $flattened;
    }

    $expanded = array();

    foreach ( $flattened as $path => $value ) {
        if ( false === strpos( $path, '.*' ) ) {
            // Preserve non-wildcard entries as-is.
            $expanded[ $path ] = $value;
            continue;
        }

        // Resolve the array path that owns the wildcard entries.
        $base_path = substr( (string) $path, 0, -2 );

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

        // Retrieve the current option values to expand into concrete paths.
        $target = wpr_translate_admin_get_option_value_by_path( $options, $base_path, true );

        if ( ! is_array( $target ) && 'wpestate_set_search.adv_search_label' === $base_path && isset( $options['wp_estate_adv_search_label'] ) ) {
            // Fall back to the legacy flat option when the grouped path is missing.
            $target = $options['wp_estate_adv_search_label'];
        }

        if ( ! is_array( $target ) ) {
            continue;
        }

        foreach ( $target as $key => $item ) {
            if ( is_array( $item ) ) {
                continue;
            }

            // Store each scalar entry as its own string key.
            $expanded[ $base_path . '.' . $key ] = (string) $item;
        }
    }

    return $expanded;
}

/**
 * Set a nested option value when the path exists.
 *
 * @param array  $target Option array to update.
 * @param string $path   Dot-separated key path.
 * @param string $value  Value to assign.
 */
function wpr_translate_admin_set_option_value_by_path( &$target, $path, $value ) {
    // Validate inputs before updating.
    if ( ! is_array( $target ) || '' === $path ) {
        return;
    }

    $segments = explode( '.', $path );
    $current  =& $target;

    foreach ( $segments as $segment ) {
        // Walk the nested array by path segments.
        if ( ! is_array( $current ) || ! array_key_exists( $segment, $current ) ) {
            return;
        }

        $current =& $current[ $segment ];
    }

    // Do not replace arrays with string values.
    if ( is_array( $current ) ) {
        return;
    }

    // Sanitize and set the translated value.
    $current = wp_kses_post( $value );
}

/**
 * Get a nested option value by path.
 *
 * @param array  $target Option array to read.
 * @param string $path   Dot-separated key path.
 *
 * @return string|array
 */
function wpr_translate_admin_get_option_value_by_path( $target, $path, $allow_array = false ) {
    // Return empty when the path is invalid.
    if ( ! is_array( $target ) || '' === $path ) {
        return '';
    }

    $segments = explode( '.', $path );
    $current  = $target;

    foreach ( $segments as $segment ) {
        // Walk the nested array until the final segment.
        if ( ! is_array( $current ) || ! array_key_exists( $segment, $current ) ) {
            return '';
        }

        $current = $current[ $segment ];
    }

    if ( is_array( $current ) ) {
        return $allow_array ? $current : '';
    }

    return (string) $current;
}

/**
 * Count how many strings exist for a given domain.
 *
 * @param string $domain Domain key.
 *
 * @return int
 */
function wpr_translate_admin_count_strings_for_domain( $domain ) {
    global $wpdb;

    // Return early when domain is missing or table is unavailable.
    if ( '' === $domain || ! function_exists( 'wpr_translate_admin_strings_table_exists' ) ) {
        return 0;
    }

    if ( ! wpr_translate_admin_strings_table_exists() ) {
        return 0;
    }

    $table = $wpdb->prefix . 'wpestate_translation_strings';

    // Count rows that match the domain.
    return (int) $wpdb->get_var(
        $wpdb->prepare(
            "SELECT COUNT(*) FROM {$table} WHERE context = %s",
            sanitize_key( $domain )
        )
    );
}

/**
 * Count how many strings exist for a domain and a list of names.
 *
 * @param string $domain Domain key.
 * @param array  $names  String names to count.
 *
 * @return int
 */
function wpr_translate_admin_count_strings_for_domain_names( $domain, $names ) {
    global $wpdb;

    if ( '' === $domain || empty( $names ) || ! is_array( $names ) ) {
        return 0;
    }

    if ( ! function_exists( 'wpr_translate_admin_strings_table_exists' ) || ! wpr_translate_admin_strings_table_exists() ) {
        return 0;
    }

    $table = $wpdb->prefix . 'wpestate_translation_strings';
    $count = 0;

    foreach ( array_chunk( $names, 50 ) as $chunk ) {
        $placeholders = implode( ',', array_fill( 0, count( $chunk ), '%s' ) );
        $params       = array_merge( array( $domain ), $chunk );
        // Count unique string names only; per-language rows would otherwise
        // inflate the total and hide newly added wildcard entries.
        $sql          = "SELECT COUNT(DISTINCT name) FROM {$table} WHERE context = %s AND name IN ({$placeholders})";
        $prepared     = $wpdb->prepare( $sql, $params );

        if ( $prepared ) {
            $count += (int) $wpdb->get_var( $prepared );
        }
    }

    return $count;
}
