<?php
/**
 * Elementor translation application helpers.
 *
 * Applies translated strings, taxonomy terms, and related post IDs back to
 * stored Elementor builder data.
 *
 * @package WPR_Translate
 */

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

/**
 * Resolve taxonomy term IDs from Elementor translation payload entries.
 *
 * @param array  $taxonomy_entry Elementor taxonomy payload entry.
 * @param string $language       Target language code.
 *
 * @return array
 */
function wpr_translate_resolve_elementor_taxonomy_ids( $taxonomy_entry, $language = '' ) {
    // Require a taxonomy name and term payloads to resolve.
    if ( empty( $taxonomy_entry['terms'] ) || ! isset( $taxonomy_entry['taxonomy'] ) ) {
        return array();
    }

    $taxonomy = sanitize_key( $taxonomy_entry['taxonomy'] );
    $language = sanitize_key( $language );

    // Abort when the taxonomy slug is invalid.
    if ( '' === $taxonomy ) {
        return array();
    }

    $term_ids = array();

    foreach ( $taxonomy_entry['terms'] as $term_entry ) {
        // Normalize incoming term data for lookups.
        $term_entry = is_array( $term_entry ) ? $term_entry : array();
        $term_id    = isset( $term_entry['term_id'] ) ? absint( $term_entry['term_id'] ) : 0;
        $term_slug  = isset( $term_entry['slug'] ) ? sanitize_title( (string) $term_entry['slug'] ) : '';
        $term_name  = isset( $term_entry['name'] ) ? sanitize_text_field( (string) $term_entry['name'] ) : '';

        // Prefer exact term IDs when valid.
        if ( $term_id > 0 && taxonomy_exists( $taxonomy ) ) {
            $resolved_term_id = $term_id;

            if ( '' !== $language && function_exists( 'wpr_translate_lookup_translated_term_id_strict' ) ) {
                $translated_term_id = wpr_translate_lookup_translated_term_id_strict( $term_id, $taxonomy, $language );

                if ( $translated_term_id && $translated_term_id > 0 ) {
                    $resolved_term_id = (int) $translated_term_id;
                }
            }

            if ( $resolved_term_id === $term_id && '' !== $language && function_exists( 'wpr_translate_lookup_translated_term_id' ) ) {
                $translated_term_id = wpr_translate_lookup_translated_term_id( $term_id, $taxonomy, $language );

                if ( $translated_term_id && $translated_term_id > 0 ) {
                    $resolved_term_id = (int) $translated_term_id;
                }
            }

            if ( term_exists( $resolved_term_id, $taxonomy ) ) {
                $term_ids[] = $resolved_term_id;
                continue;
            }

            if ( term_exists( $term_id, $taxonomy ) ) {
                $term_ids[] = $term_id;
            }

            continue;
        }

        if ( '' !== $term_slug && taxonomy_exists( $taxonomy ) ) {
            // Fall back to slug lookup.
            $resolved_term_id = 0;

            if ( function_exists( 'wpr_translate_lookup_translated_term_id_by_slug' ) ) {
                $translated_term_id = wpr_translate_lookup_translated_term_id_by_slug( $term_slug, $taxonomy, $language, false );

                if ( is_numeric( $translated_term_id ) ) {
                    $resolved_term_id = absint( $translated_term_id );
                }
            }

            if ( $resolved_term_id > 0 && term_exists( $resolved_term_id, $taxonomy ) ) {
                $source_term = get_term_by( 'slug', $term_slug, $taxonomy );
                $source_id   = ( $source_term instanceof WP_Term ) ? (int) $source_term->term_id : $resolved_term_id;
                $term_ids[] = $resolved_term_id;
                continue;
            }
        }

        if ( '' !== $term_name && taxonomy_exists( $taxonomy ) ) {
            // Fall back to name lookup.
            $resolved_term_id = 0;

            if ( function_exists( 'wpr_translate_lookup_translated_term_id_by_name' ) ) {
                $translated_term_id = wpr_translate_lookup_translated_term_id_by_name( $term_name, $taxonomy, $language, false );

                if ( is_numeric( $translated_term_id ) ) {
                    $resolved_term_id = absint( $translated_term_id );
                }
            }

            if ( $resolved_term_id > 0 && term_exists( $resolved_term_id, $taxonomy ) ) {
                $source_term = get_term_by( 'name', $term_name, $taxonomy );
                $source_id   = ( $source_term instanceof WP_Term ) ? (int) $source_term->term_id : $resolved_term_id;
                $term_ids[] = $resolved_term_id;
            }
        }
    }

    // Return unique, sanitized term IDs.
    return array_values( array_unique( array_filter( array_map( 'absint', $term_ids ) ) ) );
}

/**
 * Resolve taxonomy term slugs from Elementor translation payload entries.
 *
 * @param array  $taxonomy_entry Elementor taxonomy payload entry.
 * @param string $language       Target language code.
 *
 * @return array
 */
