<?php
/**
 * Query helpers for preparing string translation data for admin screens.
 *
 * @package WPR_Translate
 */
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}
require_once WPR_TRANSLATE_PATH . 'includes/admin/string-database.php';
require_once WPR_TRANSLATE_PATH . 'includes/admin/widget-instance-strings.php';
/**
 * Retrieve filters for the string table from the current request.
 *
 * @return array
 */
function wpr_translate_admin_get_strings_filters_from_request() {
    // Read filter values from the request.
    $status = isset( $_GET['status'] ) ? sanitize_key( wp_unslash( $_GET['status'] ) ) : 'all';
    $search = isset( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : '';
    $domain = isset( $_GET['domain'] ) ? sanitize_text_field( wp_unslash( $_GET['domain'] ) ) : '';
    // Normalize the status filter.
    if ( ! in_array( $status, array( 'all', 'translated', 'untranslated' ), true ) ) {
        $status = 'all';
    }
    return array(
        'status' => $status,
        'search' => $search,
        'domain' => $domain,
    );
}
/**
 * Retrieve pagination arguments from the current request.
 *
 * @return array
 */
function wpr_translate_admin_get_strings_pagination_from_request() {
    // Read pagination settings from the request or defaults.
    $page     = isset( $_GET['strings_page'] ) ? (int) $_GET['strings_page'] : 1;
    $per_page = (int) apply_filters( 'wpr_translate_strings_per_page', 20 );
    if ( $page < 1 ) {
        $page = 1;
    }
    if ( $per_page < 1 ) {
        $per_page = 20;
    }
    return array(
        'current_page' => $page,
        'per_page'     => $per_page,
    );
}
/**
 * Fetch strings prepared for the admin view using filters and pagination.
 *
 * @param array $filters    Filters from the request.
 * @param array $pagination Pagination configuration.
 *
 * @return array
 */
function wpr_translate_admin_get_strings_for_view( $filters, $pagination ) {
    global $wpdb;
    // Load language configuration and table name.
    $languages = get_option( 'wpr_translate_languages', array() );
    $table     = $wpdb->prefix . 'wpestate_translation_strings';
    $default_response = array(
        'strings'    => array(),
        '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,
        ),
    );
    $widget_domain = get_option( 'wpr_translate_theme_widget_strings_domain', '' );
    $widget_domain = sanitize_key( (string) $widget_domain );
    if ( '' !== $widget_domain && isset( $filters['domain'] ) && $filters['domain'] === $widget_domain && function_exists( 'wpr_translate_admin_get_widget_instance_strings_for_view' ) ) {
        return wpr_translate_admin_get_widget_instance_strings_for_view( $filters, $pagination );
    }
    // Return an empty response when the table is missing.
    if ( ! wpr_translate_admin_strings_table_exists() ) {
        return $default_response;
    }
    // Build SQL conditions based on filters.
    $conditions = array();
    $values     = array();
    if ( '' !== $filters['search'] ) {
        $like      = '%' . $wpdb->esc_like( $filters['search'] ) . '%';
        // Search both visible text and internal string keys.
        $conditions[] = '(value LIKE %s OR translation LIKE %s OR name LIKE %s)';
        $values[]     = $like;
        $values[]     = $like;
        $values[]     = $like;
    }
    if ( '' !== $filters['domain'] ) {
        $conditions[] = 'context = %s';
        $values[]     = $filters['domain'];
    }
    // Execute the query to fetch raw string rows.
    $sql = "SELECT context, name, value, language_code, translation FROM {$table}";
    if ( ! empty( $conditions ) ) {
        $sql .= ' WHERE ' . implode( ' AND ', $conditions );
    }
    $sql .= ' ORDER BY context ASC, name ASC';
    $rows = empty( $values ) ? $wpdb->get_results( $sql, ARRAY_A ) : $wpdb->get_results( $wpdb->prepare( $sql, $values ), ARRAY_A );
    if ( empty( $rows ) ) {
        $default_response['domains'] = wpr_translate_admin_get_string_domains();
        return $default_response;
    }
    // Group rows by context + name to build translation sets.
    $grouped = array();
    foreach ( $rows as $row ) {
        $key = $row['context'] . '|' . $row['name'];
        if ( ! isset( $grouped[ $key ] ) ) {
            $grouped[ $key ] = array(
                'context'      => $row['context'],
                'domain_label' => wpr_translate_admin_format_domain_label( $row['context'] ),
                'name'         => $row['name'],
                'value'        => $row['value'],
                'translations' => array(),
            );
        }
        $grouped[ $key ]['translations'][ $row['language_code'] ] = $row['translation'];
    }
    // Filter grouped results based on translation status.
    $default_code = wpr_translate_admin_get_default_language_code( $languages );
    $results      = array();
    foreach ( $grouped as $group ) {
        $status = wpr_translate_admin_evaluate_translation_status( $group['translations'], $languages, $default_code );
        if ( 'translated' === $filters['status'] && 'translated' !== $status ) {
            continue;
        }
        if ( 'untranslated' === $filters['status'] && 'untranslated' !== $status ) {
            continue;
        }
        $group['status'] = $status;
        $results[]       = $group;
    }
    $admin_domain = get_option( 'wpr_translate_theme_admin_strings_domain', '' );
    $admin_domain = is_string( $admin_domain ) ? sanitize_key( $admin_domain ) : '';
    if ( '' !== $admin_domain && isset( $filters['domain'] ) && $filters['domain'] === $admin_domain ) {
        usort(
            $results,
            static function ( $left, $right ) {
                $left_key  = isset( $left['name'] ) ? (string) $left['name'] : '';
                $right_key = isset( $right['name'] ) ? (string) $right['name'] : '';
                return strcmp( strtolower( $left_key ), strtolower( $right_key ) );
            }
        );
    }
    // Apply pagination to the result set.
    $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 );
    return array(
        'strings'    => array_values( $items ),
        'domains'    => wpr_translate_admin_get_string_domains(),
        'pagination' => array(
            'current_page' => $current,
            'per_page'     => $per_page,
            'total_pages'  => $total_page,
            'total'        => $total,
        ),
    );
}
/**
 * Retrieve the default language code.
 *
 * @param array $languages Languages list.
 *
 * @return string
 */
