<?php
/**
 * Custom field translation helpers used by post list actions.
 *
 * @package WPR_Translate
 */

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

/**
 * Clones all meta fields from the source post to the new post.
 *
 * @param int $source_post_id Source post ID.
 * @param int $new_post_id    New post ID.
 */
function wpr_translation_clone_meta_fields( $source_post_id, $new_post_id ) {
    // Load all meta fields from the source post.
    $meta = get_post_meta( $source_post_id );

    if ( empty( $meta ) ) {
        // No meta fields to clone.
        return;
    }

    $settings          = get_option( 'wpr_translate_settings', array() );
    $sync_media        = ! empty( $settings['sync_media'] );
    $attachment_fields = array(
        '_thumbnail_id',
        'wpestate_property_gallery',
        'property_gallery',
    );

    $preferences       = wpr_translation_get_cached_custom_field_preferences();
    $copy_once_tracker = wpr_translation_get_copy_once_tracker( $new_post_id );

    $single_value_keys = array(
        'wpestate_property_gallery',
        'property_agent',
    );
    $builder_meta_keys = array(
        '_elementor_data',
        '_elementor_edit_mode',
        '_elementor_version',
        '_elementor_template_type',
        '_elementor_css',
        '_elementor_page_assets',
        '_wpb_vc_js_status',
        '_wpb_shortcodes_custom_css',
        '_wpb_post_custom_css',
        '_vc_post_settings',
    );

    foreach ( $meta as $meta_key => $values ) {
        if ( in_array( $meta_key, array( '_edit_lock', '_edit_last', '_wpr_cf_copied_once' ), true ) ) {
            continue;
        }

        if ( ! $sync_media && in_array( $meta_key, $attachment_fields, true ) ) {
            // Skip copying attachment-related metadata when media synchronization is disabled.
            continue;
        }

        $rule = wpr_translation_resolve_custom_field_rule( $meta_key, $preferences );

        if ( in_array( $meta_key, $builder_meta_keys, true ) ) {
            // Always copy builder payloads so translation clones preserve layouts.
            $rule = 'copy';
        }

        if ( 'ignore' === $rule ) {
            // Skip ignored fields.
            continue;
        }

        if ( 'copy-once' === $rule && wpr_translation_copy_once_has_marker( $copy_once_tracker, $meta_key ) ) {
            // Skip fields already copied once.
            continue;
        }

        if ( 'translate' === $rule ) {
            // Seed empty placeholders for translated fields.
            wpr_translation_prepare_translate_placeholder( $new_post_id, $meta_key, $values, $single_value_keys );
            continue;
        }

        $unserialized_values = array_map( 'maybe_unserialize', $values );
        $mark_copy_once      = ( 'copy-once' === $rule );

        if ( in_array( $meta_key, $single_value_keys, true ) ) {
            $value = reset( $unserialized_values );

            if ( false === $value ) {
                // Remove meta when no value exists.
                delete_post_meta( $new_post_id, $meta_key );

                if ( $mark_copy_once ) {
                    $copy_once_tracker = wpr_translation_mark_copy_once_key( $new_post_id, $copy_once_tracker, $meta_key );
                }

                continue;
            }

            update_post_meta( $new_post_id, $meta_key, $value );
        } else {
            // Replace meta values for multi-value fields.
            delete_post_meta( $new_post_id, $meta_key );

            if ( empty( $unserialized_values ) ) {
                if ( $mark_copy_once ) {
                    $copy_once_tracker = wpr_translation_mark_copy_once_key( $new_post_id, $copy_once_tracker, $meta_key );
                }

                continue;
            }

            foreach ( $unserialized_values as $value ) {
                // Add each meta value to the target post.
                add_post_meta( $new_post_id, $meta_key, $value );
            }
        }

        if ( $mark_copy_once ) {
            // Track copy-once fields to avoid repeated updates.
            $copy_once_tracker = wpr_translation_mark_copy_once_key( $new_post_id, $copy_once_tracker, $meta_key );
        }
    }

}

/**
 * Retrieve cached custom field translation preferences.
 *
 * @return array<string, string>
 */