function wpr_translate_resolve_elementor_taxonomy_slugs( $taxonomy_entry, $language = '' ) {
    // Require a taxonomy name and term payloads to resolve.
    if ( empty( $taxonomy_entry['terms'] ) || ! isset( $taxonomy_entry['taxonomy'] ) ) {
        return array();
    }

    $taxonomy = sanitize_key( $taxonomy_entry['taxonomy'] );
    $language = sanitize_key( $language );

    // Abort when the taxonomy slug is invalid.
    if ( '' === $taxonomy || ! taxonomy_exists( $taxonomy ) ) {
        return array();
    }

    $term_slugs = array();

    foreach ( $taxonomy_entry['terms'] as $term_entry ) {
        // Normalize incoming term data for lookups.
        $term_entry = is_array( $term_entry ) ? $term_entry : array();
        $term_id    = isset( $term_entry['term_id'] ) ? absint( $term_entry['term_id'] ) : 0;
        $term_slug  = isset( $term_entry['slug'] ) ? sanitize_title( (string) $term_entry['slug'] ) : '';
        $term_name  = isset( $term_entry['name'] ) ? sanitize_text_field( (string) $term_entry['name'] ) : '';
        $resolved_term_id = 0;

        // Prefer exact term IDs when valid.
        if ( $term_id > 0 ) {
            $resolved_term_id = $term_id;

            if ( '' !== $language && function_exists( 'wpr_translate_lookup_translated_term_id_strict' ) ) {
                $translated_term_id = wpr_translate_lookup_translated_term_id_strict( $term_id, $taxonomy, $language );

                if ( $translated_term_id && $translated_term_id > 0 ) {
                    $resolved_term_id = (int) $translated_term_id;
                }
            }

            if ( $resolved_term_id === $term_id && '' !== $language && function_exists( 'wpr_translate_lookup_translated_term_id' ) ) {
                $translated_term_id = wpr_translate_lookup_translated_term_id( $term_id, $taxonomy, $language );

                if ( $translated_term_id && $translated_term_id > 0 ) {
                    $resolved_term_id = (int) $translated_term_id;
                }
            }
        }

        if ( $resolved_term_id <= 0 && '' !== $term_slug && function_exists( 'wpr_translate_lookup_translated_term_id_by_slug' ) ) {
            // Fall back to slug lookup.
            $translated_term_id = wpr_translate_lookup_translated_term_id_by_slug( $term_slug, $taxonomy, $language, false );

            if ( is_numeric( $translated_term_id ) && absint( $translated_term_id ) > 0 ) {
                $resolved_term_id = absint( $translated_term_id );
            }
        }

        if ( $resolved_term_id <= 0 && '' !== $term_name && function_exists( 'wpr_translate_lookup_translated_term_id_by_name' ) ) {
            // Fall back to name lookup.
            $translated_term_id = wpr_translate_lookup_translated_term_id_by_name( $term_name, $taxonomy, $language, false );

            if ( is_numeric( $translated_term_id ) && absint( $translated_term_id ) > 0 ) {
                $resolved_term_id = absint( $translated_term_id );
            }
        }

        if ( $resolved_term_id > 0 ) {
            $resolved_term = get_term( $resolved_term_id, $taxonomy );

            if ( $resolved_term instanceof WP_Term ) {
                $resolved_slug = sanitize_title( $resolved_term->slug );

                if ( '' !== $resolved_slug ) {
                    $term_slugs[] = $resolved_slug;
                    continue;
                }
            }
        }

        // Keep the original slug when no translated mapping exists.
        if ( '' !== $term_slug ) {
            $term_slugs[] = $term_slug;
            continue;
        }

        if ( $term_id > 0 ) {
            $source_term = get_term( $term_id, $taxonomy );

            if ( $source_term instanceof WP_Term ) {
                $source_slug = sanitize_title( $source_term->slug );

                if ( '' !== $source_slug ) {
                    $term_slugs[] = $source_slug;
                }
            }
        }
    }

    return array_values( array_unique( array_filter( array_map( 'sanitize_title', $term_slugs ) ) ) );
}

/**
 * Convert taxonomy term slugs into IDs for debug report compatibility.
 *
 * @param string $taxonomy Taxonomy slug.
 * @param array  $slugs    Resolved slugs.
 *
 * @return array
 */
function wpr_translate_resolve_elementor_taxonomy_ids_from_slugs( $taxonomy, $slugs ) {
    $taxonomy = sanitize_key( $taxonomy );
    $slugs    = is_array( $slugs ) ? $slugs : array();
    $term_ids = array();

    if ( '' === $taxonomy || ! taxonomy_exists( $taxonomy ) ) {
        return array();
    }

    foreach ( $slugs as $slug ) {
        $slug = sanitize_title( (string) $slug );

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

        $term = get_term_by( 'slug', $slug, $taxonomy );

        if ( $term instanceof WP_Term ) {
            $term_ids[] = (int) $term->term_id;
        }
    }

    return array_values( array_unique( array_filter( array_map( 'absint', $term_ids ) ) ) );
}

/**
 * Match a translated Elementor setting to the shape of the original value.
 *
 * Ensures replacements preserve arrays vs. scalars and value types (string or
 * integer) so the translated meta mirrors the source format.
 *
 * @param mixed $original_value Original Elementor setting value.
 * @param mixed $new_value      Translated value ready to apply.
 *
 * @return mixed
 */
function wpr_translate_match_elementor_setting_shape( $original_value, $new_value ) {
    // Preserve array shapes and data types where possible.
    if ( is_array( $original_value ) ) {
        $normalized_value = is_array( $new_value ) ? $new_value : array( $new_value );
        $sample_value     = reset( $original_value );

        // Preserve string vs. integer items when the original array provides a hint.
        if ( is_string( $sample_value ) ) {
            return array_map( 'strval', $normalized_value );
        }

        if ( is_int( $sample_value ) ) {
            return array_map( 'absint', $normalized_value );
        }

        return $normalized_value;
    }

    if ( is_string( $original_value ) ) {
        return is_array( $new_value ) ? (string) reset( $new_value ) : (string) $new_value;
    }

    if ( is_int( $original_value ) ) {
        return is_array( $new_value ) ? absint( reset( $new_value ) ) : absint( $new_value );
    }

    return $new_value;
}

/**
 * Store the last Elementor term replacement report for the current request.
 *
 * @param array $report Report rows collected while applying Elementor data.
 *
 * @return void
 */
function wpr_translate_set_last_elementor_term_report( $report ) {
    $report = is_array( $report ) ? $report : array();

    $GLOBALS['wpr_translate_last_elementor_term_report'] = $report;
}

/**
 * Read the last Elementor term replacement report for the current request.
 *
 * @return array
 */
