<?php

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

trait Niwa_AI_Tools_Variation_Ops {

    // ─── Validation methods ───────────────────────────────────────────────

    private function validate_variation_update_action_args( $args ) {
        $variation_check = $this->validate_required_positive_id( isset( $args['variation_id'] ) ? $args['variation_id'] : 0, 'Ciljna Woo varijacija nedostaje.' );
        if ( empty( $variation_check['success'] ) ) {
            return $variation_check;
        }

        $parent_check = $this->validate_required_positive_id( isset( $args['parent_id'] ) ? $args['parent_id'] : 0, 'Parent Woo proizvod nedostaje za varijaciju.' );
        if ( empty( $parent_check['success'] ) ) {
            return $parent_check;
        }

        $has_change = false;
        foreach ( array( 'regular_price', 'sale_price', 'stock_quantity', 'sku' ) as $field ) {
            if ( array_key_exists( $field, $args ) && null !== $args[ $field ] && '' !== trim( (string) $args[ $field ] ) ) {
                $has_change = true;
                break;
            }
        }
        if ( ! $has_change && ! empty( $args['clear_sale_price'] ) ) {
            $has_change = true;
        }

        if ( ! $has_change ) {
            return array(
                'success' => false,
                'error'   => 'Varijacija nema nijednu Woo promenu za izvrsenje.',
            );
        }

        return array(
            'success' => true,
        );
    }

    private function validate_variation_sale_schedule_action_args( $args ) {
        $variation_check = $this->validate_required_positive_id( isset( $args['variation_id'] ) ? $args['variation_id'] : 0, 'Ciljna Woo varijacija nedostaje za sale schedule.' );
        if ( empty( $variation_check['success'] ) ) {
            return $variation_check;
        }

        $parent_check = $this->validate_required_positive_id( isset( $args['parent_id'] ) ? $args['parent_id'] : 0, 'Parent Woo proizvod nedostaje za sale schedule varijacije.' );
        if ( empty( $parent_check['success'] ) ) {
            return $parent_check;
        }

        $has_change = false;
        foreach ( array( 'sale_price', 'date_on_sale_from', 'date_on_sale_to' ) as $field ) {
            if ( array_key_exists( $field, $args ) && null !== $args[ $field ] && '' !== trim( (string) $args[ $field ] ) ) {
                $has_change = true;
                break;
            }
        }
        if ( ! $has_change && ( ! empty( $args['clear_sale_price'] ) || ! empty( $args['clear_sale_dates'] ) ) ) {
            $has_change = true;
        }

        if ( ! $has_change ) {
            return array(
                'success' => false,
                'error'   => 'Sale schedule varijacije nema nijednu promenu za izvrsenje.',
            );
        }

        return array( 'success' => true );
    }

    private function validate_add_variation_action_args( $args ) {
        $parent_check = $this->validate_required_positive_id( isset( $args['parent_id'] ) ? $args['parent_id'] : 0, 'Parent Woo proizvod nedostaje za novu varijaciju.' );
        if ( empty( $parent_check['success'] ) ) {
            return $parent_check;
        }

        $normalized_meta = isset( $args['normalized_meta'] ) && is_array( $args['normalized_meta'] ) ? $args['normalized_meta'] : array();
        if ( empty( $normalized_meta ) ) {
            return array(
                'success' => false,
                'error'   => 'Nova Woo varijacija nema atribute.',
            );
        }

        return array(
            'success' => true,
        );
    }

    private function validate_bulk_update_variations_action_args( $args ) {
        $parent_check = $this->validate_required_positive_id( isset( $args['parent_id'] ) ? $args['parent_id'] : 0, 'Parent Woo proizvod nedostaje za bulk update varijacija.' );
        if ( empty( $parent_check['success'] ) ) {
            return $parent_check;
        }

        $variation_ids = isset( $args['variation_ids'] ) && is_array( $args['variation_ids'] ) ? $args['variation_ids'] : array();
        if ( empty( $variation_ids ) ) {
            return array( 'success' => false, 'error' => 'Bulk update nema nijednu ciljanu varijaciju.' );
        }

        $has_change = false;
        if ( array_key_exists( 'regular_price', $args ) && null !== $args['regular_price'] && '' !== trim( (string) $args['regular_price'] ) ) {
            $has_change = true;
        }
        if ( ! empty( $args['clear_sale_price'] ) ) {
            $has_change = true;
        }
        if ( array_key_exists( 'sale_price', $args ) && null !== $args['sale_price'] && '' !== trim( (string) $args['sale_price'] ) ) {
            $has_change = true;
        }
        if ( array_key_exists( 'stock_quantity', $args ) && null !== $args['stock_quantity'] && '' !== (string) $args['stock_quantity'] ) {
            $has_change = true;
        }

        if ( ! $has_change ) {
            return array( 'success' => false, 'error' => 'Bulk update varijacija nema nijednu promenu.' );
        }

        return array( 'success' => true );
    }

    private function validate_remove_variation_action_args( $args ) {
        $variation_check = $this->validate_required_positive_id( isset( $args['variation_id'] ) ? $args['variation_id'] : 0, 'Ciljna Woo varijacija nedostaje za uklanjanje.' );
        if ( empty( $variation_check['success'] ) ) {
            return $variation_check;
        }

        return $this->validate_required_positive_id( isset( $args['parent_id'] ) ? $args['parent_id'] : 0, 'Parent Woo proizvod nedostaje za uklanjanje varijacije.' );
    }

    // ─── Preview methods ──────────────────────────────────────────────────