function wpr_translation_get_cached_custom_field_preferences() {
    // Build preferences from custom field rules.
    $preferences = array();

    if ( function_exists( 'wpr_translate_get_custom_field_rules' ) ) {
        $rules = wpr_translate_get_custom_field_rules();

        foreach ( $rules as $rule_id => $rule ) {
            $meta_key = '';

            if ( is_string( $rule_id ) ) {
                $meta_key = $rule_id;
            }

            if ( is_array( $rule ) ) {
                // Extract meta key and action from rule arrays.
                if ( '' === $meta_key && isset( $rule['id'] ) && is_string( $rule['id'] ) ) {
                    $meta_key = $rule['id'];
                }

                if ( isset( $rule['action'] ) ) {
                    $action = $rule['action'];
                } elseif ( isset( $rule['file_action'] ) ) {
                    $action = $rule['file_action'];
                } else {
                    $action = '';
                }
            } else {
                $action = $rule;
            }

            $action   = is_string( $action ) ? $action : '';
            $meta_key = sanitize_key( $meta_key );

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

            $preferences[ $meta_key ] = $action;
        }
    }

    $preferences = apply_filters( 'wpr_translation_custom_field_preferences', $preferences );

    if ( ! is_array( $preferences ) ) {
        // Ensure preferences is always an array.
        $preferences = array();
    }

    $normalized = array();

    foreach ( $preferences as $meta_key => $rule ) {
        if ( ! is_string( $meta_key ) || '' === $meta_key ) {
            continue;
        }

        // Normalize rule values.
        $normalized[ $meta_key ] = wpr_translation_normalize_custom_field_rule( $rule );
    }

    return $normalized;
}

/**
 * Normalize a custom field rule value.
 *
 * @param mixed $rule Raw rule value.
 *
 * @return string
 */
function wpr_translation_normalize_custom_field_rule( $rule ) {
    // Normalize rule values to a supported keyword.
    $rule = is_string( $rule ) ? strtolower( $rule ) : '';

    if ( in_array( $rule, array( 'copy', 'copy-once', 'translate', 'ignore' ), true ) ) {
        return $rule;
    }

    return 'copy';
}

/**
 * Resolve the custom field rule for a given meta key.
 *
 * @param string               $meta_key    Meta key.
 * @param array<string,string> $preferences Cached preferences.
 *
 * @return string
 */
function wpr_translation_resolve_custom_field_rule( $meta_key, $preferences ) {
    // Use stored rule when available; default to copy when missing.
    $rule = isset( $preferences[ $meta_key ] ) ? $preferences[ $meta_key ] : 'copy';

    return apply_filters( 'wpr_translation_custom_field_rule', $rule, $meta_key, $preferences );
}

/**
 * Prepare placeholders for fields marked as translate.
 *
 * @param int               $post_id           Post ID receiving the placeholders.
 * @param string            $meta_key          Meta key being prepared.
 * @param array<int,string> $values            Source meta values.
 * @param array<int,string> $single_value_keys Keys that must be stored as single values.
 */
function wpr_translation_prepare_translate_placeholder( $post_id, $meta_key, $values, $single_value_keys ) {
    if ( in_array( $meta_key, $single_value_keys, true ) ) {
        // Store a single empty value for scalar fields.
        update_post_meta( $post_id, $meta_key, '' );
        return;
    }

    // Remove existing meta entries to replace with placeholders.
    delete_post_meta( $post_id, $meta_key );

    $count = count( $values );

    if ( $count < 1 ) {
        $count = 1;
    }

    // Add empty placeholders to match the source count.
    for ( $index = 0; $index < $count; $index++ ) {
        add_post_meta( $post_id, $meta_key, '' );
    }
}

/**
 * Retrieve the copy-once tracker for a post.
 *
 * @param int $post_id Post ID.
 *
 * @return array<int,string>
 */
function wpr_translation_get_copy_once_tracker( $post_id ) {
    // Read stored copy-once markers.
    $stored = get_post_meta( $post_id, '_wpr_cf_copied_once', true );

    if ( ! is_array( $stored ) ) {
        // Default to an empty tracker.
        return array();
    }

    return array_values( array_unique( array_map( 'strval', $stored ) ) );
}

/**
 * Determine if a copy-once marker already exists for a meta key.
 *
 * @param array<int,string> $tracker Tracker of existing markers.
 * @param string            $meta_key Meta key.
 *
 * @return bool
 */
function wpr_translation_copy_once_has_marker( $tracker, $meta_key ) {
    // Check if the meta key was already copied once.
    return in_array( $meta_key, $tracker, true );
}

/**
 * Persist a copy-once marker for the provided meta key.
 *
 * @param int               $post_id Post ID.
 * @param array<int,string> $tracker Tracker of existing markers.
 * @param string            $meta_key Meta key.
 *
 * @return array<int,string>
 */
function wpr_translation_mark_copy_once_key( $post_id, $tracker, $meta_key ) {
    if ( in_array( $meta_key, $tracker, true ) ) {
        // Marker already exists.
        return $tracker;
    }

    // Add the marker and persist it.
    $tracker[] = $meta_key;

    update_post_meta( $post_id, '_wpr_cf_copied_once', $tracker );

    return $tracker;
}