function wpr_translate_get_last_elementor_term_report() {
    if ( ! isset( $GLOBALS['wpr_translate_last_elementor_term_report'] ) ) {
        return array();
    }

    return is_array( $GLOBALS['wpr_translate_last_elementor_term_report'] ) ? $GLOBALS['wpr_translate_last_elementor_term_report'] : array();
}

/**
 * Normalize Elementor term report terms for debug logging.
 *
 * @param array $terms Raw terms from the report row.
 *
 * @return array
 */
function wpr_translate_normalize_elementor_report_terms_for_log( $terms ) {
    $terms       = is_array( $terms ) ? $terms : array();
    $clean_terms = array();

    foreach ( $terms as $term ) {
        if ( ! is_array( $term ) ) {
            continue;
        }

        $term_id = isset( $term['term_id'] ) ? absint( $term['term_id'] ) : 0;
        $name    = isset( $term['name'] ) ? sanitize_text_field( (string) $term['name'] ) : '';

        if ( $term_id <= 0 && '' === $name ) {
            continue;
        }

        $clean_terms[] = array(
            'term_id' => $term_id,
            'name'    => $name,
        );
    }

    return $clean_terms;
}

/**
 * Write Elementor term read/replace report rows to debug.log.
 *
 * @param int    $post_id      Translated post ID.
 * @param string $language     Target language code.
 * @param array  $term_report  Report rows collected while applying Elementor data.
 *
 * @return void
 */
function wpr_translate_log_elementor_term_report_to_debug_log( $post_id, $language, $term_report ) {
    $post_id     = absint( $post_id );
    $language    = sanitize_text_field( $language );
    $term_report = is_array( $term_report ) ? array_values( $term_report ) : array();

    if ( empty( $term_report ) ) {
        return;
    }

    return;
}

/**
 * Log the Elementor payload that is about to be saved for Wpresidence_Grids.
 *
 * @param int    $post_id       Target post ID.
 * @param string $language      Target language code.
 * @param array  $elementor_data Full Elementor data tree.
 *
 * @return void
 */
function wpr_translate_log_saved_grids_elementor_payload( $post_id, $language, $elementor_data ) {
    $post_id       = absint( $post_id );
    $language      = sanitize_text_field( $language );
    $elementor_data = is_array( $elementor_data ) ? $elementor_data : array();
    $widgets       = array();

    wpr_translate_collect_elementor_widgets_by_type( $elementor_data, 'Wpresidence_Grids', $widgets );

    if ( empty( $widgets ) ) {
        return;
    }

    $payload = array();

    foreach ( $widgets as $widget ) {
        if ( ! is_array( $widget ) ) {
            continue;
        }

        $payload[] = array(
            'id'       => isset( $widget['id'] ) ? sanitize_key( (string) $widget['id'] ) : '',
            'settings' => isset( $widget['settings'] ) && is_array( $widget['settings'] ) ? $widget['settings'] : array(),
        );
    }

    if ( empty( $payload ) ) {
        return;
    }

    // Debug logging intentionally disabled.
    return;
}

/**
 * Collect full Elementor widget nodes by widget type.
 *
 * @param array  $elements    Elementor elements tree.
 * @param string $widget_type Widget type to collect.
 * @param array  $widgets     Accumulator passed by reference.
 *
 * @return void
 */
function wpr_translate_collect_elementor_widgets_by_type( $elements, $widget_type, &$widgets ) {
    $elements    = is_array( $elements ) ? $elements : array();
    $widget_type = sanitize_text_field( $widget_type );
    $widgets     = is_array( $widgets ) ? $widgets : array();

    foreach ( $elements as $element ) {
        if ( ! is_array( $element ) ) {
            continue;
        }

        if ( isset( $element['widgetType'] ) && $widget_type === sanitize_text_field( (string) $element['widgetType'] ) ) {
            $widgets[] = $element;
        }

        if ( isset( $element['elements'] ) && is_array( $element['elements'] ) ) {
            wpr_translate_collect_elementor_widgets_by_type( $element['elements'], $widget_type, $widgets );
        }
    }
}

/**
 * Get full Search Form Builder widget code from Elementor data.
 *
 * @param array $elementor_data Elementor data tree.
 *
 * @return array
 */
function wpr_translate_get_search_form_builder_widgets_from_elementor_data( $elementor_data ) {
    $widgets = array();

    wpr_translate_collect_elementor_widgets_by_type( $elementor_data, 'WpResidence_Search_Form_Builder', $widgets );

    return $widgets;
}

/**
 * Log full original and saved Search Form Builder widget code.
 *
 * @param int    $source_post_id Source/original post ID.
 * @param int    $post_id        Translated post ID.
 * @param string $language       Target language code.
 * @param array  $original       Original widget nodes.
 * @param array  $saved          Saved translated widget nodes.
 *
 * @return void
 */
function wpr_translate_log_search_form_builder_full_code( $source_post_id, $post_id, $language, $original, $saved ) {
    $source_post_id = absint( $source_post_id );
    $post_id        = absint( $post_id );
    $language       = sanitize_text_field( $language );
    $original       = is_array( $original ) ? $original : array();
    $saved          = is_array( $saved ) ? $saved : array();

    return;
}

/**
 * Build report-friendly source terms from an Elementor taxonomy payload.
 *
 * @param array $taxonomy_entry Elementor taxonomy payload entry.
 *
 * @return array
 */