    private function preview_update_product_variation( $args ) {
        // Shortcut: if variation_id is provided directly, skip the attribute resolution.
        $direct_variation_id = isset( $args['variation_id'] ) ? intval( $args['variation_id'] ) : 0;
        if ( $direct_variation_id > 0 ) {
            if ( ! function_exists( 'wc_get_product' ) ) {
                return array( 'success' => false, 'error' => 'WooCommerce nije dostupan.' );
            }
            $variation_obj = wc_get_product( $direct_variation_id );
            if ( ! $variation_obj || ! $variation_obj->is_type( 'variation' ) ) {
                return array( 'success' => false, 'error' => 'Varijacija #' . $direct_variation_id . ' ne postoji.' );
            }
            $parent_id   = $variation_obj->get_parent_id();
            $parent_post = get_post( $parent_id );
            $variation   = $this->build_variation_target( get_post( $direct_variation_id ), $variation_obj );

            $variation_args = $this->prepare_variation_update_args( $args, $variation );
            if ( empty( $variation_args['success'] ) ) {
                return $variation_args;
            }

            $parent_title = $parent_post ? (string) $parent_post->post_title : '#' . $parent_id;

            return array(
                'success' => true,
                'action'  => array(
                    'type'             => 'update_product_variation',
                    'label'            => 'Azuriraj Woo varijaciju',
                    'summary'          => 'Azuriraj varijaciju "' . $this->format_variation_meta_for_summary( $variation['attributes'] ) . '" za proizvod "' . $parent_title . '": ' . implode( '; ', $variation_args['summary_parts'] ) . '.',
                    'rollback_plan'    => 'Vraca prethodne Woo vrednosti za tu varijaciju.',
                    'rollback_support' => 'full',
                    'targets'          => array( $variation ),
                    'args'             => array_merge(
                        $variation_args['args'],
                        array(
                            'variation_id' => $direct_variation_id,
                            'parent_id'    => intval( $parent_id ),
                        )
                    ),
                ),
            );
        }

        // Standard path: resolve via product_query + variation_attributes.
        if ( empty( $args['product_query'] ) ) {
            return array( 'success' => false, 'error' => 'Potreban je variation_id ili product_query + variation_attributes.' );
        }

        $resolved = $this->resolve_variation_target_from_args( $args, false );
        if ( empty( $resolved['success'] ) ) {
            return $resolved;
        }

        $variation      = $resolved['variation'];
        $variation_args = $this->prepare_variation_update_args( $args, $variation );
        if ( empty( $variation_args['success'] ) ) {
            return $variation_args;
        }

        $summary_parts = $variation_args['summary_parts'];

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'update_product_variation',
                'label'            => 'Azuriraj Woo varijaciju',
                'summary'          => 'Azuriraj varijaciju "' . $resolved['variation_label'] . '" za proizvod "' . $resolved['product_target']['post_title'] . '": ' . implode( '; ', $summary_parts ) . '.',
                'rollback_plan'    => 'Vraca prethodne Woo vrednosti za tu varijaciju.',
                'rollback_support' => 'full',
                'targets'          => array( $variation ),
                'args'             => array_merge(
                    $variation_args['args'],
                    array(
                        'variation_id' => intval( $variation['variation_id'] ),
                        'parent_id'    => intval( $resolved['product_target']['post_id'] ),
                    )
                ),
            ),
        );
    }

    private function preview_add_product_variation( $args ) {
        $resolved = $this->resolve_variable_product_from_args( $args, true );
        if ( empty( $resolved['success'] ) ) {
            return $resolved;
        }

        $normalized = $this->normalize_variation_attributes_for_product( $resolved['product'], isset( $args['variation_attributes'] ) ? (array) $args['variation_attributes'] : array() );
        if ( empty( $normalized['success'] ) ) {
            return $normalized;
        }

        $existing = $this->find_variation_by_attributes(
            $resolved['product'],
            $normalized['meta'],
            array( 'publish', 'private', 'draft', 'pending', 'future', 'trash' )
        );
        if ( ! empty( $existing['success'] ) ) {
            return array(
                'success' => false,
                'error'   => 'Takva Woo varijacija vec postoji za taj proizvod.',
            );
        }

        $variation_args = $this->prepare_new_variation_args( $args );
        if ( empty( $variation_args['success'] ) ) {
            return $variation_args;
        }

        $summary_parts = array( 'dodaj varijaciju ' . $this->format_variation_meta_for_summary( $normalized['meta'] ) );
        $summary_parts = array_merge( $summary_parts, $variation_args['summary_parts'] );

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'add_product_variation',
                'label'            => 'Dodaj Woo varijaciju',
                'summary'          => 'Dodaj novu varijaciju za "' . $resolved['product_target']['post_title'] . '": ' . implode( '; ', $summary_parts ) . '.',
                'rollback_plan'    => 'Brise novokreiranu varijaciju ako zatreba rollback.',
                'rollback_support' => 'full',
                'targets'          => array(
                    array(
                        'parent_id'        => intval( $resolved['product_target']['post_id'] ),
                        'variation_label'  => $this->format_variation_meta_for_summary( $normalized['meta'] ),
                    ),
                ),
                'args'             => array_merge(
                    $variation_args['args'],
                    array(
                        'parent_id'           => intval( $resolved['product_target']['post_id'] ),
                        'normalized_meta'     => $normalized['meta'],
                        'normalized_display'  => $normalized['display'],
                    )
                ),
            ),
        );
    }

    private function preview_set_variation_sale_schedule( $args ) {
        if ( empty( $args['variation_id'] ) && empty( $args['product_query'] ) && empty( $args['product_id'] ) ) {
            return array( 'success' => false, 'error' => 'Potreban je variation_id ili product_query/product_id + variation_attributes.' );
        }

        $resolved = $this->resolve_variation_target_from_args( $args, false );
        if ( empty( $resolved['success'] ) ) {
            return $resolved;
        }

        $schedule_args = $this->prepare_variation_sale_schedule_args( $args, $resolved['variation'] );
        if ( empty( $schedule_args['success'] ) ) {
            return $schedule_args;
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'set_variation_sale_schedule',
                'label'            => 'Podesi sale schedule varijacije',
                'summary'          => 'Podesi akcijski period varijacije "' . $resolved['variation_label'] . '" za proizvod "' . $resolved['product_target']['post_title'] . '": ' . implode( '; ', $schedule_args['summary_parts'] ) . '.',
                'rollback_plan'    => 'Vraca prethodnu sale cenu i prethodne sale datume za tu varijaciju.',
                'rollback_support' => 'full',
                'targets'          => array( $resolved['variation'] ),
                'args'             => array_merge(
                    $schedule_args['args'],
                    array(
                        'variation_id' => intval( $resolved['variation']['variation_id'] ),
                        'parent_id'    => intval( $resolved['product_target']['post_id'] ),
                    )
                ),
            ),
        );
    }

    private function preview_bulk_update_variations( $args ) {
        $resolved = $this->resolve_variable_product_from_args( $args, true );
        if ( empty( $resolved['success'] ) ) {
            return $resolved;
        }

        $product    = $resolved['product'];
        $parent_id  = intval( $resolved['product_target']['post_id'] );
        $variations = $this->get_variation_targets_for_product( $product, array(), array( 'publish', 'private', 'draft', 'pending', 'future' ), 50 );

        if ( empty( $variations ) ) {
            return array(
                'success' => false,
                'error'   => 'Proizvod "' . $resolved['product_target']['post_title'] . '" nema nijednu varijaciju.',
            );
        }

        // Validate at least one change field is present.
        $regular_price_in = isset( $args['regular_price'] ) ? (string) $args['regular_price'] : null;
        $sale_price_in    = isset( $args['sale_price'] ) ? (string) $args['sale_price'] : null;
        $clear_sale_price = ! empty( $args['clear_sale_price'] );
        $has_stock_qty    = array_key_exists( 'stock_quantity', $args ) && '' !== (string) $args['stock_quantity'] && null !== $args['stock_quantity'];

        if ( null === $regular_price_in && null === $sale_price_in && ! $clear_sale_price && ! $has_stock_qty ) {
            return array(
                'success' => false,
                'error'   => 'Nema nijedne promene. Navedi regular_price, sale_price, clear_sale_price ili stock_quantity.',
            );
        }

        // Validate prices if provided.
        $regular_price = null;
        if ( null !== $regular_price_in && '' !== trim( $regular_price_in ) ) {
            $regular_price = $this->normalize_decimal_price( $regular_price_in );
            if ( null === $regular_price ) {
                return array( 'success' => false, 'error' => 'regular_price nije validan decimalni broj.' );
            }
        }

        $sale_price = null;
        if ( null !== $sale_price_in && '' !== trim( $sale_price_in ) ) {
            $sale_price = $this->normalize_decimal_price( $sale_price_in );
            if ( null === $sale_price ) {
                return array( 'success' => false, 'error' => 'sale_price nije validan decimalni broj.' );
            }
        }

        // Build summary.
        $summary_parts = array();
        if ( null !== $regular_price ) {
            $summary_parts[] = 'regular_price → ' . $this->format_price_display_value( $regular_price );
        }
        if ( $clear_sale_price ) {
            $summary_parts[] = 'ukloni sale_price';
        } elseif ( null !== $sale_price ) {
            $summary_parts[] = 'sale_price → ' . $this->format_price_display_value( $sale_price );
        }
        if ( $has_stock_qty ) {
            $summary_parts[] = 'stock_quantity → ' . intval( $args['stock_quantity'] );
        }

        $target_preview = array();
        $variation_ids  = array();
        foreach ( $variations as $v ) {
            $target_preview[] = array(
                'variation_id'          => intval( $v['variation_id'] ),
                'label'                 => $v['variation_label'],
                'current_price'         => $v['regular_price'],
                'current_price_display'  => isset( $v['regular_price_display'] ) ? (string) $v['regular_price_display'] : $this->format_price_display_value( $v['regular_price'] ),
                'current_sale'          => $v['sale_price'],
                'current_sale_display'  => isset( $v['sale_price_display'] ) ? (string) $v['sale_price_display'] : $this->format_price_display_value( $v['sale_price'] ),
                'current_stock'         => $v['stock_quantity'],
            );
            $variation_ids[] = intval( $v['variation_id'] );
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'bulk_update_variations',
                'label'            => 'Bulk azuriraj Woo varijacije',
                'summary'          => 'Azuriraj ' . count( $variations ) . ' varijacija za "' . $resolved['product_target']['post_title'] . '": ' . implode( '; ', $summary_parts ) . '.',
                'rollback_plan'    => 'Vraca prethodne vrednosti za sve promenjene varijacije.',
                'rollback_support' => 'full',
                'targets'          => $target_preview,
                'args'             => array(
                    'parent_id'       => $parent_id,
                    'variation_ids'   => $variation_ids,
                    'regular_price'   => $regular_price,
                    'sale_price'      => $clear_sale_price ? null : $sale_price,
                    'clear_sale_price'=> $clear_sale_price ? 1 : 0,
                    'stock_quantity'  => $has_stock_qty ? max( 0, intval( $args['stock_quantity'] ) ) : null,
                ),
            ),
        );
    }

    private function preview_remove_product_variation( $args ) {
        // Shortcut: if variation_id is provided directly, skip attribute resolution.
        $direct_variation_id = isset( $args['variation_id'] ) ? intval( $args['variation_id'] ) : 0;
        if ( $direct_variation_id > 0 ) {
            $post = get_post( $direct_variation_id );
            if ( ! $post || 'product_variation' !== (string) $post->post_type ) {
                return array( 'success' => false, 'error' => 'Varijacija #' . $direct_variation_id . ' ne postoji.' );
            }
            if ( ! function_exists( 'wc_get_product' ) ) {
                return array( 'success' => false, 'error' => 'WooCommerce nije dostupan.' );
            }
            $variation_obj = wc_get_product( $direct_variation_id );
            if ( ! $variation_obj || ! $variation_obj->is_type( 'variation' ) ) {
                return array( 'success' => false, 'error' => 'Varijacija #' . $direct_variation_id . ' nije validna WC varijacija.' );
            }
            $parent_id   = intval( $post->post_parent );
            $parent_post = get_post( $parent_id );
            $variation   = $this->build_variation_target( $post, $variation_obj );

            return array(
                'success' => true,
                'action'  => array(
                    'type'             => 'remove_product_variation',
                    'label'            => 'Ukloni Woo varijaciju',
                    'summary'          => 'Prebaci Woo varijaciju "' . $this->format_variation_meta_for_summary( $variation['attributes'] ) . '" u trash za proizvod "' . ( $parent_post ? (string) $parent_post->post_title : '#' . $parent_id ) . '".',
                    'rollback_plan'    => 'Vraca varijaciju iz trash-a.',
                    'rollback_support' => 'full',
                    'targets'          => array( $variation ),
                    'args'             => array(
                        'variation_id' => $direct_variation_id,
                        'parent_id'    => $parent_id,
                    ),
                ),
            );
        }

        // Standard path: resolve via product_query + variation_attributes.
        if ( empty( $args['product_query'] ) ) {
            return array( 'success' => false, 'error' => 'Potreban je variation_id ili product_query + variation_attributes.' );
        }

        $resolved = $this->resolve_variation_target_from_args( $args, false );
        if ( empty( $resolved['success'] ) ) {
            return $resolved;
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'remove_product_variation',
                'label'            => 'Ukloni Woo varijaciju',
                'summary'          => 'Prebaci Woo varijaciju "' . $resolved['variation_label'] . '" u trash za proizvod "' . $resolved['product_target']['post_title'] . '".',
                'rollback_plan'    => 'Vraca varijaciju iz trash-a.',
                'rollback_support' => 'full',
                'targets'          => array( $resolved['variation'] ),
                'args'             => array(
                    'variation_id' => intval( $resolved['variation']['variation_id'] ),
                    'parent_id'    => intval( $resolved['product_target']['post_id'] ),
                ),
            ),
        );
    }

    // ─── Execution methods ────────────────────────────────────────────────

    private function execute_update_product_variation_action( $action ) {
        if ( ! function_exists( 'wc_get_product' ) ) {
            return array( 'success' => false, 'error' => 'WooCommerce nije dostupan.' );
        }

        $args         = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $variation_id = intval( isset( $args['variation_id'] ) ? $args['variation_id'] : 0 );
        $parent_id    = intval( isset( $args['parent_id'] ) ? $args['parent_id'] : 0 );
        $variation    = wc_get_product( $variation_id );
        if ( ! $variation || ! $variation->is_type( 'variation' ) ) {
            return array( 'success' => false, 'error' => 'Ciljna Woo varijacija ne postoji.' );
        }

        $rollback_entry = $this->build_variation_restore_entry( $variation );
        $changes        = array();
        $shared_args    = $this->extract_shared_variation_state_args( $args );
        $shared_change_count = 0;

        if ( ! empty( $shared_args ) ) {
            if ( ! $this->product_management_service || ! method_exists( $this->product_management_service, 'update_variation_state' ) ) {
                return array( 'success' => false, 'error' => 'Shared product-management service nije ucitan za varijacije.' );
            }

            $shared_result = $this->product_management_service->update_variation_state(
                $parent_id > 0 ? $parent_id : intval( $variation->get_parent_id() ),
                $variation_id,
                array_merge(
                    $shared_args,
                    array(
                        'defer_parent_sync' => true,
                    )
                )
            );
            if ( empty( $shared_result['success'] ) ) {
                return array(
                    'success' => false,
                    'error'   => isset( $shared_result['error'] ) ? (string) $shared_result['error'] : 'Shared variation update nije uspela.',
                );
            }

            if ( ! empty( $shared_result['changes'] ) && is_array( $shared_result['changes'] ) ) {
                $changes = array_merge( $changes, array_values( array_filter( array_map( 'strval', $shared_result['changes'] ) ) ) );
            }
            $shared_change_count = count( $changes );

            foreach ( array( 'regular_price', 'sale_price', 'clear_sale_price', 'stock_quantity', 'sku', 'variation_status' ) as $shared_key ) {
                unset( $args[ $shared_key ] );
            }

            $variation = wc_get_product( $variation_id );
            if ( ! $variation || ! $variation->is_type( 'variation' ) ) {
                return array( 'success' => false, 'error' => 'Varijacija vise nije dostupna nakon shared update-a.' );
            }
        }

        if ( array_key_exists( 'regular_price', $args ) && null !== $args['regular_price'] && '' !== trim( (string) $args['regular_price'] ) ) {
            $variation->set_regular_price( (string) $args['regular_price'] );
            $changes[] = 'regular price';
        }

        if ( ! empty( $action['args']['clear_sale_price'] ) ) {
            $variation->set_sale_price( '' );
            $changes[] = 'sale price cleared';
        } elseif ( array_key_exists( 'sale_price', $args ) && null !== $args['sale_price'] && '' !== trim( (string) $args['sale_price'] ) ) {
            $variation->set_sale_price( (string) $args['sale_price'] );
            $changes[] = 'sale price';
        }

        if ( array_key_exists( 'stock_quantity', $args ) && null !== $args['stock_quantity'] && '' !== (string) $args['stock_quantity'] ) {
            $qty = max( 0, intval( $args['stock_quantity'] ) );
            $variation->set_manage_stock( true );
            $variation->set_stock_quantity( $qty );
            $variation->set_stock_status( $qty > 0 ? 'instock' : 'outofstock' );
            $changes[] = 'stock quantity';
        }

        if ( array_key_exists( 'sku', $args ) && null !== $args['sku'] ) {
            $sku = trim( (string) $args['sku'] );
            if ( '' !== $sku ) {
                $variation->set_sku( $sku );
                $changes[] = 'sku';
            }
        }

        // Handle variation image.
        if ( ! empty( $args['set_image'] ) ) {
            $img_attachment_id = isset( $args['attachment_id'] ) ? intval( $args['attachment_id'] ) : 0;
            $img_url           = isset( $args['image_url'] ) ? esc_url_raw( trim( (string) $args['image_url'] ) ) : '';

            if ( $img_attachment_id > 0 && get_post( $img_attachment_id ) ) {
                $variation->set_image_id( $img_attachment_id );
                $changes[] = 'image (att #' . $img_attachment_id . ')';
            } elseif ( '' !== $img_url ) {
                require_once ABSPATH . 'wp-admin/includes/file.php';
                require_once ABSPATH . 'wp-admin/includes/media.php';
                require_once ABSPATH . 'wp-admin/includes/image.php';

                if ( class_exists( 'Niwa_AI_Admin_Autonomy_Image_Utils' ) && method_exists( 'Niwa_AI_Admin_Autonomy_Image_Utils', 'ingest_from_url' ) ) {
                    $ingested = Niwa_AI_Admin_Autonomy_Image_Utils::ingest_from_url( $img_url );
                    if ( ! empty( $ingested['attachment_id'] ) ) {
                        $variation->set_image_id( intval( $ingested['attachment_id'] ) );
                        $changes[] = 'image';
                    } else {
                        $img_error = isset( $ingested['error'] ) ? (string) $ingested['error'] : 'nepoznata greska';
                        error_log( '[Niwa AI] Variation image ingest failed: ' . $img_error );
                    }
                }
            }
        }

        /* ── Variation description ── */
        if ( array_key_exists( 'variation_description', $args ) && null !== $args['variation_description'] ) {
            $variation->set_description( wp_kses_post( (string) $args['variation_description'] ) );
            $changes[] = 'description';
        }

        /* ── Variation status (enabled/disabled) ── */
        if ( ! empty( $action['args']['variation_status'] ) && in_array( (string) $action['args']['variation_status'], array( 'publish', 'private' ), true ) ) {
            $variation->set_status( (string) $action['args']['variation_status'] );
            $changes[] = 'status → ' . (string) $action['args']['variation_status'];
        }

        /* ── Variation weight / dimensions ── */
        if ( array_key_exists( 'weight', $args ) && null !== $args['weight'] && '' !== trim( (string) $args['weight'] ) ) {
            $variation->set_weight( (string) $args['weight'] );
            $changes[] = 'weight';
        }
        if ( array_key_exists( 'length', $args ) && null !== $args['length'] && '' !== trim( (string) $args['length'] ) ) {
            $variation->set_length( (string) $args['length'] );
            $changes[] = 'length';
        }
        if ( array_key_exists( 'width', $args ) && null !== $args['width'] && '' !== trim( (string) $args['width'] ) ) {
            $variation->set_width( (string) $args['width'] );
            $changes[] = 'width';
        }
        if ( array_key_exists( 'height', $args ) && null !== $args['height'] && '' !== trim( (string) $args['height'] ) ) {
            $variation->set_height( (string) $args['height'] );
            $changes[] = 'height';
        }

        /* ── Virtual / Downloadable ── */
        if ( array_key_exists( 'virtual', $args ) && null !== $args['virtual'] ) {
            $variation->set_virtual( (bool) $args['virtual'] );
            $changes[] = 'virtual → ' . ( $action['args']['virtual'] ? 'yes' : 'no' );
        }
        if ( array_key_exists( 'downloadable', $args ) && null !== $args['downloadable'] ) {
            $variation->set_downloadable( (bool) $args['downloadable'] );
            $changes[] = 'downloadable → ' . ( $action['args']['downloadable'] ? 'yes' : 'no' );
        }

        /* ── Tax class ── */
        if ( array_key_exists( 'tax_class', $args ) && null !== $args['tax_class'] ) {
            $variation->set_tax_class( (string) $args['tax_class'] );
            $changes[] = 'tax class';
        }

        /* ── Backorders ── */
        if ( ! empty( $action['args']['backorders'] ) && in_array( (string) $action['args']['backorders'], array( 'no', 'notify', 'yes' ), true ) ) {
            $variation->set_backorders( (string) $action['args']['backorders'] );
            $changes[] = 'backorders → ' . (string) $action['args']['backorders'];
        }

        if ( empty( $changes ) ) {
            return array( 'success' => false, 'error' => 'Nema Woo variation promena za izvrsenje.' );
        }

        $local_changes = array_slice( $changes, $shared_change_count );
        if ( ! empty( $local_changes ) ) {
            if ( method_exists( $variation, 'get_changes' ) && empty( $variation->get_changes() ) ) {
                if ( $shared_change_count <= 0 ) {
                    return array(
                        'success'      => false,
                        'error'        => 'Varijacija je vec u trazenom stanju; nema lokalne promene za snimanje.',
                        'variation_id' => $variation_id,
                        'parent_id'    => $parent_id > 0 ? $parent_id : intval( $variation->get_parent_id() ),
                        'requested_changes' => $local_changes,
                    );
                }
                $changes = array_slice( $changes, 0, $shared_change_count );
            } else {
                $saved = $variation->save();
                if ( ! $saved ) {
                    return array( 'success' => false, 'error' => 'Woo varijacija nije sacuvana.' );
                }
            }
        }

        $this->sync_variable_parent( $parent_id > 0 ? $parent_id : $variation->get_parent_id() );

        return array(
            'success'          => true,
            'summary'          => 'Azurirana je Woo varijacija #' . intval( $variation_id ) . '.',
            'executed_actions' => array(
                array(
                    'type'         => 'update_product_variation',
                    'variation_id' => $variation_id,
                    'changes'      => $changes,
                ),
            ),
            'rollback_entries' => array( $rollback_entry ),
        );
    }

    private function execute_bulk_update_variations_action( $action ) {
        if ( ! function_exists( 'wc_get_product' ) ) {
            return array( 'success' => false, 'error' => 'WooCommerce nije dostupan.' );
        }

        $args          = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $parent_id     = intval( isset( $args['parent_id'] ) ? $args['parent_id'] : 0 );
        $variation_ids = isset( $args['variation_ids'] ) && is_array( $args['variation_ids'] ) ? array_map( 'intval', $args['variation_ids'] ) : array();

        if ( empty( $variation_ids ) ) {
            return array( 'success' => false, 'error' => 'Bulk update nema ciljanih varijacija.' );
        }

        $shared_args = $this->extract_shared_variation_state_args( $args );
        if ( ! empty( $shared_args ) ) {
            if ( ! $this->product_management_service || ! method_exists( $this->product_management_service, 'update_variation_state' ) ) {
                return array( 'success' => false, 'error' => 'Shared product-management service nije ucitan za bulk variation update.' );
            }

            $executed = array();
            $rollback = array();
            $unchanged = array();

            foreach ( $variation_ids as $vid ) {
                $variation = wc_get_product( $vid );
                if ( ! $variation || ! $variation->is_type( 'variation' ) ) {
                    $this->rollback_entries( $rollback );
                    return array( 'success' => false, 'error' => 'Varijacija #' . $vid . ' vise ne postoji.' );
                }

                $rollback_entry = $this->build_variation_restore_entry( $variation );
                $shared_result = $this->product_management_service->update_variation_state(
                    $parent_id,
                    $vid,
                    array_merge(
                        $shared_args,
                        array(
                            'defer_parent_sync' => true,
                        )
                    )
                );
                if ( empty( $shared_result['success'] ) ) {
                    if ( $this->is_shared_variation_noop_result( $shared_result ) ) {
                        $unchanged[] = array(
                            'variation_id' => $vid,
                            'reason'       => isset( $shared_result['error'] ) ? (string) $shared_result['error'] : 'unchanged',
                        );
                        continue;
                    }
                    $this->rollback_entries( $rollback );
                    return array(
                        'success' => false,
                        'error'   => isset( $shared_result['error'] ) ? (string) $shared_result['error'] : 'Varijacija #' . $vid . ' nije sacuvana.',
                    );
                }

                $rollback[] = $rollback_entry;
                $executed[] = array(
                    'type'         => 'bulk_update_variations',
                    'variation_id' => $vid,
                    'changes'      => isset( $shared_result['changes'] ) && is_array( $shared_result['changes'] ) ? array_values( array_filter( array_map( 'strval', $shared_result['changes'] ) ) ) : array(),
                );
            }

            if ( empty( $executed ) ) {
                return array(
                    'success'              => false,
                    'error'                => 'Sve ciljane varijacije su vec u trazenom stanju; nema bulk promene za snimanje.',
                    'unchanged_variations' => $unchanged,
                );
            }

            $this->sync_variable_parent( $parent_id );

            return array(
                'success'          => true,
                'summary'          => 'Azurirano je ' . count( $executed ) . ' varijacija za proizvod #' . $parent_id . '.',
                'executed_actions' => $executed,
                'unchanged_variations' => $unchanged,
                'rollback_entries' => $rollback,
            );
        }

        $regular_price    = isset( $args['regular_price'] ) && null !== $args['regular_price'] && '' !== trim( (string) $args['regular_price'] ) ? (string) $args['regular_price'] : null;
        $sale_price       = isset( $args['sale_price'] ) && null !== $args['sale_price'] && '' !== trim( (string) $args['sale_price'] ) ? (string) $args['sale_price'] : null;
        $clear_sale_price = ! empty( $args['clear_sale_price'] );
        $has_stock_qty    = array_key_exists( 'stock_quantity', $args ) && null !== $args['stock_quantity'] && '' !== (string) $args['stock_quantity'];
        $stock_quantity   = $has_stock_qty ? max( 0, intval( $args['stock_quantity'] ) ) : null;

        if ( null === $regular_price && null === $sale_price && ! $clear_sale_price && null === $stock_quantity ) {
            return array( 'success' => false, 'error' => 'Nema bulk variation promene za izvrsenje.' );
        }

        $executed = array();
        $rollback = array();
        $unchanged = array();

        foreach ( $variation_ids as $vid ) {
            $variation = wc_get_product( $vid );
            if ( ! $variation || ! $variation->is_type( 'variation' ) ) {
                $this->rollback_entries( $rollback );
                return array( 'success' => false, 'error' => 'Varijacija #' . $vid . ' vise ne postoji.' );
            }

            $rollback[] = $this->build_variation_restore_entry( $variation );
            $changes    = array();

            if ( null !== $regular_price ) {
                $variation->set_regular_price( $regular_price );
                $changes[] = 'regular price';
            }

            if ( $clear_sale_price ) {
                $variation->set_sale_price( '' );
                $changes[] = 'sale price cleared';
            } elseif ( null !== $sale_price ) {
                $variation->set_sale_price( $sale_price );
                $changes[] = 'sale price';
            }

            if ( null !== $stock_quantity ) {
                $variation->set_manage_stock( true );
                $variation->set_stock_quantity( $stock_quantity );
                $variation->set_stock_status( $stock_quantity > 0 ? 'instock' : 'outofstock' );
                $changes[] = 'stock quantity';
            }

            if ( empty( $changes ) ) {
                continue;
            }

            if ( method_exists( $variation, 'get_changes' ) && empty( $variation->get_changes() ) ) {
                $unchanged[] = array(
                    'variation_id' => $vid,
                    'reason'       => 'Varijacija je vec u trazenom stanju; nema promene za snimanje.',
                );
                continue;
            }

            $saved = $variation->save();
            if ( ! $saved ) {
                $this->rollback_entries( $rollback );
                return array( 'success' => false, 'error' => 'Varijacija #' . $vid . ' nije sacuvana.' );
            }

            $executed[] = array(
                'type'         => 'bulk_update_variations',
                'variation_id' => $vid,
                'changes'      => $changes,
            );
        }

        if ( empty( $executed ) ) {
            return array(
                'success'              => false,
                'error'                => 'Sve ciljane varijacije su vec u trazenom stanju; nema bulk promene za snimanje.',
                'unchanged_variations' => $unchanged,
            );
        }

        $this->sync_variable_parent( $parent_id );

        return array(
            'success'          => true,
            'summary'          => 'Azurirano je ' . count( $executed ) . ' varijacija za proizvod #' . $parent_id . '.',
            'executed_actions' => $executed,
            'unchanged_variations' => $unchanged,
            'rollback_entries' => $rollback,
        );
    }

    private function execute_set_variation_sale_schedule_action( $action ) {
        if ( ! function_exists( 'wc_get_product' ) ) {
            return array( 'success' => false, 'error' => 'WooCommerce nije dostupan.' );
        }

        $args         = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $variation_id = intval( isset( $args['variation_id'] ) ? $args['variation_id'] : 0 );
        $parent_id    = intval( isset( $args['parent_id'] ) ? $args['parent_id'] : 0 );
        $variation    = wc_get_product( $variation_id );
        if ( ! $variation || ! $variation->is_type( 'variation' ) ) {
            return array( 'success' => false, 'error' => 'Ciljna Woo varijacija ne postoji.' );
        }

        $rollback_entry = $this->build_variation_restore_entry( $variation );
        $changes        = array();

        if ( ! empty( $args['clear_sale_price'] ) ) {
            $variation->set_sale_price( '' );
            $this->set_variation_sale_schedule_dates( $variation, null, null );
            $changes[] = 'sale price cleared';
            $changes[] = 'sale schedule cleared';
        } else {
            if ( array_key_exists( 'sale_price', $args ) && null !== $args['sale_price'] && '' !== trim( (string) $args['sale_price'] ) ) {
                $variation->set_sale_price( (string) $args['sale_price'] );
                $changes[] = 'sale price';
            }

            if ( ! empty( $args['clear_sale_dates'] ) ) {
                $this->set_variation_sale_schedule_dates( $variation, null, null );
                $changes[] = 'sale schedule cleared';
            } else {
                $from = array_key_exists( 'date_on_sale_from', $args ) ? $args['date_on_sale_from'] : '__niwa_keep__';
                $to   = array_key_exists( 'date_on_sale_to', $args ) ? $args['date_on_sale_to'] : '__niwa_keep__';
                if ( '__niwa_keep__' !== $from || '__niwa_keep__' !== $to ) {
                    $this->set_variation_sale_schedule_dates( $variation, $from, $to );
                    if ( '__niwa_keep__' !== $from ) {
                        $changes[] = 'sale start date';
                    }
                    if ( '__niwa_keep__' !== $to ) {
                        $changes[] = 'sale end date';
                    }
                }
            }
        }

        if ( empty( $changes ) ) {
            return array( 'success' => false, 'error' => 'Nema sale schedule promene za izvrsenje.' );
        }

        if ( method_exists( $variation, 'get_changes' ) && empty( $variation->get_changes() ) ) {
            return array( 'success' => false, 'error' => 'Varijacija je vec u trazenom sale schedule stanju; nema promene za snimanje.' );
        }

        $saved = $variation->save();
        if ( ! $saved ) {
            return array( 'success' => false, 'error' => 'Woo varijacija nije sacuvala sale schedule.' );
        }

        $this->sync_variable_parent( $parent_id > 0 ? $parent_id : $variation->get_parent_id() );

        return array(
            'success'          => true,
            'summary'          => 'Azuriran je akcijski period za Woo varijaciju #' . intval( $variation_id ) . '.',
            'executed_actions' => array(
                array(
                    'type'         => 'set_variation_sale_schedule',
                    'variation_id' => $variation_id,
                    'changes'      => $changes,
                ),
            ),
            'rollback_entries' => array( $rollback_entry ),
        );
    }

    private function execute_add_product_variation_action( $action ) {
        if ( ! function_exists( 'wc_get_product' ) ) {
            return array( 'success' => false, 'error' => 'WooCommerce nije dostupan.' );
        }

        $args      = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $parent_id = intval( isset( $args['parent_id'] ) ? $args['parent_id'] : 0 );
        $parent    = wc_get_product( $parent_id );
        if ( ! $parent || ! $parent->is_type( 'variable' ) ) {
            return array( 'success' => false, 'error' => 'Ciljni variable Woo proizvod ne postoji.' );
        }

        if ( $this->product_management_service && method_exists( $this->product_management_service, 'create_variation' ) ) {
            $shared_result = $this->product_management_service->create_variation(
                $parent_id,
                $args
            );
            if ( empty( $shared_result['success'] ) || empty( $shared_result['variation_id'] ) ) {
                return array(
                    'success' => false,
                    'error'   => isset( $shared_result['error'] ) ? (string) $shared_result['error'] : 'Kreiranje shared Woo varijacije nije uspelo.',
                );
            }

            $variation_id = intval( $shared_result['variation_id'] );

            return array(
                'success'          => true,
                'summary'          => 'Dodata je nova Woo varijacija za proizvod "' . get_the_title( $parent_id ) . '".',
                'executed_actions' => array(
                    array(
                        'type'         => 'add_product_variation',
                        'variation_id' => $variation_id,
                    ),
                ),
                'rollback_entries' => array(
                    array(
                        'type'         => 'variation_delete',
                        'variation_id' => $variation_id,
                        'parent_id'    => $parent_id,
                    ),
                ),
            );
        }

        $normalized_meta = isset( $args['normalized_meta'] ) && is_array( $args['normalized_meta'] ) ? $args['normalized_meta'] : array();
        $existing_variations = $this->get_variation_targets_for_product(
            $parent,
            $normalized_meta,
            array( 'publish', 'private', 'draft', 'pending', 'future' ),
            2
        );
        if ( ! empty( $existing_variations ) ) {
            return array(
                'success'               => false,
                'error'                 => 'Takva Woo varijacija vec postoji za taj proizvod; nema nove varijacije za kreiranje.',
                'parent_id'             => $parent_id,
                'existing_variation_id' => intval( $existing_variations[0]['variation_id'] ),
            );
        }

        $variation_id = wp_insert_post(
            array(
                'post_title'  => get_the_title( $parent_id ) . ' variation',
                'post_name'   => 'product-' . $parent_id . '-variation',
                'post_status' => 'publish',
                'post_parent' => $parent_id,
                'post_type'   => 'product_variation',
                'menu_order'  => 0,
            ),
            true
        );
        if ( is_wp_error( $variation_id ) || intval( $variation_id ) <= 0 ) {
            return array( 'success' => false, 'error' => is_wp_error( $variation_id ) ? $variation_id->get_error_message() : 'Kreiranje Woo varijacije nije uspelo.' );
        }

        foreach ( (array) $normalized_meta as $meta_key => $value ) {
            update_post_meta( $variation_id, (string) $meta_key, (string) $value );
        }

        $variation = wc_get_product( $variation_id );
        if ( ! $variation || ! $variation->is_type( 'variation' ) ) {
            wp_delete_post( $variation_id, true );
            return array( 'success' => false, 'error' => 'Nova Woo varijacija nije mogla da se ucita.' );
        }

        if ( array_key_exists( 'regular_price', $args ) && null !== $args['regular_price'] && '' !== trim( (string) $args['regular_price'] ) ) {
            $variation->set_regular_price( (string) $args['regular_price'] );
        }
        if ( array_key_exists( 'sale_price', $args ) && null !== $args['sale_price'] && '' !== trim( (string) $args['sale_price'] ) ) {
            $variation->set_sale_price( (string) $args['sale_price'] );
        }
        if ( array_key_exists( 'sku', $args ) && null !== $args['sku'] ) {
            $sku = trim( (string) $args['sku'] );
            if ( '' !== $sku ) {
                $variation->set_sku( $sku );
            }
        }
        if ( array_key_exists( 'stock_quantity', $args ) && null !== $args['stock_quantity'] && '' !== (string) $args['stock_quantity'] ) {
            $qty = max( 0, intval( $args['stock_quantity'] ) );
            $variation->set_manage_stock( true );
            $variation->set_stock_quantity( $qty );
            $variation->set_stock_status( $qty > 0 ? 'instock' : 'outofstock' );
        } else {
            $manage_stock = array_key_exists( 'manage_stock', $args ) ? (bool) $args['manage_stock'] : false;
            $variation->set_manage_stock( $manage_stock );
            if ( isset( $args['stock_status'] ) && in_array( (string) $args['stock_status'], array( 'instock', 'outofstock', 'onbackorder' ), true ) ) {
                $variation->set_stock_status( (string) $args['stock_status'] );
            }
        }
        if ( isset( $args['backorders'] ) && in_array( (string) $args['backorders'], array( 'no', 'notify', 'yes' ), true ) ) {
            $variation->set_backorders( (string) $args['backorders'] );
        }

        $attachment_id = isset( $args['attachment_id'] ) ? intval( $args['attachment_id'] ) : 0;
        if ( $attachment_id <= 0 && ! empty( $args['image_url'] ) && ( ! array_key_exists( 'set_image', $args ) || ! empty( $args['set_image'] ) ) ) {
            $image = Niwa_AI_Admin_Autonomy_Image_Utils::ingest_from_url( esc_url_raw( (string) $args['image_url'] ), get_the_title( $parent_id ), $parent_id );
            if ( ! empty( $image['success'] ) && ! empty( $image['attachment_id'] ) ) {
                $attachment_id = intval( $image['attachment_id'] );
            }
        }
        if ( $attachment_id > 0 && ( ! array_key_exists( 'set_image', $args ) || ! empty( $args['set_image'] ) ) ) {
            $variation->set_image_id( $attachment_id );
        }

        $saved = $variation->save();
        if ( ! $saved ) {
            wp_delete_post( $variation_id, true );
            return array( 'success' => false, 'error' => 'Nova Woo varijacija nije sacuvana.' );
        }

        $this->sync_variable_parent( $parent_id );

        return array(
            'success'          => true,
            'summary'          => 'Dodata je nova Woo varijacija za proizvod "' . get_the_title( $parent_id ) . '".',
            'executed_actions' => array(
                array(
                    'type'         => 'add_product_variation',
                    'variation_id' => intval( $variation_id ),
                ),
            ),
            'rollback_entries' => array(
                array(
                    'type'         => 'variation_delete',
                    'variation_id' => intval( $variation_id ),
                    'parent_id'    => $parent_id,
                ),
            ),
        );
    }

    private function execute_remove_product_variation_action( $action ) {
        $variation_id = intval( isset( $action['args']['variation_id'] ) ? $action['args']['variation_id'] : 0 );
        $parent_id    = intval( isset( $action['args']['parent_id'] ) ? $action['args']['parent_id'] : 0 );
        $post         = get_post( $variation_id );

        if ( ! $post || 'product_variation' !== $post->post_type ) {
            return array( 'success' => false, 'error' => 'Ciljna Woo varijacija ne postoji.' );
        }

        $parent_id          = $parent_id > 0 ? $parent_id : intval( $post->post_parent );
        $variation_meta     = $this->get_variation_attributes_meta( $variation_id );
        $parent             = $parent_id > 0 && function_exists( 'wc_get_product' ) ? wc_get_product( $parent_id ) : false;
        $rollback_entries   = array(
            array(
                'type'         => 'variation_untrash',
                'variation_id' => $variation_id,
                'parent_id'    => $parent_id,
            ),
        );
        if ( $parent && method_exists( $parent, 'is_type' ) && $parent->is_type( 'variable' ) ) {
            $rollback_entries[] = $this->build_product_attribute_restore_entry( $parent_id, $parent );
        }

        $trashed = wp_trash_post( $variation_id );
        if ( false === $trashed ) {
            return array( 'success' => false, 'error' => 'Uklanjanje Woo varijacije nije uspelo.' );
        }

        $removed_attribute_options = $this->remove_orphaned_parent_attribute_options_after_variation_delete( $parent_id, $variation_id, $variation_meta );

        $this->sync_variable_parent( $parent_id );

        return array(
            'success'          => true,
            'summary'          => 'Woo varijacija je prebacena u trash' . ( ! empty( $removed_attribute_options ) ? ', a parent atributi su ocisceni: ' . implode( ', ', $removed_attribute_options ) : '' ) . '.',
            'executed_actions' => array(
                array(
                    'type'                      => 'remove_product_variation',
                    'variation_id'              => $variation_id,
                    'removed_attribute_options' => $removed_attribute_options,
                ),
            ),
            'rollback_entries' => $rollback_entries,
        );
    }

    // ─── Helper methods ───────────────────────────────────────────────────

    private function remove_orphaned_parent_attribute_options_after_variation_delete( $parent_id, $deleted_variation_id, $deleted_variation_meta ) {
        $parent_id            = intval( $parent_id );
        $deleted_variation_id = intval( $deleted_variation_id );
        $deleted_variation_meta = is_array( $deleted_variation_meta ) ? $deleted_variation_meta : array();

        if ( $parent_id <= 0 || empty( $deleted_variation_meta ) || ! function_exists( 'wc_get_product' ) ) {
            return array();
        }

        $parent = wc_get_product( $parent_id );
        if ( ! $parent || ! method_exists( $parent, 'is_type' ) || ! $parent->is_type( 'variable' ) ) {
            return array();
        }

        $attributes = $parent->get_attributes();
        if ( empty( $attributes ) || ! is_array( $attributes ) ) {
            return array();
        }

        $changed = false;
        $removed = array();

        foreach ( $deleted_variation_meta as $meta_key => $deleted_value ) {
            $meta_key      = (string) $meta_key;
            $deleted_value = trim( (string) $deleted_value );
            if ( '' === $deleted_value || 0 !== strpos( $meta_key, 'attribute_' ) ) {
                continue;
            }

            if ( $this->variation_attribute_value_exists_on_other_active_variation( $parent_id, $deleted_variation_id, $meta_key, $deleted_value ) ) {
                continue;
            }

            $attribute_name = substr( $meta_key, strlen( 'attribute_' ) );
            foreach ( $attributes as $key => $attribute ) {
                if ( ! is_a( $attribute, 'WC_Product_Attribute' ) ) {
                    continue;
                }

                $attribute_meta_name = $attribute->is_taxonomy() ? (string) $attribute->get_name() : sanitize_title( (string) $attribute->get_name() );
                if ( $attribute_meta_name !== $attribute_name ) {
                    continue;
                }

                $options = $attribute->get_options();
                if ( $attribute->is_taxonomy() ) {
                    $term = get_term_by( 'slug', $deleted_value, $attribute_name );
                    if ( ! $term || is_wp_error( $term ) ) {
                        continue;
                    }

                    $term_id     = intval( $term->term_id );
                    $new_options = array_values( array_filter( array_map( 'intval', $options ), function ( $option_id ) use ( $term_id ) {
                        return intval( $option_id ) !== $term_id;
                    } ) );

                    if ( count( $new_options ) === count( $options ) ) {
                        continue;
                    }

                    wp_remove_object_terms( $parent_id, array( $term_id ), $attribute_name );
                    $removed[] = $attribute_name . ':' . (string) $term->name;
                } else {
                    $new_options = array();
                    foreach ( (array) $options as $option ) {
                        if ( $this->normalize_variation_key( $option ) === $this->normalize_variation_key( $deleted_value ) ) {
                            continue;
                        }
                        $new_options[] = $option;
                    }

                    if ( count( $new_options ) === count( $options ) ) {
                        continue;
                    }

                    $removed[] = $attribute_name . ':' . $deleted_value;
                }

                if ( empty( $new_options ) ) {
                    unset( $attributes[ $key ] );
                } else {
                    $attributes[ $key ] = $this->clone_variation_parent_attribute_with_options( $attribute, $new_options );
                }
                $changed = true;
                break;
            }
        }

        if ( ! $changed ) {
            return array();
        }

        $parent->set_attributes( array_values( $attributes ) );
        $parent->save();

        return array_values( array_unique( $removed ) );
    }

    private function clone_variation_parent_attribute_with_options( $attribute, $options ) {
        $updated_attribute = new WC_Product_Attribute();
        $updated_attribute->set_id( $attribute->get_id() );
        $updated_attribute->set_name( $attribute->get_name() );
        $updated_attribute->set_options( $options );
        $updated_attribute->set_position( $attribute->get_position() );
        $updated_attribute->set_visible( $attribute->get_visible() );
        $updated_attribute->set_variation( $attribute->get_variation() );

        return $updated_attribute;
    }

    private function variation_attribute_value_exists_on_other_active_variation( $parent_id, $deleted_variation_id, $meta_key, $value ) {
        $siblings = get_posts(
            array(
                'post_type'      => 'product_variation',
                'post_parent'    => intval( $parent_id ),
                'post_status'    => array( 'publish', 'private', 'draft', 'pending', 'future' ),
                'fields'         => 'ids',
                'posts_per_page' => -1,
                'no_found_rows'  => true,
            )
        );

        foreach ( (array) $siblings as $sibling_id ) {
            $sibling_id = intval( $sibling_id );
            if ( $sibling_id <= 0 || $sibling_id === intval( $deleted_variation_id ) ) {
                continue;
            }

            $sibling_value = get_post_meta( $sibling_id, (string) $meta_key, true );
            if ( (string) $sibling_value === (string) $value ) {
                return true;
            }
        }

        return false;
    }

    private function resolve_variable_product_from_args( $args, $require_exact = false ) {
        if ( ! class_exists( 'WooCommerce' ) || ! function_exists( 'wc_get_product' ) ) {
            return array(
                'success' => false,
                'error'   => 'WooCommerce nije aktivan.',
            );
        }

        $product_id    = isset( $args['product_id'] ) ? intval( $args['product_id'] ) : 0;
        $parent_id     = isset( $args['parent_id'] ) ? intval( $args['parent_id'] ) : 0;
        $sku           = isset( $args['sku'] ) ? trim( (string) $args['sku'] ) : '';
        $exact_only    = ! empty( $args['exact_only'] );
        $product_query = trim( (string) ( isset( $args['product_query'] ) ? $args['product_query'] : '' ) );

        if ( $product_id <= 0 && $parent_id > 0 ) {
            $product_id = $parent_id;
        }

        if ( $product_id <= 0 && '' === $product_query && '' === $sku ) {
            return array(
                'success' => false,
                'error'   => 'product_id, parent_id, sku ili product_query je obavezan.',
            );
        }

        $product_target = array();
        if ( $product_id > 0 ) {
            $post    = get_post( $product_id );
            $product = wc_get_product( $product_id );
            if ( $post && 'product' === (string) $post->post_type && $product ) {
                if ( $product->is_type( 'variation' ) ) {
                    $parent_product = wc_get_product( intval( $product->get_parent_id() ) );
                    if ( $parent_product && $parent_product->is_type( 'variable' ) ) {
                        $product_target = $this->build_product_target( get_post( intval( $parent_product->get_id() ) ), $parent_product );
                    }
                } elseif ( $product->is_type( 'variable' ) ) {
                    $product_target = $this->build_product_target( $post, $product );
                }
            }
        }

        if ( empty( $product_target ) && '' !== $sku && function_exists( 'wc_get_product_id_by_sku' ) ) {
            $resolved_id = wc_get_product_id_by_sku( $sku );
            if ( $resolved_id > 0 ) {
                $resolved_product = wc_get_product( $resolved_id );
                if ( $resolved_product && $resolved_product->is_type( 'variable' ) ) {
                    $product_target = $this->build_product_target( get_post( $resolved_id ), $resolved_product );
                } elseif ( $resolved_product && $resolved_product->is_type( 'variation' ) ) {
                    $parent_product = wc_get_product( intval( $resolved_product->get_parent_id() ) );
                    if ( $parent_product && $parent_product->is_type( 'variable' ) ) {
                        $product_target = $this->build_product_target( get_post( intval( $parent_product->get_id() ) ), $parent_product );
                    }
                }
            }
        }

        if ( empty( $product_target ) && '' !== $product_query && $require_exact ) {
            $resolved_exact = $this->resolve_product_target_for_write( 0, $product_query, array( 'publish', 'private', 'draft', 'pending', 'future' ), 'variation parent' );
            if ( empty( $resolved_exact['success'] ) ) {
                return $resolved_exact;
            }

            $product_target = $resolved_exact['target'];
        } elseif ( empty( $product_target ) && '' !== $product_query && method_exists( $this, 'find_exact_products_by_query' ) ) {
            $exact_products = $this->find_exact_products_by_query( $product_query, array( 'publish', 'private', 'draft', 'pending', 'future' ), 1 );
            if ( ! empty( $exact_products[0] ) ) {
                $product_target = $exact_products[0];
            }
        }

        if ( empty( $product_target ) && ! $exact_only && ! $require_exact && '' !== $product_query ) {
            $product_target = $this->find_product_by_query( $product_query, array( 'publish', 'private', 'draft', 'pending', 'future' ) );
        }

        if ( empty( $product_target ) ) {
            return array(
                'success' => false,
                'error'   => $product_id > 0 ? 'Nisam nasla variable proizvod za product_id: ' . $product_id : 'Nisam nasla variable proizvod za query: ' . $product_query,
            );
        }

        $product = wc_get_product( intval( $product_target['post_id'] ) );
        if ( ! $product || ! $product->is_type( 'variable' ) ) {
            return array(
                'success' => false,
                'error'   => 'Ciljni proizvod nije variable Woo proizvod.',
            );
        }

        return array(
            'success'        => true,
            'product_target' => $product_target,
            'product'        => $product,
        );
    }

    private function resolve_variation_target_from_args( $args, $include_trash = false ) {
        $direct_variation_id = isset( $args['variation_id'] ) ? intval( $args['variation_id'] ) : 0;
        if ( $direct_variation_id > 0 ) {
            if ( ! function_exists( 'wc_get_product' ) ) {
                return array( 'success' => false, 'error' => 'WooCommerce nije dostupan.' );
            }

            $variation = wc_get_product( $direct_variation_id );
            if ( ! $variation || ! $variation->is_type( 'variation' ) ) {
                return array( 'success' => false, 'error' => 'Varijacija #' . $direct_variation_id . ' ne postoji.' );
            }

            $parent_id = intval( $variation->get_parent_id() );
            if ( ! empty( $args['parent_id'] ) && intval( $args['parent_id'] ) !== $parent_id ) {
                return array( 'success' => false, 'error' => 'Parent ID ne odgovara varijaciji #' . $direct_variation_id . '.' );
            }

            $parent_product = wc_get_product( $parent_id );
            if ( ! $parent_product || ! $parent_product->is_type( 'variable' ) ) {
                return array( 'success' => false, 'error' => 'Parent proizvod za varijaciju nije variable Woo proizvod.' );
            }

            $filtered_attributes = array();
            if ( isset( $args['variation_attributes'] ) && is_array( $args['variation_attributes'] ) ) {
                foreach ( (array) $args['variation_attributes'] as $raw_key => $raw_value ) {
                    $normalized_key = $this->normalize_variation_key( $raw_key );
                    if ( in_array( $normalized_key, array( 'variation_id', 'variationid', 'parent_id', 'parentid', 'product_id', 'productid', 'sku', 'exact_only', 'exactonly', 'exact' ), true ) ) {
                        continue;
                    }
                    $filtered_attributes[ $raw_key ] = $raw_value;
                }
            }

            if ( ! empty( $filtered_attributes ) ) {
                $normalized = $this->normalize_variation_attributes_for_product( $parent_product, $filtered_attributes );
                if ( empty( $normalized['success'] ) ) {
                    return $normalized;
                }

                $stored_attributes = $this->get_variation_attributes_meta( $direct_variation_id );
                if ( ! $this->variation_matches_filter( $stored_attributes, $normalized['meta'] ) ) {
                    return array( 'success' => false, 'error' => 'Variation atributi ne odgovaraju varijaciji #' . $direct_variation_id . '.' );
                }
            }

            return array(
                'success'         => true,
                'product_target'  => $this->build_product_target( get_post( $parent_id ), $parent_product ),
                'product'         => $parent_product,
                'variation'       => $this->build_variation_target( get_post( $direct_variation_id ), $variation ),
                'variation_label' => $this->format_variation_meta_for_summary( $this->get_variation_attributes_meta( $direct_variation_id ) ),
            );
        }

        $resolved = $this->resolve_variable_product_from_args( $args, true );
        if ( empty( $resolved['success'] ) ) {
            return $resolved;
        }

        $normalized = $this->normalize_variation_attributes_for_product( $resolved['product'], isset( $args['variation_attributes'] ) ? (array) $args['variation_attributes'] : array() );
        if ( empty( $normalized['success'] ) ) {
            return $normalized;
        }

        $statuses  = $include_trash ? $this->normalize_variation_statuses( array( 'publish', 'private', 'draft', 'pending', 'future', 'trash' ) ) : $this->normalize_variation_statuses( array( 'publish', 'private', 'draft', 'pending', 'future' ) );
        $variation = $this->find_variation_by_attributes( $resolved['product'], $normalized['meta'], $statuses );
        if ( empty( $variation['success'] ) ) {
            return $variation;
        }

        return array(
            'success'         => true,
            'product_target'  => $resolved['product_target'],
            'product'         => $resolved['product'],
            'variation'       => $variation['variation'],
            'variation_label' => $this->format_variation_meta_for_summary( $variation['variation']['attributes'] ),
        );
    }

    private function prepare_variation_update_args( $args, $variation ) {
        $regular_price_in = isset( $args['regular_price'] ) ? (string) $args['regular_price'] : null;
        $sale_price_in    = isset( $args['sale_price'] ) ? (string) $args['sale_price'] : null;
        $clear_sale_price = ! empty( $args['clear_sale_price'] );
        $has_stock_qty    = array_key_exists( 'stock_quantity', $args ) && '' !== (string) $args['stock_quantity'] && null !== $args['stock_quantity'];
        $stock_quantity   = $has_stock_qty ? max( 0, intval( $args['stock_quantity'] ) ) : null;
        $sku              = isset( $args['sku'] ) ? trim( (string) $args['sku'] ) : null;
        $has_image        = ! empty( $args['set_image'] ) || ( isset( $args['image_url'] ) && '' !== trim( (string) $args['image_url'] ) ) || ( isset( $args['attachment_id'] ) && intval( $args['attachment_id'] ) > 0 );

        if ( null === $regular_price_in && null === $sale_price_in && ! $clear_sale_price && ! $has_stock_qty && ( null === $sku || '' === $sku ) && ! $has_image ) {
            return array(
                'success' => false,
                'error'   => 'Nema nijedne Woo variation promene.',
            );
        }

        $regular_price = null;
        if ( null !== $regular_price_in && '' !== trim( $regular_price_in ) ) {
            $regular_price = $this->normalize_decimal_price( $regular_price_in );
            if ( null === $regular_price ) {
                return array(
                    'success' => false,
                    'error'   => 'regular_price nije validan decimalni broj.',
                );
            }
        }

        $sale_price = null;
        if ( null !== $sale_price_in && '' !== trim( $sale_price_in ) ) {
            $sale_price = $this->normalize_decimal_price( $sale_price_in );
            if ( null === $sale_price ) {
                return array(
                    'success' => false,
                    'error'   => 'sale_price nije validan decimalni broj.',
                );
            }
        }

        $effective_regular = null !== $regular_price ? floatval( $regular_price ) : floatval( isset( $variation['regular_price'] ) ? $variation['regular_price'] : 0 );
        if ( null !== $sale_price && $effective_regular > 0 && floatval( $sale_price ) >= $effective_regular ) {
            return array(
                'success' => false,
                'error'   => 'Sale price mora biti manji od regular price.',
            );
        }

        $summary_parts = array();
        if ( null !== $regular_price ) {
            $summary_parts[] = 'regular price ' . $this->format_price_display_value( isset( $variation['regular_price'] ) && '' !== (string) $variation['regular_price'] ? (string) $variation['regular_price'] : '-' ) . ' -> ' . $this->format_price_display_value( $regular_price );
        }
        if ( $clear_sale_price ) {
            $summary_parts[] = 'ukloni sale price';
        } elseif ( null !== $sale_price ) {
            $summary_parts[] = 'sale price ' . $this->format_price_display_value( isset( $variation['sale_price'] ) && '' !== (string) $variation['sale_price'] ? (string) $variation['sale_price'] : '-' ) . ' -> ' . $this->format_price_display_value( $sale_price );
        }
        if ( null !== $stock_quantity ) {
            $summary_parts[] = 'stock qty ' . ( isset( $variation['stock_quantity'] ) && null !== $variation['stock_quantity'] ? intval( $variation['stock_quantity'] ) : '-' ) . ' -> ' . intval( $stock_quantity );
        }
        if ( null !== $sku && '' !== $sku ) {
            $summary_parts[] = 'sku ' . ( isset( $variation['sku'] ) && '' !== (string) $variation['sku'] ? (string) $variation['sku'] : '-' ) . ' -> ' . $sku;
        }

        $image_url     = isset( $args['image_url'] ) ? esc_url_raw( trim( (string) $args['image_url'] ) ) : null;
        $attachment_id = isset( $args['attachment_id'] ) ? intval( $args['attachment_id'] ) : 0;
        if ( $has_image ) {
            if ( $attachment_id > 0 ) {
                $summary_parts[] = 'slika (attachment #' . $attachment_id . ')';
            } elseif ( ! empty( $image_url ) ) {
                $summary_parts[] = 'slika (url)';
            } else {
                $summary_parts[] = 'slika (Telegram attachment)';
            }
        }

        $result_args = array(
            'regular_price'    => null !== $regular_price ? (string) $regular_price : null,
            'sale_price'       => null !== $sale_price ? (string) $sale_price : null,
            'clear_sale_price' => $clear_sale_price ? 1 : 0,
            'stock_quantity'   => null !== $stock_quantity ? intval( $stock_quantity ) : null,
            'sku'              => null !== $sku && '' !== $sku ? $sku : null,
        );

        if ( $has_image ) {
            $result_args['set_image']     = true;
            $result_args['image_url']     = ! empty( $image_url ) ? $image_url : null;
            $result_args['attachment_id'] = $attachment_id > 0 ? $attachment_id : null;
        }

        return array(
            'success'       => true,
            'summary_parts' => $summary_parts,
            'args'          => $result_args,
        );
    }

    private function prepare_variation_sale_schedule_args( $args, $variation ) {
        $sale_price_in     = isset( $args['sale_price'] ) ? (string) $args['sale_price'] : null;
        $clear_sale_price  = ! empty( $args['clear_sale_price'] );
        $clear_sale_dates  = ! empty( $args['clear_sale_dates'] );
        $has_from          = array_key_exists( 'date_on_sale_from', $args ) && null !== $args['date_on_sale_from'] && '' !== trim( (string) $args['date_on_sale_from'] );
        $has_to            = array_key_exists( 'date_on_sale_to', $args ) && null !== $args['date_on_sale_to'] && '' !== trim( (string) $args['date_on_sale_to'] );

        if ( null === $sale_price_in && ! $clear_sale_price && ! $clear_sale_dates && ! $has_from && ! $has_to ) {
            return array(
                'success' => false,
                'error'   => 'Nema nijedne sale schedule promene.',
            );
        }

        $sale_price = null;
        if ( null !== $sale_price_in && '' !== trim( $sale_price_in ) ) {
            $sale_price = $this->normalize_decimal_price( $sale_price_in );
            if ( null === $sale_price ) {
                return array(
                    'success' => false,
                    'error'   => 'sale_price nije validan decimalni broj.',
                );
            }

            $effective_regular = floatval( isset( $variation['regular_price'] ) ? $variation['regular_price'] : 0 );
            if ( $effective_regular > 0 && floatval( $sale_price ) >= $effective_regular ) {
                return array(
                    'success' => false,
                    'error'   => 'Sale price mora biti manji od regular price.',
                );
            }
        }

        $from = null;
        if ( $has_from ) {
            $from_result = $this->normalize_variation_sale_schedule_date( (string) $args['date_on_sale_from'], 'from' );
            if ( empty( $from_result['success'] ) ) {
                return $from_result;
            }
            $from = $from_result['value'];
        }

        $to = null;
        if ( $has_to ) {
            $to_result = $this->normalize_variation_sale_schedule_date( (string) $args['date_on_sale_to'], 'to' );
            if ( empty( $to_result['success'] ) ) {
                return $to_result;
            }
            $to = $to_result['value'];
        }

        if ( null !== $from && null !== $to && strtotime( $from ) > strtotime( $to ) ) {
            return array(
                'success' => false,
                'error'   => 'date_on_sale_from mora biti pre date_on_sale_to.',
            );
        }

        $summary_parts = array();
        if ( $clear_sale_price ) {
            $summary_parts[] = 'ukloni sale price i sale schedule';
        } else {
            if ( null !== $sale_price ) {
                $summary_parts[] = 'sale price ' . $this->format_price_display_value( isset( $variation['sale_price'] ) && '' !== (string) $variation['sale_price'] ? (string) $variation['sale_price'] : '-' ) . ' -> ' . $this->format_price_display_value( $sale_price );
            }
            if ( $clear_sale_dates ) {
                $summary_parts[] = 'ukloni sale schedule datume';
            } else {
                if ( null !== $from ) {
                    $summary_parts[] = 'sale start ' . ( isset( $variation['date_on_sale_from'] ) && '' !== (string) $variation['date_on_sale_from'] ? (string) $variation['date_on_sale_from'] : '-' ) . ' -> ' . $from;
                }
                if ( null !== $to ) {
                    $summary_parts[] = 'sale end ' . ( isset( $variation['date_on_sale_to'] ) && '' !== (string) $variation['date_on_sale_to'] ? (string) $variation['date_on_sale_to'] : '-' ) . ' -> ' . $to;
                }
            }
        }

        $result_args = array(
            'sale_price'       => null !== $sale_price ? (string) $sale_price : null,
            'clear_sale_price' => $clear_sale_price ? 1 : 0,
            'clear_sale_dates' => $clear_sale_dates ? 1 : 0,
        );
        if ( $has_from ) {
            $result_args['date_on_sale_from'] = null !== $from ? (string) $from : null;
        }
        if ( $has_to ) {
            $result_args['date_on_sale_to'] = null !== $to ? (string) $to : null;
        }

        return array(
            'success'       => true,
            'summary_parts' => $summary_parts,
            'args'          => $result_args,
        );
    }

    private function normalize_variation_sale_schedule_date( $value, $boundary ) {
        $value = trim( (string) $value );
        if ( '' === $value ) {
            return array( 'success' => true, 'value' => null );
        }

        if ( ! preg_match( '/^\d{4}-\d{2}-\d{2}(?:[ T]\d{2}:\d{2}(?::\d{2})?)?(?:Z|[+-]\d{2}:?\d{2})?$/', $value ) ) {
            return array(
                'success' => false,
                'error'   => 'Sale schedule datum mora biti YYYY-MM-DD ili ISO datetime.',
            );
        }

        $date_only = preg_match( '/^\d{4}-\d{2}-\d{2}$/', $value );
        if ( $date_only ) {
            $value .= 'to' === $boundary ? ' 23:59:59' : ' 00:00:00';
        }

        $timezone = function_exists( 'wp_timezone' ) ? wp_timezone() : new DateTimeZone( 'UTC' );
        try {
            $date = new DateTimeImmutable( $value, $timezone );
        } catch ( Exception $e ) {
            return array(
                'success' => false,
                'error'   => 'Sale schedule datum nije validan.',
            );
        }

        return array(
            'success' => true,
            'value'   => $date->setTimezone( $timezone )->format( 'Y-m-d H:i:s' ),
        );
    }

    private function set_variation_sale_schedule_dates( $variation, $from, $to ) {
        if ( '__niwa_keep__' !== $from && method_exists( $variation, 'set_date_on_sale_from' ) ) {
            $variation->set_date_on_sale_from( null === $from || '' === (string) $from ? null : (string) $from );
        }
        if ( '__niwa_keep__' !== $to && method_exists( $variation, 'set_date_on_sale_to' ) ) {
            $variation->set_date_on_sale_to( null === $to || '' === (string) $to ? null : (string) $to );
        }
    }

    private function format_wc_datetime_for_tool( $date ) {
        if ( ! is_object( $date ) || ! method_exists( $date, 'date' ) ) {
            return '';
        }

        return (string) $date->date( 'Y-m-d H:i:s' );
    }

    private function prepare_new_variation_args( $args ) {
        $regular_price = null;
        if ( array_key_exists( 'regular_price', $args ) && null !== $args['regular_price'] && '' !== trim( (string) $args['regular_price'] ) ) {
            $regular_price = $this->normalize_decimal_price( (string) $args['regular_price'] );
            if ( null === $regular_price ) {
                return array( 'success' => false, 'error' => 'regular_price nije validan decimalni broj.' );
            }
        }

        $sale_price = null;
        if ( array_key_exists( 'sale_price', $args ) && null !== $args['sale_price'] && '' !== trim( (string) $args['sale_price'] ) ) {
            $sale_price = $this->normalize_decimal_price( (string) $args['sale_price'] );
            if ( null === $sale_price ) {
                return array( 'success' => false, 'error' => 'sale_price nije validan decimalni broj.' );
            }
        }

        if ( null !== $sale_price && null !== $regular_price && floatval( $sale_price ) >= floatval( $regular_price ) ) {
            return array( 'success' => false, 'error' => 'Sale price mora biti manji od regular price.' );
        }

        $stock_quantity = null;
        if ( array_key_exists( 'stock_quantity', $args ) && null !== $args['stock_quantity'] && '' !== (string) $args['stock_quantity'] ) {
            $stock_quantity = max( 0, intval( $args['stock_quantity'] ) );
        }

        $stock_status = isset( $args['stock_status'] ) ? sanitize_key( (string) $args['stock_status'] ) : '';
        if ( '' !== $stock_status && ! in_array( $stock_status, array( 'instock', 'outofstock', 'onbackorder' ), true ) ) {
            return array( 'success' => false, 'error' => 'stock_status nije validan.' );
        }

        $backorders = isset( $args['backorders'] ) ? sanitize_key( (string) $args['backorders'] ) : '';
        if ( '' !== $backorders && ! in_array( $backorders, array( 'no', 'notify', 'yes' ), true ) ) {
            return array( 'success' => false, 'error' => 'backorders nije validan.' );
        }

        $attachment_id = isset( $args['attachment_id'] ) ? intval( $args['attachment_id'] ) : 0;
        $image_url     = isset( $args['image_url'] ) ? esc_url_raw( trim( (string) $args['image_url'] ) ) : '';
        if ( $attachment_id <= 0 && '' !== $image_url && ! preg_match( '#^https?://#i', $image_url ) ) {
            return array( 'success' => false, 'error' => 'image_url mora biti validan http/https URL.' );
        }

        $sku = isset( $args['sku'] ) ? trim( (string) $args['sku'] ) : null;
        $summary_parts = array();
        if ( null !== $regular_price ) {
            $summary_parts[] = 'regular price ' . $this->format_price_display_value( $regular_price );
        }
        if ( null !== $sale_price ) {
            $summary_parts[] = 'sale price ' . $this->format_price_display_value( $sale_price );
        }
        if ( null !== $stock_quantity ) {
            $summary_parts[] = 'stock qty ' . intval( $stock_quantity );
        } elseif ( '' !== $stock_status ) {
            $summary_parts[] = 'stock status ' . $stock_status;
        }
        if ( null !== $sku && '' !== $sku ) {
            $summary_parts[] = 'sku ' . $sku;
        }
        if ( $attachment_id > 0 || '' !== $image_url ) {
            $summary_parts[] = 'slika varijacije';
        }

        return array(
            'success'       => true,
            'summary_parts' => $summary_parts,
            'args'          => array(
                'regular_price'  => null !== $regular_price ? (string) $regular_price : null,
                'sale_price'     => null !== $sale_price ? (string) $sale_price : null,
                'stock_quantity' => null !== $stock_quantity ? intval( $stock_quantity ) : null,
                'manage_stock'   => array_key_exists( 'manage_stock', $args ) ? (bool) $args['manage_stock'] : null,
                'stock_status'   => '' !== $stock_status ? $stock_status : null,
                'backorders'     => '' !== $backorders ? $backorders : null,
                'sku'            => null !== $sku && '' !== $sku ? $sku : null,
                'image_url'      => '' !== $image_url ? $image_url : null,
                'attachment_id'  => $attachment_id > 0 ? $attachment_id : null,
                'set_image'      => ! empty( $args['set_image'] ) || $attachment_id > 0 || '' !== $image_url,
            ),
        );
    }

    private function extract_shared_variation_state_args( $args ) {
        $args   = is_array( $args ) ? $args : array();
        $shared = array();

        foreach ( array( 'regular_price', 'sale_price', 'stock_quantity', 'manage_stock', 'stock_status', 'backorders', 'sku', 'image_url', 'attachment_id', 'set_image' ) as $key ) {
            if ( ! array_key_exists( $key, $args ) ) {
                continue;
            }
            if ( null === $args[ $key ] || '' === trim( (string) $args[ $key ] ) ) {
                continue;
            }
            $shared[ $key ] = $args[ $key ];
        }

        if ( ! empty( $args['clear_sale_price'] ) ) {
            $shared['clear_sale_price'] = 1;
        }

        if ( ! empty( $args['variation_status'] ) ) {
            $shared['status'] = (string) $args['variation_status'];
        } elseif ( ! empty( $args['status'] ) ) {
            $shared['status'] = (string) $args['status'];
        }

        return $shared;
    }

    private function normalize_variation_attributes_for_product( $product, $input_attributes ) {
        if ( empty( $input_attributes ) || ! is_array( $input_attributes ) ) {
            return array(
                'success' => false,
                'error'   => 'variation_attributes su obavezni za rad sa Woo varijacijama.',
            );
        }

        $definitions = $this->build_variation_attribute_definitions( $product );
        if ( empty( $definitions ) ) {
            return array(
                'success' => false,
                'error'   => 'Variable proizvod nema definisane varijacione atribute.',
            );
        }

        $meta    = array();
        $display = array();
        foreach ( $input_attributes as $raw_key => $raw_value ) {
            $key   = $this->normalize_variation_key( $raw_key );
            $value = trim( (string) $raw_value );
            if ( '' === $key || '' === $value ) {
                continue;
            }

            if ( in_array( $key, array( 'variation_id', 'variationid', 'parent_id', 'parentid', 'product_id', 'productid', 'sku', 'exact_only', 'exactonly', 'exact' ), true ) ) {
                continue;
            }

            $matched = null;
            foreach ( $definitions as $definition ) {
                if ( in_array( $key, $definition['candidate_keys'], true ) ) {
                    $matched = $definition;
                    break;
                }
            }

            if ( empty( $matched ) ) {
                return array(
                    'success' => false,
                    'error'   => 'Nisam uspeo da mapiram variation atribut "' . (string) $raw_key . '" na Woo atribut proizvoda.',
                );
            }

            $normalized_value = $this->normalize_variation_option_value( $matched, $value );
            if ( null === $normalized_value ) {
                return array(
                    'success' => false,
                    'error'   => 'Vrednost "' . $value . '" nije validna opcija za atribut "' . $matched['label'] . '".',
                );
            }

            $meta[ $matched['meta_key'] ]    = $normalized_value;
            $display[ $matched['label'] ]    = $this->get_variation_option_display( $matched, $normalized_value );
        }

        if ( empty( $meta ) ) {
            return array(
                'success' => false,
                'error'   => 'variation_attributes nisu mogla da se normalizuju.',
            );
        }

        return array(
            'success' => true,
            'meta'    => $meta,
            'display' => $display,
        );
    }

    private function build_variation_attribute_definitions( $product ) {
        $definitions = array();
        foreach ( (array) $product->get_attributes() as $attribute ) {
            if ( ! is_object( $attribute ) || ! method_exists( $attribute, 'get_variation' ) || ! $attribute->get_variation() ) {
                continue;
            }

            $name      = (string) $attribute->get_name();
            $is_tax    = method_exists( $attribute, 'is_taxonomy' ) ? $attribute->is_taxonomy() : taxonomy_exists( $name );
            $meta_key  = 'attribute_' . ( $is_tax ? $name : sanitize_title( $name ) );
            $label     = function_exists( 'wc_attribute_label' ) ? wc_attribute_label( $name, $product ) : $name;
            $options   = array();

            if ( $is_tax ) {
                foreach ( (array) $attribute->get_options() as $term_id ) {
                    $term = get_term_by( 'id', $term_id, $name );
                    if ( ! $term || is_wp_error( $term ) ) {
                        continue;
                    }
                    $options[] = array(
                        'slug'        => (string) $term->slug,
                        'label'       => (string) $term->name,
                        'search_keys' => array_values(
                            array_unique(
                                array_filter(
                                    array(
                                        $this->normalize_variation_key( $term->slug ),
                                        $this->normalize_variation_key( $term->name ),
                                    )
                                )
                            )
                        ),
                    );
                }
            } else {
                foreach ( (array) $attribute->get_options() as $option_value ) {
                    $option_value = (string) $option_value;
                    $options[]    = array(
                        'slug'        => $option_value,
                        'label'       => $option_value,
                        'search_keys' => array( $this->normalize_variation_key( $option_value ) ),
                    );
                }
            }

            $candidate_keys = array_filter(
                array_unique(
                    array(
                        $this->normalize_variation_key( $name ),
                        $this->normalize_variation_key( str_replace( 'pa_', '', $name ) ),
                        $this->normalize_variation_key( $label ),
                    )
                )
            );

            $definitions[] = array(
                'meta_key'        => $meta_key,
                'label'           => (string) $label,
                'candidate_keys'  => array_values( $candidate_keys ),
                'options'         => $options,
            );
        }

        return $definitions;
    }

    private function normalize_variation_option_value( $definition, $value ) {
        $needle = $this->normalize_variation_key( $value );
        foreach ( (array) $definition['options'] as $option ) {
            if ( in_array( $needle, (array) $option['search_keys'], true ) ) {
                return (string) $option['slug'];
            }
        }

        return null;
    }

    private function get_variation_option_display( $definition, $value ) {
        foreach ( (array) $definition['options'] as $option ) {
            if ( (string) $option['slug'] === (string) $value ) {
                return (string) $option['label'];
            }
        }

        return (string) $value;
    }

    private function normalize_variation_key( $value ) {
        $value = remove_accents( trim( (string) $value ) );
        $value = strtolower( $value );
        $value = preg_replace( '/[^a-z0-9]+/', '_', $value );
        return trim( (string) $value, '_' );
    }

    private function find_variation_by_attributes( $product, $normalized_meta, $statuses = array() ) {
        $variations = $this->get_variation_targets_for_product( $product, $normalized_meta, $statuses, 20 );
        if ( empty( $variations ) ) {
            return array(
                'success' => false,
                'error'   => 'Nisam nasao Woo varijaciju sa tim atributima.',
            );
        }

        if ( count( $variations ) > 1 ) {
            return array(
                'success' => false,
                'error'   => 'Pronadjeno je vise Woo varijacija za taj selector. Treba precizniji skup atributa.',
            );
        }

        return array(
            'success'   => true,
            'variation' => $variations[0],
        );
    }

    private function get_variation_targets_for_product( $product, $filter_meta = array(), $statuses = array(), $limit = 10 ) {
        $statuses = $this->normalize_variation_statuses( $statuses );
        $filter_meta = is_array( $filter_meta )
            ? array_filter(
                $filter_meta,
                function ( $value ) {
                    return '' !== (string) $value;
                }
            )
            : array();
        $limit    = max( 1, min( 50, intval( $limit ) ) );
        $query_args = array(
            'post_type'      => 'product_variation',
            'post_status'    => $statuses,
            'posts_per_page' => $limit,
            'post_parent'    => intval( $product->get_id() ),
            'orderby'        => 'menu_order ID',
            'order'          => 'ASC',
        );

        if ( ! empty( $filter_meta ) ) {
            $meta_query = array( 'relation' => 'AND' );
            foreach ( $filter_meta as $meta_key => $value ) {
                $meta_query[] = array(
                    'key'   => (string) $meta_key,
                    'value' => (string) $value,
                );
            }
            $query_args['meta_query'] = $meta_query;
        }

        $posts    = get_posts(
            $query_args
        );

        $variations = array();
        foreach ( (array) $posts as $post ) {
            $variation = wc_get_product( intval( $post->ID ) );
            if ( ! $variation || ! $variation->is_type( 'variation' ) ) {
                continue;
            }

            $target = $this->build_variation_target( $post, $variation );
            if ( ! $this->variation_matches_filter( $target['attributes'], $filter_meta ) ) {
                continue;
            }
            $variations[] = $target;
        }

        return array_slice( $variations, 0, $limit );
    }

    private function build_variation_target( $post, $variation ) {
        $attributes = $this->get_variation_attributes_meta( intval( $post->ID ) );
        $regular_price = method_exists( $variation, 'get_regular_price' ) ? (string) $variation->get_regular_price() : '';
        $sale_price    = method_exists( $variation, 'get_sale_price' ) ? (string) $variation->get_sale_price() : '';
        $price         = method_exists( $variation, 'get_price' ) ? (string) $variation->get_price() : '';
        $sale_from     = method_exists( $variation, 'get_date_on_sale_from' ) ? $this->format_wc_datetime_for_tool( $variation->get_date_on_sale_from( 'edit' ) ) : '';
        $sale_to       = method_exists( $variation, 'get_date_on_sale_to' ) ? $this->format_wc_datetime_for_tool( $variation->get_date_on_sale_to( 'edit' ) ) : '';

        return array(
            'variation_id'    => intval( $post->ID ),
            'parent_id'       => intval( $post->post_parent ),
            'post_status'     => (string) $post->post_status,
            'attributes'      => $attributes,
            'wildcard_attributes' => array_keys(
                array_filter(
                    $attributes,
                    function ( $value ) {
                        return '' === (string) $value;
                    }
                )
            ),
            'variation_label' => $this->format_variation_meta_for_summary( $attributes ),
            'sku'             => method_exists( $variation, 'get_sku' ) ? (string) $variation->get_sku() : '',
            'regular_price'   => $regular_price,
            'regular_price_display' => $this->format_price_display_value( $regular_price ),
            'sale_price'      => $sale_price,
            'sale_price_display' => $this->format_price_display_value( $sale_price ),
            'date_on_sale_from' => $sale_from,
            'date_on_sale_to' => $sale_to,
            'price'           => $price,
            'price_display'   => $this->format_price_display_value( $price ),
            'manage_stock'    => method_exists( $variation, 'get_manage_stock' ) ? ( $variation->get_manage_stock() ? 1 : 0 ) : 0,
            'stock_quantity'  => method_exists( $variation, 'get_stock_quantity' ) ? $variation->get_stock_quantity() : null,
            'stock_status'    => method_exists( $variation, 'get_stock_status' ) ? (string) $variation->get_stock_status() : '',
        );
    }

    private function get_variation_attributes_meta( $variation_id ) {
        $meta   = get_post_meta( $variation_id );
        $result = array();
        foreach ( (array) $meta as $key => $values ) {
            if ( 0 !== strpos( (string) $key, 'attribute_' ) ) {
                continue;
            }
            $value = is_array( $values ) && array_key_exists( 0, $values ) ? (string) $values[0] : '';
            $result[ (string) $key ] = $value;
        }

        ksort( $result );
        return $result;
    }

    private function variation_matches_filter( $attributes, $filter_meta ) {
        foreach ( (array) $filter_meta as $meta_key => $value ) {
            if ( ! isset( $attributes[ $meta_key ] ) || (string) $attributes[ $meta_key ] !== (string) $value ) {
                return false;
            }
        }

        return true;
    }

    private function format_variation_meta_for_summary( $meta ) {
        if ( empty( $meta ) || ! is_array( $meta ) ) {
            return 'variation';
        }

        $parts = array();
        foreach ( $meta as $key => $value ) {
            $label = str_replace( array( 'attribute_pa_', 'attribute_' ), '', (string) $key );
            $label = ucwords( str_replace( array( '-', '_' ), ' ', $label ) );
            $parts[] = $label . ': ' . ( '' === (string) $value ? '(any)' : (string) $value );
        }

        return implode( ', ', $parts );
    }

    private function normalize_variation_statuses( $statuses ) {
        $default = array( 'publish', 'private', 'draft', 'pending', 'future', 'trash' );
        if ( empty( $statuses ) || ! is_array( $statuses ) ) {
            return $default;
        }

        $normalized = array();
        foreach ( $statuses as $status ) {
            $status = sanitize_key( (string) $status );
            if ( in_array( $status, $default, true ) ) {
                $normalized[] = $status;
            }
        }

        return ! empty( $normalized ) ? array_values( array_unique( $normalized ) ) : $default;
    }

    private function build_variation_restore_entry( $variation ) {
        $post = get_post( intval( $variation->get_id() ) );

        return array(
            'type'                   => 'variation_restore',
            'variation_id'           => intval( $variation->get_id() ),
            'parent_id'              => intval( $variation->get_parent_id() ),
            'previous_attributes'    => $this->get_variation_attributes_meta( intval( $variation->get_id() ) ),
            'previous_regular_price' => (string) $variation->get_regular_price(),
            'previous_sale_price'    => (string) $variation->get_sale_price(),
            'previous_date_on_sale_from' => method_exists( $variation, 'get_date_on_sale_from' ) ? $this->format_wc_datetime_for_tool( $variation->get_date_on_sale_from( 'edit' ) ) : '',
            'previous_date_on_sale_to'   => method_exists( $variation, 'get_date_on_sale_to' ) ? $this->format_wc_datetime_for_tool( $variation->get_date_on_sale_to( 'edit' ) ) : '',
            'previous_manage_stock'  => $variation->get_manage_stock() ? 1 : 0,
            'previous_stock_quantity'=> null !== $variation->get_stock_quantity() ? intval( $variation->get_stock_quantity() ) : '',
            'previous_stock_status'  => (string) $variation->get_stock_status(),
            'previous_sku'           => (string) $variation->get_sku(),
            'previous_image_id'      => method_exists( $variation, 'get_image_id' ) ? intval( $variation->get_image_id() ) : 0,
            'previous_description'   => method_exists( $variation, 'get_description' ) ? (string) $variation->get_description() : '',
            'previous_status'        => $post ? (string) $post->post_status : 'publish',
            'previous_weight'        => method_exists( $variation, 'get_weight' ) ? (string) $variation->get_weight() : '',
            'previous_length'        => method_exists( $variation, 'get_length' ) ? (string) $variation->get_length() : '',
            'previous_width'         => method_exists( $variation, 'get_width' ) ? (string) $variation->get_width() : '',
            'previous_height'        => method_exists( $variation, 'get_height' ) ? (string) $variation->get_height() : '',
            'previous_virtual'       => method_exists( $variation, 'get_virtual' ) ? ( $variation->get_virtual() ? 1 : 0 ) : 0,
            'previous_downloadable'  => method_exists( $variation, 'get_downloadable' ) ? ( $variation->get_downloadable() ? 1 : 0 ) : 0,
            'previous_tax_class'     => method_exists( $variation, 'get_tax_class' ) ? (string) $variation->get_tax_class() : '',
            'previous_backorders'    => method_exists( $variation, 'get_backorders' ) ? (string) $variation->get_backorders() : 'no',
            'previous_menu_order'    => $post ? intval( $post->menu_order ) : 0,
        );
    }

    private function build_variation_recreate_entry( $variation ) {
        $entry         = $this->build_variation_restore_entry( $variation );
        $entry['type'] = 'variation_recreate';
        return $entry;
    }

    private function sync_variable_parent( $parent_id ) {
        $parent_id = intval( $parent_id );
        if ( $parent_id <= 0 ) {
            return;
        }

        if ( class_exists( 'WC_Product_Variable' ) && method_exists( 'WC_Product_Variable', 'sync' ) ) {
            WC_Product_Variable::sync( $parent_id );
        }

        // Mandatory backstop after every variation edit: re-derive the parent
        // taxonomy attributes from the real active variations so numeric sizes
        // ("38"/"41") can never linger as the wrong term IDs on the parent.
        if ( $this->product_management_service && method_exists( $this->product_management_service, 'reconcile_parent_attributes_from_variations' ) ) {
            $this->product_management_service->reconcile_parent_attributes_from_variations( $parent_id );
        }

        $this->sync_product_ops_write( $parent_id );
    }

    private function is_shared_variation_noop_result( $result ) {
        if ( ! is_array( $result ) || ! empty( $result['success'] ) ) {
            return false;
        }

        $error = isset( $result['error'] ) ? (string) $result['error'] : '';
        return false !== strpos( $error, 'vec u trazenom stanju' )
            || false !== strpos( $error, 'nema promene za snimanje' );
    }
}
