<?php

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

trait Niwa_AI_Tools_Rollback {

    /* ================================================================
     * Rollback as a Tool — LLM calls this when user asks to undo
     * ============================================================= */

    private function preview_rollback_last_action( $args ) {
        if ( ! $this->autonomy_store || ! method_exists( $this->autonomy_store, 'get_latest_completed_run_for_rollback' ) ) {
            return array( 'success' => false, 'error' => 'Rollback store is not available.' );
        }

        $run = $this->autonomy_store->get_latest_completed_run_for_rollback();
        if ( empty( $run ) ) {
            return array( 'success' => false, 'error' => 'No recent completed action available to rollback.' );
        }

        $entries = isset( $run['rollback_entries'] ) && is_array( $run['rollback_entries'] ) ? $run['rollback_entries'] : array();
        if ( empty( $entries ) ) {
            return array( 'success' => false, 'error' => 'Last completed action has no rollback data.' );
        }

        $run_id  = isset( $run['id'] ) ? intval( $run['id'] ) : 0;
        $summary = isset( $run['summary'] ) ? (string) $run['summary'] : 'Unknown action';

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'rollback_last_action',
                'label'            => 'Rollback Last Action',
                'summary'          => 'Undo run #' . $run_id . ': ' . $summary,
                'rollback_plan'    => 'Reverts ' . count( $entries ) . ' change(s) from the last executed action.',
                'rollback_support' => 'none',
                'targets'          => array(
                    array(
                        'run_id'  => $run_id,
                        'summary' => $summary,
                        'entries' => count( $entries ),
                    ),
                ),
                'args' => array(
                    'run_id' => $run_id,
                ),
            ),
        );
    }

    private function execute_rollback_last_action( $action ) {
        if ( ! $this->autonomy_store || ! method_exists( $this->autonomy_store, 'get_latest_completed_run_for_rollback' ) ) {
            return array( 'success' => false, 'error' => 'Rollback store is not available.' );
        }

        $run = $this->autonomy_store->get_latest_completed_run_for_rollback();
        if ( empty( $run ) ) {
            return array( 'success' => false, 'error' => 'No recent completed action available to rollback.' );
        }

        $entries = isset( $run['rollback_entries'] ) && is_array( $run['rollback_entries'] ) ? $run['rollback_entries'] : array();
        if ( empty( $entries ) ) {
            return array( 'success' => false, 'error' => 'Last completed action has no rollback data.' );
        }

        $result = $this->rollback_entries( $entries );
        if ( empty( $result['success'] ) ) {
            return $result;
        }

        $run_id = isset( $run['id'] ) ? intval( $run['id'] ) : 0;
        if ( $run_id > 0 && method_exists( $this->autonomy_store, 'mark_rolled_back' ) ) {
            $this->autonomy_store->mark_rolled_back( $run_id, 'completed', '' );
        }

        return array(
            'success'          => true,
            'summary'          => sprintf( 'Rollback of run #%d completed. Reverted %d change(s).', $run_id, count( $entries ) ),
            'executed_actions' => array(
                array(
                    'type'   => 'rollback_last_action',
                    'run_id' => $run_id,
                ),
            ),
            'rollback_entries' => array(),
        );
    }

    /* ================================================================
     * Rollback entry restoration (individual entries)
     * ============================================================= */

    private function restore_entry( $entry ) {
        switch ( isset( $entry['type'] ) ? (string) $entry['type'] : '' ) {
            case 'post_status_restore':
                $updated = wp_update_post(
                    array(
                        'ID'          => intval( $entry['post_id'] ),
                        'post_status' => (string) $entry['previous_status'],
                    ),
                    true
                );
                return is_wp_error( $updated ) ? array( 'success' => false, 'error' => $updated->get_error_message() ) : array( 'success' => true );
            case 'post_retrash':
                $trashed = wp_trash_post( intval( $entry['post_id'] ) );
                return false === $trashed ? array( 'success' => false, 'error' => 'Rollback re-trash nije uspeo.' ) : array( 'success' => true );
            case 'post_field_restore':
                return $this->write_post_field_value( intval( $entry['post_id'] ), (string) $entry['field'], isset( $entry['previous_value'] ) ? (string) $entry['previous_value'] : '' );
            case 'file_restore':
                if ( ! empty( $entry['snapshot_path'] ) ) {
                    return $this->restore_file_from_snapshot( $entry );
                }
                $written = file_put_contents( (string) $entry['path'], isset( $entry['previous_content'] ) ? (string) $entry['previous_content'] : '', LOCK_EX );
                return false === $written ? array( 'success' => false, 'error' => 'Rollback file restore nije uspeo.' ) : array( 'success' => true );
            case 'file_delete':
                return $this->rollback_file_delete( $entry );
            case 'product_thumbnail_restore':
                $product_id = intval( $entry['product_id'] );
                $previous   = intval( $entry['previous_thumbnail_id'] );
                if ( $previous > 0 ) {
                    update_post_meta( $product_id, '_thumbnail_id', $previous );
                } else {
                    delete_post_meta( $product_id, '_thumbnail_id' );
                }
                if ( ! empty( $entry['new_attachment_id'] ) ) {
                    wp_delete_attachment( intval( $entry['new_attachment_id'] ), true );
                }
                clean_post_cache( $product_id );
                $this->sync_product_ops_write( $product_id );
                return array( 'success' => true );
            case 'inventory_cleanup_restore':
                $updated = wp_update_post(
                    array(
                        'ID'          => intval( $entry['product_id'] ),
                        'post_status' => (string) $entry['previous_status'],
                    ),
                    true
                );
                if ( is_wp_error( $updated ) ) {
                    return array( 'success' => false, 'error' => $updated->get_error_message() );
                }
                if ( ! empty( $entry['had_noindex_meta'] ) ) {
                    update_post_meta( intval( $entry['product_id'] ), '_za_noindex', isset( $entry['previous_noindex'] ) ? (string) $entry['previous_noindex'] : '' );
                } else {
                    delete_post_meta( intval( $entry['product_id'] ), '_za_noindex' );
                }
                return array( 'success' => true );
            case 'simple_product_restore':
                if ( ! function_exists( 'wc_get_product' ) ) {
                    return array( 'success' => false, 'error' => 'WooCommerce nije dostupan za rollback.' );
                }
                $product = wc_get_product( intval( $entry['product_id'] ) );
                if ( ! $product ) {
                    return array( 'success' => false, 'error' => 'Woo proizvod vise ne postoji za rollback.' );
                }
                if ( array_key_exists( 'previous_title', $entry ) ) {
                    $product->set_name( (string) $entry['previous_title'] );
                }
                if ( array_key_exists( 'previous_description', $entry ) ) {
                    $product->set_description( (string) $entry['previous_description'] );
                }
                if ( array_key_exists( 'previous_short_description', $entry ) ) {
                    $product->set_short_description( (string) $entry['previous_short_description'] );
                }
                if ( array_key_exists( 'previous_sku', $entry ) ) {
                    try { $product->set_sku( (string) $entry['previous_sku'] ); } catch ( \Exception $e ) { /* skip */ }
                }
                if ( array_key_exists( 'previous_status', $entry ) ) {
                    $product->set_status( (string) $entry['previous_status'] );
                }
                $product->set_regular_price( isset( $entry['previous_regular_price'] ) ? (string) $entry['previous_regular_price'] : '' );
                $product->set_sale_price( isset( $entry['previous_sale_price'] ) ? (string) $entry['previous_sale_price'] : '' );
                if ( method_exists( $product, 'set_date_on_sale_from' ) ) {
                    $prev_sale_from = isset( $entry['previous_date_on_sale_from'] ) ? (string) $entry['previous_date_on_sale_from'] : '';
                    $product->set_date_on_sale_from( '' !== $prev_sale_from ? $prev_sale_from : null );
                }
                if ( method_exists( $product, 'set_date_on_sale_to' ) ) {
                    $prev_sale_to = isset( $entry['previous_date_on_sale_to'] ) ? (string) $entry['previous_date_on_sale_to'] : '';
                    $product->set_date_on_sale_to( '' !== $prev_sale_to ? $prev_sale_to : null );
                }
                $product->set_manage_stock( ! empty( $entry['previous_manage_stock'] ) );
                $prev_qty = isset( $entry['previous_stock_quantity'] ) ? $entry['previous_stock_quantity'] : '';
                $product->set_stock_quantity( '' === $prev_qty ? null : intval( $prev_qty ) );
                $product->set_stock_status( isset( $entry['previous_stock_status'] ) ? (string) $entry['previous_stock_status'] : 'instock' );
                if ( array_key_exists( 'previous_weight', $entry ) ) {
                    $product->set_weight( (string) $entry['previous_weight'] );
                }
                if ( array_key_exists( 'previous_length', $entry ) ) {
                    $product->set_length( (string) $entry['previous_length'] );
                }
                if ( array_key_exists( 'previous_width', $entry ) ) {
                    $product->set_width( (string) $entry['previous_width'] );
                }
                if ( array_key_exists( 'previous_height', $entry ) ) {
                    $product->set_height( (string) $entry['previous_height'] );
                }
                if ( array_key_exists( 'previous_catalog_visibility', $entry ) ) {
                    $product->set_catalog_visibility( (string) $entry['previous_catalog_visibility'] );
                }
                if ( array_key_exists( 'previous_featured', $entry ) ) {
                    $product->set_featured( ! empty( $entry['previous_featured'] ) );
                }
                if ( array_key_exists( 'previous_virtual', $entry ) ) {
                    $product->set_virtual( ! empty( $entry['previous_virtual'] ) );
                }
                if ( array_key_exists( 'previous_downloadable', $entry ) ) {
                    $product->set_downloadable( ! empty( $entry['previous_downloadable'] ) );
                }
                if ( array_key_exists( 'previous_tax_status', $entry ) ) {
                    $product->set_tax_status( (string) $entry['previous_tax_status'] );
                }
                if ( array_key_exists( 'previous_tax_class', $entry ) ) {
                    $product->set_tax_class( (string) $entry['previous_tax_class'] );
                }
                if ( array_key_exists( 'previous_sold_individually', $entry ) ) {
                    $product->set_sold_individually( ! empty( $entry['previous_sold_individually'] ) );
                }
                if ( array_key_exists( 'previous_backorders', $entry ) ) {
                    $product->set_backorders( (string) $entry['previous_backorders'] );
                }
                if ( array_key_exists( 'previous_low_stock_amount', $entry ) && '' !== (string) $entry['previous_low_stock_amount'] ) {
                    $product->set_low_stock_amount( intval( $entry['previous_low_stock_amount'] ) );
                }
                if ( array_key_exists( 'previous_purchase_note', $entry ) ) {
                    $product->set_purchase_note( (string) $entry['previous_purchase_note'] );
                }
                if ( array_key_exists( 'previous_reviews_allowed', $entry ) ) {
                    $product->set_reviews_allowed( ! empty( $entry['previous_reviews_allowed'] ) );
                }
                if ( array_key_exists( 'previous_menu_order', $entry ) ) {
                    $product->set_menu_order( intval( $entry['previous_menu_order'] ) );
                }
                if ( array_key_exists( 'previous_upsell_ids', $entry ) && is_array( $entry['previous_upsell_ids'] ) ) {
                    $product->set_upsell_ids( array_map( 'intval', $entry['previous_upsell_ids'] ) );
                }
                if ( array_key_exists( 'previous_cross_sell_ids', $entry ) && is_array( $entry['previous_cross_sell_ids'] ) ) {
                    $product->set_cross_sell_ids( array_map( 'intval', $entry['previous_cross_sell_ids'] ) );
                }
                $saved = $product->save();
                if ( ! $saved ) {
                    return array( 'success' => false, 'error' => 'Woo rollback save nije uspeo.' );
                }
                $rb_pid = intval( $entry['product_id'] );
                if ( array_key_exists( 'previous_categories', $entry ) && is_array( $entry['previous_categories'] ) ) {
                    wp_set_object_terms( $rb_pid, array_map( 'intval', $entry['previous_categories'] ), 'product_cat', false );
                }
                if ( array_key_exists( 'previous_tags', $entry ) && is_array( $entry['previous_tags'] ) ) {
                    wp_set_object_terms( $rb_pid, array_map( 'intval', $entry['previous_tags'] ), 'product_tag', false );
                }
                $this->sync_product_ops_write( $rb_pid );
                return array( 'success' => true );
            case 'product_delete':
                if ( ! function_exists( 'wc_get_product' ) ) {
                    return array( 'success' => false, 'error' => 'WooCommerce nije dostupan za rollback.' );
                }
                $del_pid = intval( isset( $entry['product_id'] ) ? $entry['product_id'] : 0 );
                if ( $del_pid > 0 ) {
                    wp_trash_post( $del_pid );
                }
                return array( 'success' => true );
            case 'gallery_restore':
                if ( ! function_exists( 'wc_get_product' ) ) {
                    return array( 'success' => false, 'error' => 'WooCommerce nije dostupan za rollback.' );
                }
                $gal_product = wc_get_product( intval( isset( $entry['product_id'] ) ? $entry['product_id'] : 0 ) );
                if ( ! $gal_product ) {
                    return array( 'success' => false, 'error' => 'Proizvod za gallery rollback ne postoji.' );
                }
                $gal_product->set_gallery_image_ids( isset( $entry['previous_gallery_ids'] ) && is_array( $entry['previous_gallery_ids'] ) ? array_map( 'intval', $entry['previous_gallery_ids'] ) : array() );
                $gal_product->save();
                $this->sync_product_ops_write( intval( isset( $entry['product_id'] ) ? $entry['product_id'] : 0 ) );
                return array( 'success' => true );
            case 'attribute_restore':
                if ( ! function_exists( 'wc_get_product' ) ) {
                    return array( 'success' => false, 'error' => 'WooCommerce nije dostupan za rollback.' );
                }
                $attr_product = wc_get_product( intval( isset( $entry['product_id'] ) ? $entry['product_id'] : 0 ) );
                if ( ! $attr_product ) {
                    return array( 'success' => false, 'error' => 'Proizvod za attribute rollback ne postoji.' );
                }
                $restored_attrs = array();
                if ( ! empty( $entry['previous_attributes'] ) && is_array( $entry['previous_attributes'] ) ) {
                    foreach ( $entry['previous_attributes'] as $key => $attr_data ) {
                        $attr_obj = new \WC_Product_Attribute();
                        $attr_obj->set_name( isset( $attr_data['name'] ) ? (string) $attr_data['name'] : '' );
                        $attr_obj->set_options( isset( $attr_data['options'] ) && is_array( $attr_data['options'] ) ? $attr_data['options'] : array() );
                        $attr_obj->set_visible( ! empty( $attr_data['visible'] ) );
                        $attr_obj->set_variation( ! empty( $attr_data['variation'] ) );
                        $restored_attrs[] = $attr_obj;
                    }
                }
                $attr_product->set_attributes( $restored_attrs );
                $attr_product->save();
                $this->sync_product_ops_write( intval( isset( $entry['product_id'] ) ? $entry['product_id'] : 0 ) );
                return array( 'success' => true );
            case 'variation_untrash':
                $restored = wp_untrash_post( intval( $entry['variation_id'] ) );
                if ( false === $restored ) {
                    return array( 'success' => false, 'error' => 'Rollback variation untrash nije uspeo.' );
                }
                $this->sync_variable_parent( intval( isset( $entry['parent_id'] ) ? $entry['parent_id'] : 0 ) );
                return array( 'success' => true );
            case 'variation_delete':
                wp_delete_post( intval( $entry['variation_id'] ), true );
                $this->sync_variable_parent( intval( isset( $entry['parent_id'] ) ? $entry['parent_id'] : 0 ) );
                return array( 'success' => true );
            case 'variation_restore':
                if ( ! function_exists( 'wc_get_product' ) ) {
                    return array( 'success' => false, 'error' => 'WooCommerce nije dostupan za variation rollback.' );
                }
                $variation = wc_get_product( intval( $entry['variation_id'] ) );
                if ( ! $variation || ! $variation->is_type( 'variation' ) ) {
                    return array( 'success' => false, 'error' => 'Woo varijacija vise ne postoji za rollback.' );
                }
                foreach ( (array) ( isset( $entry['previous_attributes'] ) ? $entry['previous_attributes'] : array() ) as $meta_key => $value ) {
                    update_post_meta( intval( $entry['variation_id'] ), (string) $meta_key, (string) $value );
                }
                $variation->set_regular_price( isset( $entry['previous_regular_price'] ) ? (string) $entry['previous_regular_price'] : '' );
                $variation->set_sale_price( isset( $entry['previous_sale_price'] ) ? (string) $entry['previous_sale_price'] : '' );
                if ( method_exists( $variation, 'set_date_on_sale_from' ) ) {
                    $prev_sale_from = isset( $entry['previous_date_on_sale_from'] ) ? (string) $entry['previous_date_on_sale_from'] : '';
                    $variation->set_date_on_sale_from( '' !== $prev_sale_from ? $prev_sale_from : null );
                }
                if ( method_exists( $variation, 'set_date_on_sale_to' ) ) {
                    $prev_sale_to = isset( $entry['previous_date_on_sale_to'] ) ? (string) $entry['previous_date_on_sale_to'] : '';
                    $variation->set_date_on_sale_to( '' !== $prev_sale_to ? $prev_sale_to : null );
                }
                $variation->set_manage_stock( ! empty( $entry['previous_manage_stock'] ) );
                $prev_qty = isset( $entry['previous_stock_quantity'] ) ? $entry['previous_stock_quantity'] : '';
                $variation->set_stock_quantity( '' === $prev_qty ? null : intval( $prev_qty ) );
                $variation->set_stock_status( isset( $entry['previous_stock_status'] ) ? (string) $entry['previous_stock_status'] : 'instock' );
                if ( array_key_exists( 'previous_sku', $entry ) ) {
                    $variation->set_sku( (string) $entry['previous_sku'] );
                }
                if ( array_key_exists( 'previous_image_id', $entry ) && method_exists( $variation, 'set_image_id' ) ) {
                    $variation->set_image_id( intval( $entry['previous_image_id'] ) );
                }
                if ( array_key_exists( 'previous_description', $entry ) ) {
                    $variation->set_description( (string) $entry['previous_description'] );
                }
                if ( array_key_exists( 'previous_status', $entry ) ) {
                    $variation->set_status( (string) $entry['previous_status'] );
                }
                if ( array_key_exists( 'previous_weight', $entry ) ) {
                    $variation->set_weight( (string) $entry['previous_weight'] );
                }
                if ( array_key_exists( 'previous_length', $entry ) ) {
                    $variation->set_length( (string) $entry['previous_length'] );
                }
                if ( array_key_exists( 'previous_width', $entry ) ) {
                    $variation->set_width( (string) $entry['previous_width'] );
                }
                if ( array_key_exists( 'previous_height', $entry ) ) {
                    $variation->set_height( (string) $entry['previous_height'] );
                }
                if ( array_key_exists( 'previous_virtual', $entry ) ) {
                    $variation->set_virtual( ! empty( $entry['previous_virtual'] ) );
                }
                if ( array_key_exists( 'previous_downloadable', $entry ) ) {
                    $variation->set_downloadable( ! empty( $entry['previous_downloadable'] ) );
                }
                if ( array_key_exists( 'previous_tax_class', $entry ) ) {
                    $variation->set_tax_class( (string) $entry['previous_tax_class'] );
                }
                if ( array_key_exists( 'previous_backorders', $entry ) ) {
                    $variation->set_backorders( (string) $entry['previous_backorders'] );
                }
                $saved = $variation->save();
                if ( ! $saved ) {
                    return array( 'success' => false, 'error' => 'Woo variation rollback save nije uspeo.' );
                }
                $this->sync_variable_parent( intval( isset( $entry['parent_id'] ) ? $entry['parent_id'] : $variation->get_parent_id() ) );
                return array( 'success' => true );
            case 'variation_recreate':
                if ( ! function_exists( 'wc_get_product' ) ) {
                    return array( 'success' => false, 'error' => 'WooCommerce nije dostupan za variation recreation rollback.' );
                }

                $parent_id = intval( isset( $entry['parent_id'] ) ? $entry['parent_id'] : 0 );
                if ( $parent_id <= 0 ) {
                    return array( 'success' => false, 'error' => 'Parent variation rollback ID nedostaje.' );
                }

                $variation_id = wp_insert_post(
                    array(
                        'post_title'  => get_the_title( $parent_id ) . ' variation',
                        'post_status' => isset( $entry['previous_status'] ) ? (string) $entry['previous_status'] : 'publish',
                        'post_parent' => $parent_id,
                        'post_type'   => 'product_variation',
                        'menu_order'  => isset( $entry['previous_menu_order'] ) ? intval( $entry['previous_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() : 'Variation recreate rollback nije uspeo.',
                    );
                }

                foreach ( (array) ( isset( $entry['previous_attributes'] ) ? $entry['previous_attributes'] : array() ) as $meta_key => $value ) {
                    update_post_meta( intval( $variation_id ), (string) $meta_key, (string) $value );
                }

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

                $variation->set_regular_price( isset( $entry['previous_regular_price'] ) ? (string) $entry['previous_regular_price'] : '' );
                $variation->set_sale_price( isset( $entry['previous_sale_price'] ) ? (string) $entry['previous_sale_price'] : '' );
                if ( method_exists( $variation, 'set_date_on_sale_from' ) ) {
                    $prev_sale_from = isset( $entry['previous_date_on_sale_from'] ) ? (string) $entry['previous_date_on_sale_from'] : '';
                    $variation->set_date_on_sale_from( '' !== $prev_sale_from ? $prev_sale_from : null );
                }
                if ( method_exists( $variation, 'set_date_on_sale_to' ) ) {
                    $prev_sale_to = isset( $entry['previous_date_on_sale_to'] ) ? (string) $entry['previous_date_on_sale_to'] : '';
                    $variation->set_date_on_sale_to( '' !== $prev_sale_to ? $prev_sale_to : null );
                }
                $variation->set_manage_stock( ! empty( $entry['previous_manage_stock'] ) );
                $prev_qty = isset( $entry['previous_stock_quantity'] ) ? $entry['previous_stock_quantity'] : '';
                $variation->set_stock_quantity( '' === $prev_qty ? null : intval( $prev_qty ) );
                $variation->set_stock_status( isset( $entry['previous_stock_status'] ) ? (string) $entry['previous_stock_status'] : 'instock' );
                if ( array_key_exists( 'previous_sku', $entry ) ) {
                    $variation->set_sku( (string) $entry['previous_sku'] );
                }
                if ( array_key_exists( 'previous_image_id', $entry ) && method_exists( $variation, 'set_image_id' ) ) {
                    $variation->set_image_id( intval( $entry['previous_image_id'] ) );
                }
                if ( array_key_exists( 'previous_description', $entry ) ) {
                    $variation->set_description( (string) $entry['previous_description'] );
                }
                if ( array_key_exists( 'previous_status', $entry ) ) {
                    $variation->set_status( (string) $entry['previous_status'] );
                }
                if ( array_key_exists( 'previous_weight', $entry ) ) {
                    $variation->set_weight( (string) $entry['previous_weight'] );
                }
                if ( array_key_exists( 'previous_length', $entry ) ) {
                    $variation->set_length( (string) $entry['previous_length'] );
                }
                if ( array_key_exists( 'previous_width', $entry ) ) {
                    $variation->set_width( (string) $entry['previous_width'] );
                }
                if ( array_key_exists( 'previous_height', $entry ) ) {
                    $variation->set_height( (string) $entry['previous_height'] );
                }
                if ( array_key_exists( 'previous_virtual', $entry ) ) {
                    $variation->set_virtual( ! empty( $entry['previous_virtual'] ) );
                }
                if ( array_key_exists( 'previous_downloadable', $entry ) ) {
                    $variation->set_downloadable( ! empty( $entry['previous_downloadable'] ) );
                }
                if ( array_key_exists( 'previous_tax_class', $entry ) ) {
                    $variation->set_tax_class( (string) $entry['previous_tax_class'] );
                }
                if ( array_key_exists( 'previous_backorders', $entry ) ) {
                    $variation->set_backorders( (string) $entry['previous_backorders'] );
                }
                $saved = $variation->save();
                if ( ! $saved ) {
                    wp_delete_post( intval( $variation_id ), true );
                    return array( 'success' => false, 'error' => 'Variation recreate rollback save nije uspeo.' );
                }

                $this->sync_variable_parent( $parent_id );
                return array( 'success' => true );
            case 'attachment_delete':
                $att_id = intval( isset( $entry['attachment_id'] ) ? $entry['attachment_id'] : 0 );
                if ( $att_id > 0 ) {
                    wp_delete_attachment( $att_id, true );
                }
                return array( 'success' => true );
            case 'attachment_metadata_restore':
                $att_id = intval( isset( $entry['attachment_id'] ) ? $entry['attachment_id'] : 0 );
                if ( $att_id <= 0 || ! get_post( $att_id ) ) {
                    return array( 'success' => false, 'error' => 'Attachment za metadata rollback nije pronadjen.' );
                }

                $update = array( 'ID' => $att_id );
                if ( array_key_exists( 'previous_title', $entry ) ) {
                    $update['post_title'] = (string) $entry['previous_title'];
                }
                if ( array_key_exists( 'previous_parent_id', $entry ) ) {
                    $update['post_parent'] = intval( $entry['previous_parent_id'] );
                }
                if ( count( $update ) > 1 ) {
                    $updated = wp_update_post( $update, true );
                    if ( is_wp_error( $updated ) ) {
                        return array( 'success' => false, 'error' => 'Attachment metadata rollback nije uspeo: ' . $updated->get_error_message() );
                    }
                }

                if ( ! empty( $entry['previous_alt_exists'] ) ) {
                    update_post_meta( $att_id, '_wp_attachment_image_alt', (string) ( isset( $entry['previous_alt_text'] ) ? $entry['previous_alt_text'] : '' ) );
                } else {
                    delete_post_meta( $att_id, '_wp_attachment_image_alt' );
                }

                return array( 'success' => true );
            case 'skill_delete':
                if ( $this->skills_manager && method_exists( $this->skills_manager, 'delete_skill' ) ) {
                    return $this->skills_manager->delete_skill( isset( $entry['slug'] ) ? (string) $entry['slug'] : '' );
                }
                return array( 'success' => false, 'error' => 'Skills manager nije dostupan za rollback.' );
            case 'blog_post_delete':
                $trashed = wp_trash_post( intval( $entry['post_id'] ) );
                return false === $trashed
                    ? array( 'success' => false, 'error' => 'Rollback blog post delete (trash) nije uspeo.' )
                    : array( 'success' => true );
            case 'blog_post_restore':
                $restore_data = array( 'ID' => intval( $entry['post_id'] ) );
                if ( array_key_exists( 'previous_title', $entry ) ) {
                    $restore_data['post_title'] = (string) $entry['previous_title'];
                }
                if ( array_key_exists( 'previous_content', $entry ) ) {
                    $restore_data['post_content'] = (string) $entry['previous_content'];
                }
                if ( array_key_exists( 'previous_excerpt', $entry ) ) {
                    $restore_data['post_excerpt'] = (string) $entry['previous_excerpt'];
                }
                if ( array_key_exists( 'previous_status', $entry ) ) {
                    $restore_data['post_status'] = (string) $entry['previous_status'];
                }
                if ( array_key_exists( 'previous_slug', $entry ) ) {
                    $restore_data['post_name'] = (string) $entry['previous_slug'];
                }
				if ( array_key_exists( 'previous_author', $entry ) ) {
					$restore_data['post_author'] = intval( $entry['previous_author'] );
				}
				if ( array_key_exists( 'previous_date', $entry ) ) {
					$restore_data['post_date'] = (string) $entry['previous_date'];
				}
				if ( array_key_exists( 'previous_date_gmt', $entry ) ) {
					$restore_data['post_date_gmt'] = (string) $entry['previous_date_gmt'];
				}
                $updated = wp_update_post( $restore_data, true );
                if ( is_wp_error( $updated ) ) {
                    return array( 'success' => false, 'error' => $updated->get_error_message() );
                }
                $post_id = intval( $entry['post_id'] );
				if ( array_key_exists( 'previous_modified', $entry ) || array_key_exists( 'previous_modified_gmt', $entry ) ) {
					global $wpdb;
					if ( isset( $wpdb ) && isset( $wpdb->posts ) && method_exists( $wpdb, 'update' ) ) {
						$modified = array(
							'post_modified'     => isset( $entry['previous_modified'] ) ? (string) $entry['previous_modified'] : '',
							'post_modified_gmt' => isset( $entry['previous_modified_gmt'] ) ? (string) $entry['previous_modified_gmt'] : '',
						);
						if ( false === $wpdb->update( $wpdb->posts, $modified, array( 'ID' => $post_id ), array( '%s', '%s' ), array( '%d' ) ) ) {
							return array( 'success' => false, 'error' => 'Rollback could not restore exact post modification timestamps.' );
						}
						if ( function_exists( 'clean_post_cache' ) ) {
							clean_post_cache( $post_id );
						}
					}
				}
                if ( array_key_exists( 'previous_category_ids', $entry ) ) {
                    wp_set_post_categories( $post_id, array_map( 'intval', (array) $entry['previous_category_ids'] ) );
                }
                if ( array_key_exists( 'previous_tag_ids', $entry ) ) {
                    wp_set_post_terms( $post_id, array_map( 'intval', (array) $entry['previous_tag_ids'] ), 'post_tag' );
                }
                if ( array_key_exists( 'previous_thumbnail_id', $entry ) ) {
                    $prev_thumb = intval( $entry['previous_thumbnail_id'] );
                    if ( $prev_thumb > 0 ) {
                        set_post_thumbnail( $post_id, $prev_thumb );
                    } else {
                        delete_post_thumbnail( $post_id );
                    }
                }
				if ( ! empty( $entry['previous_meta'] ) && is_array( $entry['previous_meta'] ) ) {
					foreach ( $entry['previous_meta'] as $meta_key => $snapshot ) {
						delete_post_meta( $post_id, (string) $meta_key );
						if ( empty( $snapshot['exists'] ) ) {
							continue;
						}
						foreach ( isset( $snapshot['values'] ) ? (array) $snapshot['values'] : array() as $value ) {
							add_post_meta( $post_id, (string) $meta_key, $value );
						}
					}
				}
                return array( 'success' => true );
			case 'blog_term_delete_if_unused':
				$term_id  = intval( isset( $entry['term_id'] ) ? $entry['term_id'] : 0 );
				$taxonomy = isset( $entry['taxonomy'] ) ? sanitize_key( (string) $entry['taxonomy'] ) : '';
				$term     = $term_id > 0 && $taxonomy ? get_term( $term_id, $taxonomy ) : null;
				if ( ! $term || is_wp_error( $term ) ) {
					return array( 'success' => true );
				}
				if ( intval( $term->count ) > 0 ) {
					return array( 'success' => true, 'skipped' => true, 'reason' => 'term_still_in_use' );
				}
				$deleted = wp_delete_term( $term_id, $taxonomy );
				return is_wp_error( $deleted )
					? array( 'success' => false, 'error' => $deleted->get_error_message() )
					: array( 'success' => true );
            case 'blog_post_unpublish':
                $prev_status = isset( $entry['previous_status'] ) ? (string) $entry['previous_status'] : 'draft';
                $updated     = wp_update_post(
                    array(
                        'ID'          => intval( $entry['post_id'] ),
                        'post_status' => $prev_status,
                    ),
                    true
                );
                return is_wp_error( $updated )
                    ? array( 'success' => false, 'error' => $updated->get_error_message() )
                    : array( 'success' => true );

            /* ---------- User rollbacks ---------- */
            case 'user_delete':
                if ( ! function_exists( 'wp_delete_user' ) ) {
                    require_once ABSPATH . 'wp-admin/includes/user.php';
                }
                $uid = intval( isset( $entry['user_id'] ) ? $entry['user_id'] : 0 );
                if ( $uid > 0 ) {
                    wp_delete_user( $uid );
                }
                return array( 'success' => true );
            case 'user_restore':
                $uid = intval( isset( $entry['user_id'] ) ? $entry['user_id'] : 0 );
                if ( $uid <= 0 ) {
                    return array( 'success' => false, 'error' => 'User ID nedostaje za rollback.' );
                }
                $user_data = array( 'ID' => $uid );
                $fields_map = array(
                    'previous_email'        => 'user_email',
                    'previous_first_name'   => 'first_name',
                    'previous_last_name'    => 'last_name',
                    'previous_display_name' => 'display_name',
                    'previous_nickname'     => 'nickname',
                    'previous_description'  => 'description',
                    'previous_url'          => 'user_url',
                );
                foreach ( $fields_map as $entry_key => $wp_key ) {
                    if ( array_key_exists( $entry_key, $entry ) ) {
                        $user_data[ $wp_key ] = (string) $entry[ $entry_key ];
                    }
                }
                if ( ! empty( $entry['previous_role'] ) ) {
                    $user_data['role'] = (string) $entry['previous_role'];
                }
                $result = wp_update_user( $user_data );
                return is_wp_error( $result )
                    ? array( 'success' => false, 'error' => $result->get_error_message() )
                    : array( 'success' => true );

            /* ---------- Taxonomy rollbacks ---------- */
            case 'wc_term_delete':
            case 'term_delete':
                $tid = intval( isset( $entry['term_id'] ) ? $entry['term_id'] : 0 );
                $tax = isset( $entry['taxonomy'] ) ? (string) $entry['taxonomy'] : '';
                if ( $tid > 0 && '' !== $tax ) {
                    wp_delete_term( $tid, $tax );
                }
                return array( 'success' => true );
            case 'wc_term_restore':
            case 'term_restore':
                $tid = intval( isset( $entry['term_id'] ) ? $entry['term_id'] : 0 );
                $tax = isset( $entry['taxonomy'] ) ? (string) $entry['taxonomy'] : '';
                if ( $tid <= 0 || '' === $tax ) {
                    return array( 'success' => false, 'error' => 'Term ID ili taxonomy nedostaje za rollback.' );
                }
                $term_args = array();
                if ( array_key_exists( 'previous_name', $entry ) ) {
                    $term_args['name'] = (string) $entry['previous_name'];
                }
                if ( array_key_exists( 'previous_slug', $entry ) ) {
                    $term_args['slug'] = (string) $entry['previous_slug'];
                }
                if ( array_key_exists( 'previous_description', $entry ) ) {
                    $term_args['description'] = (string) $entry['previous_description'];
                }
                if ( array_key_exists( 'previous_parent', $entry ) ) {
                    $term_args['parent'] = intval( $entry['previous_parent'] );
                }
                if ( ! empty( $term_args ) ) {
                    wp_update_term( $tid, $tax, $term_args );
                }
                if ( array_key_exists( 'previous_thumbnail_id', $entry ) ) {
                    $prev_thumb = intval( $entry['previous_thumbnail_id'] );
                    if ( $prev_thumb > 0 ) {
                        update_term_meta( $tid, 'thumbnail_id', $prev_thumb );
                    } else {
                        delete_term_meta( $tid, 'thumbnail_id' );
                    }
                }
                return array( 'success' => true );

            /* ---------- Settings rollbacks ---------- */
            case 'settings_restore':
                $prev = isset( $entry['previous_settings'] ) && is_array( $entry['previous_settings'] ) ? $entry['previous_settings'] : array();
                foreach ( $prev as $opt_name => $opt_value ) {
                    update_option( (string) $opt_name, $opt_value );
                }
                return array( 'success' => true );

            /* ---------- Page rollbacks ---------- */
            case 'page_delete':
                $pid = intval( isset( $entry['page_id'] ) ? $entry['page_id'] : 0 );
                if ( $pid > 0 ) {
                    wp_trash_post( $pid );
                }
                return array( 'success' => true );
            case 'page_restore':
                $pid = intval( isset( $entry['page_id'] ) ? $entry['page_id'] : 0 );
                if ( $pid <= 0 ) {
                    return array( 'success' => false, 'error' => 'Page ID nedostaje za rollback.' );
                }
                $page_data = array( 'ID' => $pid );
                if ( array_key_exists( 'previous_title', $entry ) ) {
                    $page_data['post_title'] = (string) $entry['previous_title'];
                }
                if ( array_key_exists( 'previous_content', $entry ) ) {
                    $page_data['post_content'] = (string) $entry['previous_content'];
                }
                if ( array_key_exists( 'previous_excerpt', $entry ) ) {
                    $page_data['post_excerpt'] = (string) $entry['previous_excerpt'];
                }
                if ( array_key_exists( 'previous_status', $entry ) ) {
                    $page_data['post_status'] = (string) $entry['previous_status'];
                }
                if ( array_key_exists( 'previous_slug', $entry ) ) {
                    $page_data['post_name'] = (string) $entry['previous_slug'];
                }
                if ( array_key_exists( 'previous_parent', $entry ) ) {
                    $page_data['post_parent'] = intval( $entry['previous_parent'] );
                }
                if ( array_key_exists( 'previous_menu_order', $entry ) ) {
                    $page_data['menu_order'] = intval( $entry['previous_menu_order'] );
                }
                if ( array_key_exists( 'previous_comment_status', $entry ) ) {
                    $page_data['comment_status'] = (string) $entry['previous_comment_status'];
                }
                $updated = wp_update_post( $page_data, true );
                if ( is_wp_error( $updated ) ) {
                    return array( 'success' => false, 'error' => $updated->get_error_message() );
                }
                if ( array_key_exists( 'previous_template', $entry ) ) {
                    update_post_meta( $pid, '_wp_page_template', (string) $entry['previous_template'] );
                }
                if ( array_key_exists( 'previous_thumbnail_id', $entry ) ) {
                    $prev_thumb = intval( $entry['previous_thumbnail_id'] );
                    if ( $prev_thumb > 0 ) {
                        set_post_thumbnail( $pid, $prev_thumb );
                    } else {
                        delete_post_thumbnail( $pid );
                    }
                }
                return array( 'success' => true );

            /* ---------- Media rollbacks ---------- */
            case 'media_metadata_restore':
                $mid = intval( isset( $entry['media_id'] ) ? $entry['media_id'] : 0 );
                if ( $mid <= 0 ) {
                    return array( 'success' => false, 'error' => 'Media ID nedostaje za rollback.' );
                }
                $media_data = array( 'ID' => $mid );
                if ( array_key_exists( 'previous_title', $entry ) ) {
                    $media_data['post_title'] = (string) $entry['previous_title'];
                }
                if ( array_key_exists( 'previous_caption', $entry ) ) {
                    $media_data['post_excerpt'] = (string) $entry['previous_caption'];
                }
                if ( array_key_exists( 'previous_description', $entry ) ) {
                    $media_data['post_content'] = (string) $entry['previous_description'];
                }
                wp_update_post( $media_data );
                if ( array_key_exists( 'previous_alt_text', $entry ) ) {
                    update_post_meta( $mid, '_wp_attachment_image_alt', (string) $entry['previous_alt_text'] );
                }
                return array( 'success' => true );
            case 'media_reattach':
                $mid = intval( isset( $entry['media_id'] ) ? $entry['media_id'] : 0 );
                $prev_parent = intval( isset( $entry['previous_parent_id'] ) ? $entry['previous_parent_id'] : 0 );
                if ( $mid > 0 && $prev_parent > 0 ) {
                    wp_update_post( array( 'ID' => $mid, 'post_parent' => $prev_parent ) );
                }
                return array( 'success' => true );

            /* ---------- Elementor widget rollbacks ---------- */
            case 'elementor_widget_restore':
                $ewid = intval( isset( $entry['post_id'] ) ? $entry['post_id'] : 0 );
                $widget_id = isset( $entry['widget_id'] ) ? (string) $entry['widget_id'] : '';
                $prev_settings = array_key_exists( 'previous_settings', $entry ) && is_array( $entry['previous_settings'] ) ? $entry['previous_settings'] : null;
                if ( $ewid <= 0 || '' === $widget_id || null === $prev_settings ) {
                    return array( 'success' => false, 'error' => 'Elementor widget rollback data nedostaje.' );
                }
                $raw = get_post_meta( $ewid, '_elementor_data', true );
                $data = json_decode( $raw, true );
                if ( ! is_array( $data ) ) {
                    return array( 'success' => false, 'error' => 'Elementor data nije validan JSON za rollback.' );
                }
                $found = false;
                $this->restore_elementor_widget_settings( $data, $widget_id, $prev_settings, $found );
                if ( ! $found ) {
                    return array( 'success' => false, 'error' => 'Widget ' . $widget_id . ' nije pronadjen za rollback.' );
                }
                $json = wp_json_encode( $data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES );
                update_post_meta( $ewid, '_elementor_data', wp_slash( $json ) );
                delete_post_meta( $ewid, '_elementor_css' );
                delete_post_meta( $ewid, '_elementor_element_cache' );
                return array( 'success' => true );

            case 'elementor_page_data_restore':
                $epid = intval( isset( $entry['post_id'] ) ? $entry['post_id'] : 0 );
                if ( $epid <= 0 || ! array_key_exists( 'previous_elementor_data', $entry ) ) {
                    return array( 'success' => false, 'error' => 'Elementor page data rollback data nedostaje.' );
                }
                update_post_meta( $epid, '_elementor_data', wp_slash( (string) $entry['previous_elementor_data'] ) );
                if ( ! empty( $entry['post_content_was_changed'] ) && array_key_exists( 'previous_post_content', $entry ) ) {
                    wp_update_post(
                        array(
                            'ID'           => $epid,
                            'post_content' => (string) $entry['previous_post_content'],
                        )
                    );
                }
                delete_post_meta( $epid, '_elementor_css' );
                delete_post_meta( $epid, '_elementor_element_cache' );
                clean_post_cache( $epid );
                return array( 'success' => true );

            case 'elementor_kit_settings_restore':
                $ekid = intval( isset( $entry['kit_id'] ) ? $entry['kit_id'] : 0 );
                if ( $ekid <= 0 || ! array_key_exists( 'previous_page_settings', $entry ) || ! is_array( $entry['previous_page_settings'] ) ) {
                    return array( 'success' => false, 'error' => 'Elementor kit rollback data nedostaje.' );
                }
                update_post_meta( $ekid, '_elementor_page_settings', $entry['previous_page_settings'] );
                delete_post_meta( $ekid, '_elementor_css' );
                delete_post_meta( $ekid, '_elementor_element_cache' );
                if ( class_exists( '\Elementor\Plugin' ) ) {
                    \Elementor\Plugin::$instance->files_manager->clear_cache();
                }
                clean_post_cache( $ekid );
                return array( 'success' => true );
        }

        return array(
            'success' => false,
            'error'   => 'Nepodrzan rollback entry type.',
        );
    }

    /**
     * Recursively restore Elementor widget settings by ID.
     *
     * @param array  &$elements       Elementor data tree (modified in place).
     * @param string $widget_id       Widget ID to find.
     * @param array  $prev_settings   Previous settings to restore.
     * @param bool   &$found          Set to true when widget is found.
     * @param int    $depth           Recursion guard.
     */
    private function restore_elementor_widget_settings( &$elements, $widget_id, $prev_settings, &$found, $depth = 0 ) {
        if ( ! is_array( $elements ) || $depth > 20 || $found ) {
            return;
        }
        foreach ( $elements as &$el ) {
            if ( ! is_array( $el ) ) {
                continue;
            }
            if ( isset( $el['id'] ) && (string) $el['id'] === $widget_id ) {
                $el['settings'] = $prev_settings;
                $found          = true;
                return;
            }
            if ( isset( $el['elements'] ) && is_array( $el['elements'] ) ) {
                $this->restore_elementor_widget_settings( $el['elements'], $widget_id, $prev_settings, $found, $depth + 1 );
                if ( $found ) {
                    return;
                }
            }
        }
        unset( $el );
    }
}