function wpr_translate_build_elementor_report_terms_from_payload( $taxonomy_entry ) {
    if ( empty( $taxonomy_entry['terms'] ) || ! is_array( $taxonomy_entry['terms'] ) ) {
        return array();
    }

    $taxonomy   = isset( $taxonomy_entry['taxonomy'] ) ? sanitize_key( $taxonomy_entry['taxonomy'] ) : '';
    $read_terms = array();

    foreach ( $taxonomy_entry['terms'] as $term_entry ) {
        if ( ! is_array( $term_entry ) ) {
            continue;
        }

        $term_id          = isset( $term_entry['term_id'] ) ? absint( $term_entry['term_id'] ) : 0;
        $original_term_id = $term_id;
        $name             = isset( $term_entry['name'] ) ? sanitize_text_field( (string) $term_entry['name'] ) : '';
        $slug             = isset( $term_entry['slug'] ) ? sanitize_title( (string) $term_entry['slug'] ) : '';

        if (
            $term_id > 0
            && '' !== $taxonomy
            && taxonomy_exists( $taxonomy )
            && function_exists( 'wpr_translate_resolve_original_term_id' )
        ) {
            $resolved_original_id = absint( wpr_translate_resolve_original_term_id( $term_id, $taxonomy ) );

            if ( $resolved_original_id > 0 ) {
                $original_term_id = $resolved_original_id;
            }
        }

        if ( $original_term_id > 0 && '' !== $taxonomy && taxonomy_exists( $taxonomy ) ) {
            $term_object = get_term( $original_term_id, $taxonomy );

            if ( $term_object instanceof WP_Term ) {
                $name = sanitize_text_field( (string) $term_object->name );
                $slug = sanitize_title( (string) $term_object->slug );
            }
        }

        if ( '' === $name && '' !== $slug ) {
            $name = $slug;
        }

        if ( '' === $name && $term_id <= 0 ) {
            continue;
        }

        $read_terms[] = array(
            'term_id' => $original_term_id > 0 ? $original_term_id : $term_id,
            'slug'    => $slug,
            'name'    => $name,
        );
    }

    return $read_terms;
}

/**
 * Build report-friendly translated terms from resolved IDs.
 *
 * @param string $taxonomy Taxonomy slug.
 * @param array  $term_ids Resolved term IDs.
 *
 * @return array
 */
function wpr_translate_build_elementor_report_terms_from_ids( $taxonomy, $term_ids ) {
    $taxonomy      = sanitize_key( $taxonomy );
    $term_ids      = is_array( $term_ids ) ? $term_ids : array();
    $replaced_terms = array();

    foreach ( array_values( array_unique( array_map( 'absint', $term_ids ) ) ) as $term_id ) {
        if ( $term_id <= 0 ) {
            continue;
        }

        $name = '#' . $term_id;
        $slug = '';

        if ( '' !== $taxonomy && taxonomy_exists( $taxonomy ) ) {
            $term_object = get_term( $term_id, $taxonomy );

            if ( $term_object instanceof WP_Term ) {
                $name = sanitize_text_field( (string) $term_object->name );
                $slug = sanitize_title( (string) $term_object->slug );
            }
        }

        $replaced_terms[] = array(
            'term_id' => $term_id,
            'slug'    => $slug,
            'name'    => $name,
        );
    }

    return $replaced_terms;
}

/**
 * Collect one Elementor taxonomy replacement row for the debug report.
 *
 * @param array  $term_report    Report rows accumulator passed by reference.
 * @param string $widget_type    Elementor widget type.
 * @param string $element_id     Elementor element ID.
 * @param string $field_name     Elementor setting name.
 * @param array  $taxonomy_entry Elementor taxonomy payload entry.
 * @param array  $resolved_ids   Resolved term IDs used as replacements.
 *
 * @return void
 */
function wpr_translate_collect_elementor_term_report_entry( &$term_report, $widget_type, $element_id, $field_name, $taxonomy_entry, $resolved_ids ) {
    $taxonomy = isset( $taxonomy_entry['taxonomy'] ) ? sanitize_key( $taxonomy_entry['taxonomy'] ) : '';

    if ( '' === $taxonomy ) {
        return;
    }

    $read_terms = wpr_translate_build_elementor_report_terms_from_payload( $taxonomy_entry );

    if ( empty( $read_terms ) ) {
        return;
    }

    $report_key = md5( $widget_type . '|' . $element_id . '|' . $field_name );

    $term_report[ $report_key ] = array(
        'widget_type'    => sanitize_text_field( (string) $widget_type ),
        'element_id'     => sanitize_key( (string) $element_id ),
        'field_name'     => sanitize_key( (string) $field_name ),
        'taxonomy'       => $taxonomy,
        'read_terms'     => $read_terms,
        'replaced_terms' => wpr_translate_build_elementor_report_terms_from_ids( $taxonomy, $resolved_ids ),
    );
}

/**
 * Recursively update Elementor elements with translated widget data.
 *
 * @param array $elements            Elementor element tree passed by reference.
 * @param array $config              Widget configuration map.
 * @param array $elementor_translate  Translated widget payload.
 * @param string $language           Target language slug.
 * @param array  $term_report        Elementor term report rows passed by reference.
 */