function wpr_translate_admin_get_default_language_code( $languages ) {
    // Return early when no languages are defined.
    if ( empty( $languages ) ) {
        return '';
    }
    foreach ( $languages as $language ) {
        if ( isset( $language['is_default'] ) && $language['is_default'] && isset( $language['code'] ) ) {
            return (string) $language['code'];
        }
    }
    // Fall back to the first configured language.
    $first = reset( $languages );
    return isset( $first['code'] ) ? (string) $first['code'] : '';
}
/**
 * Determine translation status for a string.
 *
 * @param array  $translations Map of language => translation.
 * @param array  $languages    Configured languages.
 * @param string $default_code Default language code.
 *
 * @return string
 */
function wpr_translate_admin_evaluate_translation_status( $translations, $languages, $default_code ) {
    // Consider strings translated when no languages exist.
    if ( empty( $languages ) ) {
        return 'translated';
    }
    foreach ( $languages as $language ) {
        if ( ! isset( $language['code'] ) ) {
            continue;
        }
        $code = (string) $language['code'];
        if ( $code === $default_code ) {
            continue;
        }
        // Treat empty translations as untranslated.
        $value = isset( $translations[ $code ] ) ? trim( wp_strip_all_tags( (string) $translations[ $code ] ) ) : '';
        if ( '' === $value ) {
            return 'untranslated';
        }
    }
    return 'translated';
}
/**
 * Retrieve all domains stored in the strings table.
 *
 * @return array
 */
function wpr_translate_admin_get_string_domains() {
    global $wpdb;
    // Return empty when the strings table is missing.
    if ( ! wpr_translate_admin_strings_table_exists() ) {
        return array();
    }
    $table = $wpdb->prefix . 'wpestate_translation_strings';
    // Fetch distinct context values.
    $domains = $wpdb->get_col( "SELECT DISTINCT context FROM {$table} ORDER BY context ASC" );
    if ( empty( $domains ) ) {
        return array();
    }
    // Map contexts to human-readable labels.
    $results = array();
    foreach ( $domains as $context ) {
        $results[ $context ] = wpr_translate_admin_format_domain_label( $context );
    }
    return $results;
}
/**
 * Human readable label for stored context.
 *
 * @param string $context Stored context value.
 *
 * @return string
 */
function wpr_translate_admin_format_domain_label( $context ) {
    // Prefer a generic label for the configured theme widget strings domain.
    $widget_domain = get_option( 'wpr_translate_theme_widget_strings_domain', '' );
    $widget_domain = is_string( $widget_domain ) ? sanitize_key( $widget_domain ) : '';
    if ( '' !== $widget_domain && $context === $widget_domain ) {
        return __( 'Theme Widgets', 'wpr-translate' );
    }
    // Format theme contexts.
    if ( 0 === strpos( $context, 'theme:' ) ) {
        $slug = substr( $context, strlen( 'theme:' ) );
        return sprintf( __( 'Theme: %s', 'wpr-translate' ), ucwords( str_replace( array( '-', '_' ), ' ', $slug ) ) );
    }
    // Format plugin contexts.
    if ( 0 === strpos( $context, 'plugin:' ) ) {
        $slug = substr( $context, strlen( 'plugin:' ) );
        return sprintf( __( 'Plugin: %s', 'wpr-translate' ), ucwords( str_replace( array( '-', '_' ), ' ', $slug ) ) );
    }
    return $context;
}