function wpr_translate_apply_elementor_widget_translations( &$elements, $config, $elementor_translate, $language, &$term_report = array() ) {
    foreach ( $elements as &$element ) {
        // Traverse nested elements before applying updates on the current node.
        if ( isset( $element['elements'] ) && is_array( $element['elements'] ) ) {
            // Update nested elements before applying settings on the current node.
            wpr_translate_apply_elementor_widget_translations( $element['elements'], $config, $elementor_translate, $language, $term_report );
        }

        if ( ! isset( $element['widgetType'] ) ) {
            continue;
        }

        $widget_type = sanitize_text_field( (string) $element['widgetType'] );
        $element_id  = isset( $element['id'] ) ? sanitize_key( (string) $element['id'] ) : '';

        if ( '' === $widget_type || '' === $element_id ) {
            continue;
        }

        $settings = isset( $element['settings'] ) && is_array( $element['settings'] ) ? $element['settings'] : array();

        if (
            'WpResidence_Search_Form_Builder' === $widget_type
            && isset( $elementor_translate['taxonomies'][ $widget_type ][ $element_id ] )
            && is_array( $elementor_translate['taxonomies'][ $widget_type ][ $element_id ] )
        ) {
            // Apply translated taxonomy selections for the Search Form Builder even if the widget config is missing.
            foreach ( $elementor_translate['taxonomies'][ $widget_type ][ $element_id ] as $field_name => $taxonomy_payload ) {
                if ( ! isset( $element['settings'][ $field_name ] ) ) {
                    continue;
                }

                $payload_type = isset( $taxonomy_payload['type'] ) ? sanitize_key( (string) $taxonomy_payload['type'] ) : 'taxonomy';

                if ( 'taxonomy_slug' === $payload_type ) {
                    $term_slugs = wpr_translate_resolve_elementor_taxonomy_slugs( $taxonomy_payload, $language );
                    $taxonomy   = isset( $taxonomy_payload['taxonomy'] ) ? sanitize_key( $taxonomy_payload['taxonomy'] ) : '';
                    $report_ids = wpr_translate_resolve_elementor_taxonomy_ids_from_slugs( $taxonomy, $term_slugs );
                    wpr_translate_collect_elementor_term_report_entry( $term_report, $widget_type, $element_id, $field_name, $taxonomy_payload, $report_ids );

                    if ( ! empty( $term_slugs ) ) {
                        $element['settings'][ $field_name ] = wpr_translate_match_elementor_setting_shape( $element['settings'][ $field_name ], $term_slugs );
                    }
                    continue;
                }

                $term_ids = wpr_translate_resolve_elementor_taxonomy_ids( $taxonomy_payload, $language );
                wpr_translate_collect_elementor_term_report_entry( $term_report, $widget_type, $element_id, $field_name, $taxonomy_payload, $term_ids );

                if ( ! empty( $term_ids ) ) {
                    $element['settings'][ $field_name ] = wpr_translate_match_elementor_setting_shape( $element['settings'][ $field_name ], $term_ids );
                }
            }
        }

        if (
            'WpResidence_Search_Form_Builder' === $widget_type
            && isset( $elementor_translate['translated_strings'][ $widget_type ][ $element_id ] )
            && is_array( $elementor_translate['translated_strings'][ $widget_type ][ $element_id ] )
        ) {
            // Apply translated strings for the Search Form Builder even if the widget config is missing.
            $translated_strings = $elementor_translate['translated_strings'][ $widget_type ][ $element_id ];

            if ( isset( $translated_strings['form_fields'] ) && isset( $element['settings']['form_fields'] ) ) {
                foreach ( $translated_strings['form_fields'] as $index => $item ) {
                    if ( ! isset( $element['settings']['form_fields'][ $index ] ) || ! is_array( $item ) ) {
                        continue;
                    }

                    if ( isset( $item['field_label'] ) ) {
                        $element['settings']['form_fields'][ $index ]['field_label'] = wp_kses_post( (string) $item['field_label'] );
                    }

                    if ( isset( $item['placeholder'] ) ) {
                        $element['settings']['form_fields'][ $index ]['placeholder'] = wp_kses_post( (string) $item['placeholder'] );
                    }
                }
            }

            foreach ( array( 'form_field_section_title_text', 'submit_button_text' ) as $field_key ) {
                if ( isset( $translated_strings[ $field_key ] ) && isset( $element['settings'][ $field_key ] ) ) {
                    $element['settings'][ $field_key ] = wpr_translate_match_elementor_setting_shape(
                        $element['settings'][ $field_key ],
                        wp_kses_post( (string) $translated_strings[ $field_key ] )
                    );
                }
            }
        }

        if (
            'WpResidence_Search_Form_Builder' === $widget_type
            && isset( $element['settings']['tabs_field'], $element['settings']['form_fields'] )
            && is_array( $element['settings']['form_fields'] )
            && '' !== $language
        ) {
            // Translate tab holder term IDs so fields render under the correct tabs.
            $taxonomy = sanitize_key( $element['settings']['tabs_field'] );

            $sample_tab_holders = array();
            foreach ( $element['settings']['form_fields'] as $sample_item ) {
                if ( isset( $sample_item['tab_holder'] ) ) {
                    $sample_tab_holders[] = $sample_item['tab_holder'];
                }

                if ( count( $sample_tab_holders ) >= 5 ) {
                    break;
                }
            }
            // Map tab holder values to the translated tab term IDs when possible.
            $tab_terms_map = array(
                'property_action_category' => 'action_data',
                'property_category'        => 'category_data',
                'property_city'            => 'city_data',
                'property_area'            => 'area_data',
                'property_county_state'    => 'county_data',
                'property_status'          => 'status_data',
            );

            $tab_terms = array();
            $tab_field = isset( $tab_terms_map[ $taxonomy ] ) ? $tab_terms_map[ $taxonomy ] : '';

            if ( '' !== $tab_field && isset( $element['settings'][ $tab_field ] ) ) {
                $tab_values = $element['settings'][ $tab_field ];

                if ( is_string( $tab_values ) ) {
                    $decoded = json_decode( $tab_values, true );
                    if ( is_array( $decoded ) ) {
                        $tab_values = $decoded;
                    }
                }

                if ( ! is_array( $tab_values ) ) {
                    $tab_values = array( $tab_values );
                }

                $tab_terms = array_values( array_filter( array_map( 'absint', $tab_values ) ) );
            }

                $tab_holder_order = array();
                foreach ( $element['settings']['form_fields'] as $item ) {
                    if ( ! is_array( $item ) || ! isset( $item['tab_holder'] ) ) {
                        continue;
                    }

                    if ( ! is_numeric( $item['tab_holder'] ) ) {
                        continue;
                    }

                    $tab_value = absint( $item['tab_holder'] );

                    if ( $tab_value > 0 && ! in_array( $tab_value, $tab_holder_order, true ) ) {
                        $tab_holder_order[] = $tab_value;
                    }
                }

                $tab_holder_map = array();
                if ( ! empty( $tab_terms ) && count( $tab_terms ) === count( $tab_holder_order ) ) {
                    $tab_holder_map = array_combine( $tab_holder_order, $tab_terms );
                }

            foreach ( $element['settings']['form_fields'] as $index => $item ) {
                if ( ! is_array( $item ) || ! isset( $item['tab_holder'] ) ) {
                    continue;
                }

                    $tab_holder = $item['tab_holder'];

                    if ( ! is_numeric( $tab_holder ) ) {
                        continue;
                    }

                    $tab_holder = absint( $tab_holder );

                if ( $tab_holder <= 0 ) {
                    continue;
                }

                $translated_id = $tab_holder;

                if ( '' !== $taxonomy && taxonomy_exists( $taxonomy ) ) {
                    if ( function_exists( 'wpr_translate_lookup_translated_term_id_strict' ) ) {
                        $resolved = wpr_translate_lookup_translated_term_id_strict( $tab_holder, $taxonomy, $language );

                        if ( $resolved && $resolved !== $tab_holder ) {
                            $translated_id = (int) $resolved;
                        }
                    }

                    if ( $translated_id === $tab_holder && function_exists( 'wpr_translate_lookup_translated_term_id' ) ) {
                        $resolved = wpr_translate_lookup_translated_term_id( $tab_holder, $taxonomy, $language );

                        if ( $resolved && $resolved !== $tab_holder ) {
                            $translated_id = (int) $resolved;
                        }
                    }
                }

                if ( $translated_id === $tab_holder && isset( $tab_holder_map[ $tab_holder ] ) ) {
                    $translated_id = (int) $tab_holder_map[ $tab_holder ];
                }

                if ( $translated_id !== $tab_holder ) {
                    $element['settings']['form_fields'][ $index ]['tab_holder'] = $translated_id;
                }
            }
        }

        if ( ! isset( $config[ $widget_type ] ) ) {
            continue;
        }

        foreach ( $config[ $widget_type ] as $field_config ) {
            if ( ! is_array( $field_config ) ) {
                continue;
            }

            foreach ( $field_config as $field_name => $field_rules ) {
                // Skip fields that do not exist on the current element.
                if ( ! isset( $element['settings'][ $field_name ] ) ) {
                    continue;
                }

                $field_rules = is_array( $field_rules ) ? $field_rules : array();
                $field_type  = isset( $field_rules['type'] ) ? sanitize_key( $field_rules['type'] ) : 'text';

                if ( in_array( $field_type, array( 'taxonomy', 'taxonomy_slug' ), true ) ) {
                    if ( isset( $elementor_translate['taxonomies'][ $widget_type ][ $element_id ][ $field_name ] ) ) {
                        // Apply translated taxonomy selections.
                        $taxonomy_payload = $elementor_translate['taxonomies'][ $widget_type ][ $element_id ][ $field_name ];
                        $payload_type     = isset( $taxonomy_payload['type'] ) ? sanitize_key( (string) $taxonomy_payload['type'] ) : 'taxonomy';

                        if ( 'taxonomy_slug' === $payload_type ) {
                            $term_slugs = wpr_translate_resolve_elementor_taxonomy_slugs( $taxonomy_payload, $language );
                            $taxonomy   = isset( $taxonomy_payload['taxonomy'] ) ? sanitize_key( $taxonomy_payload['taxonomy'] ) : '';
                            $report_ids = wpr_translate_resolve_elementor_taxonomy_ids_from_slugs( $taxonomy, $term_slugs );
                            wpr_translate_collect_elementor_term_report_entry( $term_report, $widget_type, $element_id, $field_name, $taxonomy_payload, $report_ids );

                            if ( ! empty( $term_slugs ) ) {
                                $element['settings'][ $field_name ] = wpr_translate_match_elementor_setting_shape( $element['settings'][ $field_name ], $term_slugs );
                            }
                        } else {
                            $term_ids = wpr_translate_resolve_elementor_taxonomy_ids( $taxonomy_payload, $language );
                            wpr_translate_collect_elementor_term_report_entry( $term_report, $widget_type, $element_id, $field_name, $taxonomy_payload, $term_ids );

                            if ( ! empty( $term_ids ) ) {
                                $element['settings'][ $field_name ] = wpr_translate_match_elementor_setting_shape( $element['settings'][ $field_name ], $term_ids );
                            }
                        }
                    }

                    // Never let taxonomy fields fall through to string replacements.
                    continue;
                }

                if ( in_array( $field_type, array( 'id', 'post_id' ), true ) && isset( $elementor_translate['translated_post_id'][ $widget_type ][ $element_id ][ $field_name ] ) ) {
                    // Apply translated post ID references.
                    $translated_ids = $elementor_translate['translated_post_id'][ $widget_type ][ $element_id ][ $field_name ];
                    $ids_to_apply   = array();

                    if ( isset( $translated_ids['translated_values'] ) && is_array( $translated_ids['translated_values'] ) ) {
                        $ids_to_apply = array_filter( array_map( 'absint', $translated_ids['translated_values'] ) );
                    }

                    if ( empty( $ids_to_apply ) && isset( $translated_ids['original'] ) && is_array( $translated_ids['original'] ) ) {
                        $ids_to_apply = array_filter( array_map( 'absint', $translated_ids['original'] ) );
                    }

                    if ( ! empty( $ids_to_apply ) ) {
                        $element['settings'][ $field_name ] = wpr_translate_match_elementor_setting_shape( $element['settings'][ $field_name ], $ids_to_apply );
                    }

                    continue;
                }

                if ( isset( $elementor_translate['translated_strings'][ $widget_type ][ $element_id ][ $field_name ] ) ) {
                    // Apply translated string content.
                    if (
                        'WpResidence_Search_Form_Builder' === $widget_type
                        && 'form_fields' === $field_name
                        && isset( $element['settings'][ $field_name ] )
                        && is_array( $element['settings'][ $field_name ] )
                        && is_array( $elementor_translate['translated_strings'][ $widget_type ][ $element_id ][ $field_name ] )
                    ) {
                        // Apply translated labels/placeholders inside repeater items.
                        foreach ( $elementor_translate['translated_strings'][ $widget_type ][ $element_id ][ $field_name ] as $index => $item ) {
                            if ( ! isset( $element['settings'][ $field_name ][ $index ] ) || ! is_array( $item ) ) {
                                continue;
                            }

                            if ( isset( $item['field_label'] ) ) {
                                $element['settings'][ $field_name ][ $index ]['field_label'] = wp_kses_post( (string) $item['field_label'] );
                            }

                            if ( isset( $item['placeholder'] ) ) {
                                $element['settings'][ $field_name ][ $index ]['placeholder'] = wp_kses_post( (string) $item['placeholder'] );
                            }
                        }
                    } else {
                        $element['settings'][ $field_name ] = wpr_translate_match_elementor_setting_shape(
                            $element['settings'][ $field_name ],
                            wp_kses_post( $elementor_translate['translated_strings'][ $widget_type ][ $element_id ][ $field_name ] )
                        );
                    }
                }
            }
        }
    }
}

/**
 * Apply translated Elementor widget fields to the translated post meta.
 *
 * @param int    $post_id            Translated post ID.
 * @param array  $translated_payload Payload returned by the translation engine.
 * @param string $target_language    Target language slug.
 */
function wpr_translate_apply_elementor_translations( $post_id, $translated_payload, $target_language ) {
    // Reset per-request report before applying new Elementor changes.
    wpr_translate_set_last_elementor_term_report( array() );

    // Ensure Elementor translation payload exists.
    if ( empty( $translated_payload['elementor_translate'] ) || ! is_array( $translated_payload['elementor_translate'] ) ) {
        return;
    }


    // Resolve source/original post first so re-translation starts from a clean source base.
    $source_post_id                = isset( $translated_payload['_wpr_source_post_id'] ) ? absint( $translated_payload['_wpr_source_post_id'] ) : 0;
    $original_search_form_builders = array();
    $source_elementor_data         = array();

    if ( $source_post_id > 0 ) {
        $source_raw_elementor_data = get_post_meta( $source_post_id, '_elementor_data', true );
        $source_elementor_data     = wpr_translate_decode_elementor_data( $source_raw_elementor_data );

        if ( ! empty( $source_elementor_data ) && is_array( $source_elementor_data ) ) {
            $original_search_form_builders = wpr_translate_get_search_form_builder_widgets_from_elementor_data( $source_elementor_data );
        }
    }

    // Load translated post Elementor data and replace with source data when available.
    $raw_elementor_data = get_post_meta( $post_id, '_elementor_data', true );
    $elementor_data     = wpr_translate_decode_elementor_data( $raw_elementor_data );

    if ( ! empty( $source_elementor_data ) && is_array( $source_elementor_data ) ) {
        $elementor_data = $source_elementor_data;
    }

    if ( empty( $elementor_data ) ) {
        return;
    }

    // Load the widget field configuration used for translation.
    $config = wpr_translate_load_translatable_elementor_widget_fields();

    if ( empty( $config ) ) {
        return;
    }


    // Mutate the builder payload with translated strings, taxonomy terms, and related posts.
    $term_report = array();
    wpr_translate_apply_elementor_widget_translations( $elementor_data, $config, $translated_payload['elementor_translate'], $target_language, $term_report );
    wpr_translate_set_last_elementor_term_report( array_values( $term_report ) );
    wpr_translate_log_elementor_term_report_to_debug_log( $post_id, $target_language, $term_report );

    // Ensure Search Form Builder tabs keep field tab holders aligned with translated tab terms.
    $tab_terms_map = array(
        'property_action_category' => 'action_data',
        'property_category'        => 'category_data',
        'property_city'            => 'city_data',
        'property_area'            => 'area_data',
        'property_county_state'    => 'county_data',
        'property_status'          => 'status_data',
    );

    $tab_holder_remap = function ( &$elements ) use ( &$tab_holder_remap, $tab_terms_map ) {
        foreach ( $elements as &$elementor_element ) {
            if ( isset( $elementor_element['elements'] ) && is_array( $elementor_element['elements'] ) ) {
                $tab_holder_remap( $elementor_element['elements'] );
            }

            if ( ! isset( $elementor_element['widgetType'] ) || 'WpResidence_Search_Form_Builder' !== $elementor_element['widgetType'] ) {
                continue;
            }

            $widget_id = isset( $elementor_element['id'] ) ? sanitize_key( (string) $elementor_element['id'] ) : '';

            if ( ! isset( $elementor_element['settings']['form_fields'] ) ) {
                continue;
            }

            $form_fields_raw      = $elementor_element['settings']['form_fields'];
            $form_fields          = $form_fields_raw;
            $form_fields_encoded  = false;

            if ( is_string( $form_fields ) ) {
                $decoded = json_decode( $form_fields, true );
                if ( is_array( $decoded ) ) {
                    $form_fields         = $decoded;
                    $form_fields_encoded = true;
                }
            }

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

            $field_snapshot = array();
            foreach ( $form_fields as $index => $item ) {
                if ( ! is_array( $item ) ) {
                    continue;
                }
                $field_snapshot[] = array(
                    'index'      => $index,
                    'field_type' => isset( $item['field_type'] ) ? sanitize_text_field( (string) $item['field_type'] ) : '',
                    'tab_holder' => isset( $item['tab_holder'] ) ? $item['tab_holder'] : '',
                );
            }
            $taxonomy  = isset( $elementor_element['settings']['tabs_field'] ) ? sanitize_key( $elementor_element['settings']['tabs_field'] ) : '';

            if ( '' === $taxonomy ) {
                foreach ( $tab_terms_map as $taxonomy_key => $field_key ) {
                    if ( ! isset( $elementor_element['settings'][ $field_key ] ) ) {
                        continue;
                    }

                    $field_value = $elementor_element['settings'][ $field_key ];

                    if ( is_array( $field_value ) && empty( $field_value ) ) {
                        continue;
                    }

                    if ( is_string( $field_value ) && '' === trim( $field_value ) ) {
                        continue;
                    }

                    $taxonomy = $taxonomy_key;
                    $elementor_element['settings']['tabs_field'] = $taxonomy;
                    break;
                }
            }

            $tab_field = isset( $tab_terms_map[ $taxonomy ] ) ? $tab_terms_map[ $taxonomy ] : '';

            if ( '' === $tab_field || ! isset( $elementor_element['settings'][ $tab_field ] ) ) {
                $fallback_field   = '';
                $fallback_taxonomy = '';

                foreach ( $tab_terms_map as $taxonomy_key => $field_key ) {
                    if ( isset( $elementor_element['settings'][ $field_key ] ) && '' !== $elementor_element['settings'][ $field_key ] ) {
                        $fallback_field    = $field_key;
                        $fallback_taxonomy = $taxonomy_key;
                        break;
                    }
                }

                if ( '' !== $fallback_field ) {
                    $taxonomy  = $fallback_taxonomy;
                    $tab_field = $fallback_field;
                } else {
                    continue;
                }
            }

            $tab_values = $elementor_element['settings'][ $tab_field ];

            if ( is_string( $tab_values ) ) {
                $decoded = json_decode( $tab_values, true );
                if ( is_array( $decoded ) ) {
                    $tab_values = $decoded;
                }
            }

            if ( ! is_array( $tab_values ) ) {
                $tab_values = array( $tab_values );
            }

            $tab_terms = array_values( array_filter( array_map( 'absint', $tab_values ) ) );
            $tab_holder_order = array();
            foreach ( $form_fields as $item ) {
                if ( ! is_array( $item ) || ! isset( $item['tab_holder'] ) || ! is_numeric( $item['tab_holder'] ) ) {
                    continue;
                }

                $tab_value = absint( $item['tab_holder'] );
                if ( $tab_value > 0 && ! in_array( $tab_value, $tab_holder_order, true ) ) {
                    $tab_holder_order[] = $tab_value;
                }
            }
            if ( empty( $tab_terms ) || count( $tab_terms ) !== count( $tab_holder_order ) ) {
                continue;
            }

            $tab_holder_map = array_combine( $tab_holder_order, $tab_terms );

            foreach ( $form_fields as $index => $item ) {
                if ( ! is_array( $item ) || ! isset( $item['tab_holder'] ) || ! is_numeric( $item['tab_holder'] ) ) {
                    continue;
                }

                $tab_holder = absint( $item['tab_holder'] );

                if ( isset( $tab_holder_map[ $tab_holder ] ) ) {
                    $form_fields[ $index ]['tab_holder'] = (int) $tab_holder_map[ $tab_holder ];
                }
            }
            $updated_holders = array();
            $field_snapshot_after = array();
            foreach ( $form_fields as $item ) {
                if ( isset( $item['tab_holder'] ) ) {
                    $updated_holders[] = $item['tab_holder'];
                }
                if ( is_array( $item ) ) {
                    $field_snapshot_after[] = array(
                        'field_type' => isset( $item['field_type'] ) ? sanitize_text_field( (string) $item['field_type'] ) : '',
                        'tab_holder' => isset( $item['tab_holder'] ) ? $item['tab_holder'] : '',
                    );
                }
            }
            if ( $form_fields_encoded ) {
                $elementor_element['settings']['form_fields'] = wp_json_encode( $form_fields, JSON_UNESCAPED_UNICODE );
            } else {
                $elementor_element['settings']['form_fields'] = $form_fields;
            }
        }
    };

    $tab_holder_remap( $elementor_data );
    unset( $elementor_element );


    // Log full original code and full saved code for Search Form Builder widgets.
    $saved_search_form_builders = wpr_translate_get_search_form_builder_widgets_from_elementor_data( $elementor_data );
    wpr_translate_log_search_form_builder_full_code(
        $source_post_id,
        $post_id,
        $target_language,
        $original_search_form_builders,
        $saved_search_form_builders
    );

    // Persist the updated Elementor data to post meta.
    $encoded_elementor_data = wp_json_encode( $elementor_data, JSON_UNESCAPED_UNICODE );

    if ( false !== $encoded_elementor_data && null !== $encoded_elementor_data ) {
        // Log only Wpresidence_Grids data that is about to be saved.
        wpr_translate_log_saved_grids_elementor_payload( $post_id, $target_language, $elementor_data );
        // Store slashed JSON so wp_unslash() in meta APIs does not break escaped quotes.
        update_post_meta( $post_id, '_elementor_data', wp_slash( $encoded_elementor_data ) );

        // Verify the stored JSON after write to catch any persistence corruption early.
        $saved_elementor_data = maybe_unserialize( get_post_meta( $post_id, '_elementor_data', true ) );

        if ( is_string( $saved_elementor_data ) ) {
            json_decode( $saved_elementor_data, true );

            if ( JSON_ERROR_NONE !== json_last_error() ) {
                error_log( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
                    '[WPR Translate][ElementorSave][invalid_json_after_save] ' . print_r(
                        array(
                            'post_id'      => $post_id,
                            'language'     => $target_language,
                            'json_error'   => json_last_error_msg(),
                            'stored_bytes' => strlen( $saved_elementor_data ),
                        ),
                        true
                    )
                );
            }
        }
    }
}
