<?php

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

trait Niwa_AI_Tools_Woo_Orders {

    /* ==================================================================
     *  WooCommerce Orders & Reports — Read-only tools
     * ================================================================== */

    /* ------------------------------------------------------------------
     *  Internal helper: Execute WooCommerce REST API report request.
     * ------------------------------------------------------------------ */

    private function execute_woo_rest_report( $endpoint, $params = array() ) {
        $request = new \WP_REST_Request( 'GET', $endpoint );
        foreach ( $params as $key => $value ) {
            $request->set_param( $key, $value );
        }

        $response = rest_do_request( $request );

        if ( $response->is_error() ) {
            $error = $response->as_error();
            return array(
                'success' => false,
                'error'   => 'WooCommerce report error: ' . $error->get_error_message(),
            );
        }

        return array(
            'success' => true,
            'data'    => $response->get_data(),
        );
    }

    /* ------------------------------------------------------------------
     *  1. search_woo_orders — Search / list WooCommerce orders
     * ------------------------------------------------------------------ */

    private function normalize_posta_epk_order_ids( $raw ) {
        $ids  = array();
        $seen = array();

        $values = is_array( $raw ) ? $raw : array( $raw );
        foreach ( $values as $value ) {
            if ( is_array( $value ) ) {
                foreach ( $this->normalize_posta_epk_order_ids( $value ) as $nested_id ) {
                    if ( isset( $seen[ $nested_id ] ) ) {
                        continue;
                    }
                    $seen[ $nested_id ] = true;
                    $ids[]              = $nested_id;
                }
                continue;
            }

            preg_match_all( '/\d+/', (string) $value, $matches );
            foreach ( isset( $matches[0] ) ? $matches[0] : array() as $match ) {
                $id = max( 0, intval( $match ) );
                if ( $id <= 0 || isset( $seen[ $id ] ) ) {
                    continue;
                }
                $seen[ $id ] = true;
                $ids[]       = $id;
            }
        }

        return $ids;
    }

    private function preview_posta_epk_submit_orders( $args ) {
        $order_ids = $this->normalize_posta_epk_order_ids( isset( $args['order_ids'] ) ? $args['order_ids'] : ( isset( $args['orders'] ) ? $args['orders'] : array() ) );
        if ( empty( $order_ids ) ) {
            return array(
                'success' => false,
                'error'   => 'Nisu navedeni WooCommerce order ID-jevi za Posta EPK slanje.',
            );
        }

        if ( count( $order_ids ) > 40 ) {
            return array(
                'success' => false,
                'error'   => 'Posta EPK slanje je ograniceno na 40 porudzbina po jednoj akciji.',
            );
        }

        if ( ! class_exists( 'WooCommerce' ) || ! function_exists( 'wc_get_order' ) ) {
            return array(
                'success' => false,
                'error'   => 'WooCommerce nije aktivan na ovom sajtu.',
            );
        }

        if ( ! class_exists( 'Posta_EPK_Plugin' ) || ! class_exists( 'Posta_EPK_Order_Sync' ) ) {
            return array(
                'success' => false,
                'error'   => 'Posta EPK Connector plugin nije aktivan ili nije ucitan.',
            );
        }

        $force_resend = ! empty( $args['force_resend'] );
        $dry_run      = ! empty( $args['dry_run'] );
        $chunks       = array_chunk( $order_ids, 4 );
        $summary      = 1 === count( $order_ids )
            ? 'Slanje WooCommerce porudzbine #' . $order_ids[0] . ' kroz Posta EPK Connector.'
            : 'Batch slanje ' . count( $order_ids ) . ' WooCommerce porudzbina kroz Posta EPK Connector u ' . count( $chunks ) . ' grupa (maksimum 4 po PDF adresnici).';

        if ( $force_resend ) {
            $summary .= ' Force resend je ukljucen.';
        }
        if ( $dry_run ) {
            $summary .= ' Dry-run: bez stvarnog slanja.';
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'posta_epk_submit_orders',
                'label'            => 'Posta EPK slanje porudzbina',
                'summary'          => $summary,
                'risk'             => 'high',
                'rollback_plan'    => 'Nema rollback-a za slanje posiljke kuriru; neuspele porudzbine ostaju za retry.',
                'rollback_support' => 'none',
                'targets'          => array_map(
                    function ( $order_id ) {
                        return array(
                            'type'     => 'shop_order',
                            'order_id' => (int) $order_id,
                        );
                    },
                    $order_ids
                ),
                'args'             => array(
                    'order_ids'    => $order_ids,
                    'force_resend' => $force_resend,
                    'dry_run'      => $dry_run,
                ),
            ),
        );
    }

    private function validate_posta_epk_submit_orders_action_args( $args ) {
        $order_ids = $this->normalize_posta_epk_order_ids( isset( $args['order_ids'] ) ? $args['order_ids'] : ( isset( $args['orders'] ) ? $args['orders'] : array() ) );
        if ( empty( $order_ids ) ) {
            return array(
                'success' => false,
                'error'   => 'Nedostaju WooCommerce order ID-jevi za Posta EPK slanje.',
            );
        }
        if ( count( $order_ids ) > 40 ) {
            return array(
                'success' => false,
                'error'   => 'Posta EPK slanje je ograniceno na 40 porudzbina po jednoj akciji.',
            );
        }

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

    private function execute_posta_epk_submit_orders_action( $action ) {
        $args         = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $order_ids    = $this->normalize_posta_epk_order_ids( isset( $args['order_ids'] ) ? $args['order_ids'] : ( isset( $args['orders'] ) ? $args['orders'] : array() ) );
        $force_resend = ! empty( $args['force_resend'] );
        $dry_run      = ! empty( $args['dry_run'] );

        if ( empty( $order_ids ) ) {
            return array(
                'success' => false,
                'error'   => 'Nedostaju WooCommerce order ID-jevi za Posta EPK slanje.',
            );
        }

        if ( ! class_exists( 'WooCommerce' ) || ! function_exists( 'wc_get_order' ) ) {
            return array(
                'success' => false,
                'error'   => 'WooCommerce nije aktivan na ovom sajtu.',
            );
        }

        $service = $this->get_posta_epk_order_sync_service();
        if ( empty( $service['success'] ) ) {
            return $service;
        }

        $order_sync = $service['order_sync'];
        $data       = array(
            'input_orders' => $order_ids,
            'force_resend' => $force_resend,
            'dry_run'      => $dry_run,
            'submitted'    => array(),
            'skipped'      => array(),
            'failed'       => array(),
            'batches'      => array(),
            'batch_emails' => 0,
            'email_errors' => array(),
        );

        if ( 1 === count( $order_ids ) ) {
            $this->execute_posta_epk_single_order( $order_sync, (int) $order_ids[0], $force_resend, $dry_run, $data );
        } else {
            foreach ( array_chunk( $order_ids, 4 ) as $chunk_index => $chunk ) {
                $this->execute_posta_epk_batch_chunk( $order_sync, $chunk, $chunk_index + 1, $force_resend, $dry_run, $data );
            }
        }

        $submitted_count = count( $data['submitted'] );
        $failed_count    = count( $data['failed'] ) + count( $data['email_errors'] );
        $skipped_count   = count( $data['skipped'] );

        $summary_parts = array(
            'Posta EPK obrada zavrsena: poslato ' . $submitted_count . ', preskoceno ' . $skipped_count . ', neuspesno ' . $failed_count . ', PDF emailova za stampu ' . (int) $data['batch_emails'] . '.',
        );
        if ( ! empty( $data['submitted'] ) ) {
            $summary_parts[] = 'Poslato: ' . implode( ', ', array_map(
                function ( $entry ) {
                    $label = '#' . ( isset( $entry['order_id'] ) ? (int) $entry['order_id'] : 0 );
                    if ( ! empty( $entry['billing_email'] ) ) {
                        $label .= ' <' . (string) $entry['billing_email'] . '>';
                    }
                    return $label;
                },
                $data['submitted']
            ) ) . '.';
        }
        if ( ! empty( $data['skipped'] ) ) {
            $summary_parts[] = 'Preskoceno: ' . implode( ', ', array_map(
                function ( $entry ) {
                    return '#' . ( isset( $entry['order_id'] ) ? (int) $entry['order_id'] : 0 ) . ' (' . ( isset( $entry['reason'] ) ? (string) $entry['reason'] : 'preskoceno' ) . ')';
                },
                $data['skipped']
            ) ) . '.';
        }
        if ( ! empty( $data['failed'] ) ) {
            $summary_parts[] = 'Neuspesno: ' . implode( ', ', array_map(
                function ( $entry ) {
                    return '#' . ( isset( $entry['order_id'] ) ? (int) $entry['order_id'] : 0 ) . ' (' . ( isset( $entry['message'] ) ? (string) $entry['message'] : 'greska' ) . ')';
                },
                $data['failed']
            ) ) . '.';
        }
        if ( ! empty( $data['email_errors'] ) ) {
            $summary_parts[] = 'PDF email greske: ' . implode( ', ', array_map(
                function ( $entry ) {
                    return 'batch ' . ( isset( $entry['batch_index'] ) ? (int) $entry['batch_index'] : 0 ) . ' (' . ( isset( $entry['message'] ) ? (string) $entry['message'] : 'greska' ) . ')';
                },
                $data['email_errors']
            ) ) . '.';
        }

        $summary = implode( ' ', $summary_parts );
        if ( $dry_run ) {
            $summary = 'Posta EPK dry-run zavrsen: za slanje ' . $submitted_count . ', preskoceno ' . $skipped_count . ', neuspesno ' . $failed_count . '.';
        }

        return array(
            'success'          => true,
            'summary'          => $summary,
            'data'             => $data,
            'executed_actions' => $submitted_count > 0 ? array(
                array(
                    'type'      => 'posta_epk_submit_orders',
                    'order_ids' => array_values(
                        array_filter(
                            array_map(
                                function ( $entry ) {
                                    return isset( $entry['order_id'] ) ? (int) $entry['order_id'] : 0;
                                },
                                $data['submitted']
                            )
                        )
                    ),
                ),
            ) : array(),
            'rollback_entries' => array(),
        );
    }

    private function execute_posta_epk_single_order( $order_sync, $order_id, $force_resend, $dry_run, &$data ) {
        $order = wc_get_order( (int) $order_id );
        if ( ! $order instanceof WC_Order ) {
            $data['failed'][] = array(
                'order_id' => (int) $order_id,
                'message'  => 'Porudzbina nije pronadjena.',
            );
            return;
        }

        $skip = $this->maybe_skip_posta_epk_resend( $order, $force_resend );
        if ( $skip ) {
            $data['skipped'][] = $skip;
            return;
        }

        $customer = $this->get_posta_epk_order_customer_payload( $order );
        if ( $dry_run ) {
            $data['submitted'][] = array_merge(
                $customer,
                array(
                    'order_id' => (int) $order_id,
                    'status'   => 'would_submit_immediately',
                )
            );
            return;
        }

        $result = $this->posta_epk_call_private_method( $order_sync, 'sync_order', array( $order, true, 'single' ) );
        if ( $this->posta_epk_is_error( $result ) ) {
            $data['failed'][] = $this->posta_epk_error_payload( $result, (int) $order_id );
            return;
        }

        $data['submitted'][] = array_merge(
            $customer,
            array(
                'order_id' => (int) $order_id,
                'status'   => 'submitted',
                'mode'     => 'single',
            )
        );
    }

    private function execute_posta_epk_batch_chunk( $order_sync, $chunk, $chunk_index, $force_resend, $dry_run, &$data ) {
        $batch = array(
            'index'     => (int) $chunk_index,
            'order_ids' => array_values( array_map( 'intval', $chunk ) ),
            'submitted' => array(),
            'skipped'   => array(),
            'failed'    => array(),
        );

        $labels       = array();
        $batch_orders = array();

        foreach ( $chunk as $order_id ) {
            $order = wc_get_order( (int) $order_id );
            if ( ! $order instanceof WC_Order ) {
                $failure = array(
                    'order_id' => (int) $order_id,
                    'message'  => 'Porudzbina nije pronadjena.',
                );
                $batch['failed'][] = $failure;
                $data['failed'][]  = $failure;
                continue;
            }

            $skip = $this->maybe_skip_posta_epk_resend( $order, $force_resend );
            if ( $skip ) {
                $batch['skipped'][] = $skip;
                $data['skipped'][]  = $skip;
                continue;
            }

            $customer = $this->get_posta_epk_order_customer_payload( $order );
            if ( $dry_run ) {
                $submitted = array_merge(
                    $customer,
                    array(
                        'order_id' => (int) $order_id,
                        'status'   => 'would_submit_in_batch',
                    )
                );
                $batch['submitted'][] = $submitted;
                $data['submitted'][]  = $submitted;
                continue;
            }

            $result = $this->posta_epk_has_private_method( $order_sync, 'sync_buffered_order_with_retry' )
                ? $this->posta_epk_call_private_method( $order_sync, 'sync_buffered_order_with_retry', array( $order ) )
                : $this->posta_epk_call_private_method( $order_sync, 'sync_order', array( $order, true, 'batch' ) );

            if ( $this->posta_epk_is_error( $result ) ) {
                $failure = $this->posta_epk_error_payload( $result, (int) $order_id );
                $batch['failed'][] = $failure;
                $data['failed'][]  = $failure;
                continue;
            }

            if ( is_array( $result ) && isset( $result['label_payload'] ) && is_array( $result['label_payload'] ) ) {
                $labels[]       = $result['label_payload'];
                $batch_orders[] = $order;
            }

            $submitted = array_merge(
                $customer,
                array(
                    'order_id' => (int) $order_id,
                    'status'   => 'submitted',
                    'mode'     => 'batch',
                )
            );
            $batch['submitted'][] = $submitted;
            $data['submitted'][]  = $submitted;
        }

        if ( ! $dry_run && ! empty( $labels ) ) {
            $mail_result = $this->posta_epk_call_private_method( $order_sync, 'generate_and_send_batch_label_pdf', array( $labels, $batch_orders ) );
            if ( $this->posta_epk_is_error( $mail_result ) ) {
                $error = $this->posta_epk_error_payload( $mail_result, 0 );
                $batch['email_error']   = $error['message'];
                $data['email_errors'][] = array(
                    'batch_index' => (int) $chunk_index,
                    'message'     => $error['message'],
                );
            } else {
                $batch['email_status'] = 'sent';
                ++$data['batch_emails'];
            }
        } elseif ( $dry_run && ! empty( $batch['submitted'] ) ) {
            $batch['email_status'] = 'would_send_one_pdf_if_labels_are_generated';
        }

        $data['batches'][] = $batch;
    }

    private function maybe_skip_posta_epk_resend( $order, $force_resend ) {
        if ( $force_resend || ! is_object( $order ) || ! method_exists( $order, 'get_meta' ) || ! method_exists( $order, 'get_id' ) ) {
            return null;
        }

        $status = (string) $order->get_meta( '_posta_epk_status', true );
        if ( 'success' !== strtolower( $status ) ) {
            return null;
        }

        return array(
            'order_id' => (int) $order->get_id(),
            'reason'   => 'Porudzbina vec ima _posta_epk_status=success. Koristi force_resend samo ako founder eksplicitno trazi ponovno slanje.',
        );
    }

    private function get_posta_epk_order_customer_payload( $order ) {
        $first = is_object( $order ) && method_exists( $order, 'get_billing_first_name' ) ? (string) $order->get_billing_first_name() : '';
        $last  = is_object( $order ) && method_exists( $order, 'get_billing_last_name' ) ? (string) $order->get_billing_last_name() : '';

        return array(
            'customer_name' => trim( $first . ' ' . $last ),
            'billing_email' => is_object( $order ) && method_exists( $order, 'get_billing_email' ) ? (string) $order->get_billing_email() : '',
            'order_status'  => is_object( $order ) && method_exists( $order, 'get_status' ) ? (string) $order->get_status() : '',
        );
    }

    private function get_posta_epk_order_sync_service() {
        if ( ! class_exists( 'Posta_EPK_Plugin' ) || ! class_exists( 'Posta_EPK_Order_Sync' ) ) {
            return array(
                'success' => false,
                'error'   => 'Posta EPK Connector plugin nije aktivan ili nije ucitan.',
            );
        }

        if ( ! method_exists( 'Posta_EPK_Plugin', 'instance' ) ) {
            return array(
                'success' => false,
                'error'   => 'Posta EPK Connector nema dostupnu instance() metodu.',
            );
        }

        $plugin = Posta_EPK_Plugin::instance();
        if ( ! is_object( $plugin ) ) {
            return array(
                'success' => false,
                'error'   => 'Posta EPK Connector instanca nije dostupna.',
            );
        }

        $order_sync = $this->posta_epk_get_private_property( $plugin, 'order_sync' );
        if ( ! $order_sync instanceof Posta_EPK_Order_Sync ) {
            return array(
                'success' => false,
                'error'   => 'Ne mogu da pristupim Posta EPK order sync servisu.',
            );
        }

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

    private function posta_epk_get_private_property( $object, $property ) {
        if ( ! is_object( $object ) ) {
            return null;
        }

        $reflection = new ReflectionObject( $object );
        while ( ! $reflection->hasProperty( $property ) && $reflection->getParentClass() ) {
            $reflection = $reflection->getParentClass();
        }

        if ( ! $reflection->hasProperty( $property ) ) {
            return null;
        }

        $prop = $reflection->getProperty( $property );
        $prop->setAccessible( true );

        return $prop->getValue( $object );
    }

    private function posta_epk_has_private_method( $object, $method ) {
        if ( ! is_object( $object ) ) {
            return false;
        }

        $reflection = new ReflectionObject( $object );
        while ( ! $reflection->hasMethod( $method ) && $reflection->getParentClass() ) {
            $reflection = $reflection->getParentClass();
        }

        return $reflection->hasMethod( $method );
    }

    private function posta_epk_call_private_method( $object, $method, $args = array() ) {
        if ( ! is_object( $object ) ) {
            return $this->posta_epk_error_object( 'posta_epk_invalid_service', 'Posta EPK servis nije validan objekat.' );
        }

        $reflection = new ReflectionObject( $object );
        while ( ! $reflection->hasMethod( $method ) && $reflection->getParentClass() ) {
            $reflection = $reflection->getParentClass();
        }

        if ( ! $reflection->hasMethod( $method ) ) {
            return $this->posta_epk_error_object( 'posta_epk_missing_method', 'Posta EPK metoda nije dostupna: ' . $method );
        }

        $ref_method = $reflection->getMethod( $method );
        $ref_method->setAccessible( true );

        return $ref_method->invokeArgs( $object, (array) $args );
    }

    private function posta_epk_error_object( $code, $message ) {
        if ( class_exists( 'WP_Error' ) ) {
            return new WP_Error( $code, $message );
        }

        return array(
            '_niwa_error' => true,
            'code'        => (string) $code,
            'message'     => (string) $message,
        );
    }

    private function posta_epk_is_error( $value ) {
        if ( function_exists( 'is_wp_error' ) && is_wp_error( $value ) ) {
            return true;
        }

        return is_array( $value ) && ! empty( $value['_niwa_error'] );
    }

    private function posta_epk_error_payload( $error, $order_id ) {
        if ( function_exists( 'is_wp_error' ) && is_wp_error( $error ) ) {
            return array(
                'order_id' => (int) $order_id,
                'message'  => $error->get_error_message(),
                'code'     => $error->get_error_code(),
            );
        }

        return array(
            'order_id' => (int) $order_id,
            'message'  => isset( $error['message'] ) ? (string) $error['message'] : 'Nepoznata Posta EPK greska.',
            'code'     => isset( $error['code'] ) ? (string) $error['code'] : '',
        );
    }

    private function preview_search_woo_orders( $args ) {
        if ( ! class_exists( 'WooCommerce' ) ) {
            return array(
                'success' => false,
                'error'   => 'WooCommerce nije aktivan na ovom sajtu.',
            );
        }

        $status  = isset( $args['status'] ) ? sanitize_text_field( (string) $args['status'] ) : 'any';
        $allowed_statuses = array( 'pending', 'processing', 'on-hold', 'completed', 'cancelled', 'refunded', 'failed', 'any' );
        if ( ! in_array( $status, $allowed_statuses, true ) ) {
            $status = 'any';
        }

        $customer = isset( $args['customer'] ) ? intval( $args['customer'] ) : 0;
        $per_page = isset( $args['per_page'] ) ? max( 1, min( 50, intval( $args['per_page'] ) ) ) : 10;
        $page     = isset( $args['page'] ) ? max( 1, intval( $args['page'] ) ) : 1;
        $after    = isset( $args['after'] ) ? sanitize_text_field( (string) $args['after'] ) : '';
        $before   = isset( $args['before'] ) ? sanitize_text_field( (string) $args['before'] ) : '';
        $orderby  = isset( $args['orderby'] ) && in_array( (string) $args['orderby'], array( 'date', 'id', 'total' ), true )
            ? (string) $args['orderby']
            : 'date';
        $order    = isset( $args['order'] ) && in_array( strtolower( (string) $args['order'] ), array( 'asc', 'desc' ), true )
            ? strtolower( (string) $args['order'] )
            : 'desc';

        $summary_parts   = array();
        $summary_parts[] = 'Pretraga WooCommerce porudzbina';
        $summary_parts[] = 'Status: ' . $status;
        $summary_parts[] = 'Strana: ' . $page . ', po stranici: ' . $per_page;
        if ( $customer > 0 ) {
            $summary_parts[] = 'Kupac ID: ' . $customer;
        }
        if ( '' !== $after ) {
            $summary_parts[] = 'Posle: ' . $after;
        }
        if ( '' !== $before ) {
            $summary_parts[] = 'Pre: ' . $before;
        }
        $summary_parts[] = 'Sortiranje: ' . $orderby . ' ' . $order;

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'search_woo_orders',
                'label'            => 'Pretrazi WooCommerce porudzbine',
                'summary'          => implode( ' | ', $summary_parts ),
                'rollback_plan'    => 'Read-only operation, no rollback needed.',
                'rollback_support' => 'none',
                'targets'          => array(),
                'args'             => array(
                    'status'   => $status,
                    'customer' => $customer,
                    'per_page' => $per_page,
                    'page'     => $page,
                    'after'    => $after,
                    'before'   => $before,
                    'orderby'  => $orderby,
                    'order'    => $order,
                ),
            ),
        );
    }

    private function execute_search_woo_orders_action( $action ) {
        if ( ! class_exists( 'WooCommerce' ) ) {
            return array(
                'success' => false,
                'error'   => 'WooCommerce nije aktivan na ovom sajtu.',
            );
        }

        $args = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();

        $status   = isset( $args['status'] ) ? (string) $args['status'] : 'any';
        $customer = isset( $args['customer'] ) ? intval( $args['customer'] ) : 0;
        $per_page = isset( $args['per_page'] ) ? max( 1, min( 50, intval( $args['per_page'] ) ) ) : 10;
        $page     = isset( $args['page'] ) ? max( 1, intval( $args['page'] ) ) : 1;
        $after    = isset( $args['after'] ) ? (string) $args['after'] : '';
        $before   = isset( $args['before'] ) ? (string) $args['before'] : '';
        $orderby  = isset( $args['orderby'] ) ? (string) $args['orderby'] : 'date';
        $order    = isset( $args['order'] ) ? (string) $args['order'] : 'desc';

        $query_args = array(
            'limit'   => $per_page,
            'page'    => $page,
            'orderby' => $orderby,
            'order'   => $order,
            'return'  => 'objects',
        );

        if ( 'any' !== $status ) {
            $query_args['status'] = $status;
        }

        if ( $customer > 0 ) {
            $query_args['customer_id'] = $customer;
        }

        if ( '' !== $after ) {
            $query_args['date_created'] = '>=' . $after;
        }

        if ( '' !== $before ) {
            if ( isset( $query_args['date_created'] ) ) {
                $query_args['date_created'] .= '...' . $before;
            } else {
                $query_args['date_created'] = '<=' . $before;
            }
        }

        $orders      = wc_get_orders( $query_args );
        $orders_data = array();

        foreach ( $orders as $wc_order ) {
            if ( ! is_a( $wc_order, 'WC_Order' ) ) {
                continue;
            }

            $line_items = array();
            foreach ( $wc_order->get_items() as $item ) {
                $line_items[] = array(
                    'product_name' => (string) $item->get_name(),
                    'quantity'     => intval( $item->get_quantity() ),
                    'total'        => (string) $item->get_total(),
                );
            }

            $billing_first = '';
            $billing_last  = '';
            $billing_email = '';

            if ( method_exists( $wc_order, 'get_billing_first_name' ) ) {
                $billing_first = (string) $wc_order->get_billing_first_name();
            }
            if ( method_exists( $wc_order, 'get_billing_last_name' ) ) {
                $billing_last = (string) $wc_order->get_billing_last_name();
            }
            if ( method_exists( $wc_order, 'get_billing_email' ) ) {
                $billing_email = (string) $wc_order->get_billing_email();
            }

            $customer_name = trim( $billing_first . ' ' . $billing_last );

            $date_created  = $wc_order->get_date_created();
            $date_modified = $wc_order->get_date_modified();

            $orders_data[] = array(
                'id'                   => intval( $wc_order->get_id() ),
                'status'               => (string) $wc_order->get_status(),
                'date_created'         => $date_created ? $date_created->date( 'Y-m-d H:i:s' ) : '',
                'date_modified'        => $date_modified ? $date_modified->date( 'Y-m-d H:i:s' ) : '',
                'total'                => (string) $wc_order->get_total(),
                'currency'             => (string) $wc_order->get_currency(),
                'customer_id'          => intval( $wc_order->get_customer_id() ),
                'customer_name'        => $customer_name,
                'billing_email'        => $billing_email,
                'payment_method'       => (string) $wc_order->get_payment_method(),
                'payment_method_title' => (string) $wc_order->get_payment_method_title(),
                'items_count'          => count( $line_items ),
                'line_items'           => $line_items,
            );
        }

        return array(
            'success'          => true,
            'summary'          => 'Pronadjeno ' . count( $orders_data ) . ' porudzbina (strana ' . $page . ').',
            'data'             => array(
                'orders' => $orders_data,
                'count'  => count( $orders_data ),
                'page'   => $page,
            ),
            'executed_actions' => array(
                array(
                    'type' => 'search_woo_orders',
                ),
            ),
            'rollback_entries' => array(),
        );
    }

    private function preview_inspect_order_attribution( $args ) {
        if ( ! class_exists( 'WooCommerce' ) ) {
            return array(
                'success' => false,
                'error'   => 'WooCommerce nije aktivan na ovom sajtu.',
            );
        }

        $order_ids      = $this->normalize_order_attribution_order_ids( isset( $args['order_ids'] ) ? $args['order_ids'] : array() );
        $customer_names = $this->normalize_order_attribution_customer_names( isset( $args['customer_names'] ) ? $args['customer_names'] : array() );
        if ( empty( $order_ids ) && empty( $customer_names ) ) {
            return array(
                'success' => false,
                'error'   => 'order_ids ili customer_names su obavezni za proveru atribucije konkretnih porudzbina.',
            );
        }

        $after          = isset( $args['after'] ) ? sanitize_text_field( (string) $args['after'] ) : '';
        $before         = isset( $args['before'] ) ? sanitize_text_field( (string) $args['before'] ) : '';
        $limit          = isset( $args['limit'] ) ? max( 1, min( 20, intval( $args['limit'] ) ) ) : 10;
        $include_events = ! array_key_exists( 'include_events', $args ) || ! empty( $args['include_events'] );
        $event_limit    = isset( $args['event_limit'] ) ? max( 0, min( 20, intval( $args['event_limit'] ) ) ) : 10;

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'inspect_order_attribution',
                'label'            => 'Proveri atribuciju porudzbina',
                'summary'          => 'Read-only provera order meta + Niwa traffic attribution za konkretne porudzbine.',
                'rollback_plan'    => 'Read-only operation, no rollback needed.',
                'rollback_support' => 'none',
                'targets'          => $order_ids,
                'args'             => array(
                    'order_ids'      => $order_ids,
                    'customer_names' => $customer_names,
                    'after'          => $after,
                    'before'         => $before,
                    'limit'          => $limit,
                    'include_events' => $include_events,
                    'event_limit'    => $event_limit,
                ),
            ),
        );
    }

    private function execute_inspect_order_attribution_action( $action ) {
        if ( ! class_exists( 'WooCommerce' ) ) {
            return array(
                'success' => false,
                'error'   => 'WooCommerce nije aktivan na ovom sajtu.',
            );
        }

        $args           = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $order_ids      = $this->normalize_order_attribution_order_ids( isset( $args['order_ids'] ) ? $args['order_ids'] : array() );
        $customer_names = $this->normalize_order_attribution_customer_names( isset( $args['customer_names'] ) ? $args['customer_names'] : array() );
        $after          = isset( $args['after'] ) ? sanitize_text_field( (string) $args['after'] ) : '';
        $before         = isset( $args['before'] ) ? sanitize_text_field( (string) $args['before'] ) : '';
        $limit          = isset( $args['limit'] ) ? max( 1, min( 20, intval( $args['limit'] ) ) ) : 10;
        $include_events = ! array_key_exists( 'include_events', $args ) || ! empty( $args['include_events'] );
        $event_limit    = isset( $args['event_limit'] ) ? max( 0, min( 20, intval( $args['event_limit'] ) ) ) : 10;

        $orders = $this->resolve_order_attribution_orders( $order_ids, $customer_names, $after, $before, $limit );
        $rows   = array();
        foreach ( $orders as $order ) {
            if ( is_a( $order, 'WC_Order' ) ) {
                $rows[] = $this->build_order_attribution_evidence( $order, $include_events, $event_limit );
            }
        }

        return array(
            'success'          => true,
            'summary'          => 'Provereno ' . count( $rows ) . ' porudzbina za attribution evidence.',
            'data'             => array(
                'orders' => $rows,
                'count'  => count( $rows ),
                'inputs' => array(
                    'order_ids'      => $order_ids,
                    'customer_names' => $customer_names,
                    'after'          => $after,
                    'before'         => $before,
                ),
            ),
            'executed_actions' => array(
                array(
                    'type' => 'inspect_order_attribution',
                ),
            ),
            'rollback_entries' => array(),
        );
    }

    private function normalize_order_attribution_order_ids( $raw ) {
        $raw = is_array( $raw ) ? $raw : array( $raw );
        $ids = array();
        foreach ( $raw as $id ) {
            $id = absint( $id );
            if ( $id > 0 ) {
                $ids[] = $id;
            }
        }

        return array_slice( array_values( array_unique( $ids ) ), 0, 20 );
    }

    private function normalize_order_attribution_customer_names( $raw ) {
        $raw   = is_array( $raw ) ? $raw : array( $raw );
        $names = array();
        foreach ( $raw as $name ) {
            $name = trim( sanitize_text_field( (string) $name ) );
            if ( '' !== $name ) {
                $names[] = $name;
            }
        }

        return array_slice( array_values( array_unique( $names ) ), 0, 10 );
    }

    private function resolve_order_attribution_orders( $order_ids, $customer_names, $after, $before, $limit ) {
        $orders = array();
        foreach ( $order_ids as $order_id ) {
            $order = function_exists( 'wc_get_order' ) ? wc_get_order( $order_id ) : false;
            if ( is_a( $order, 'WC_Order' ) ) {
                $orders[ $order->get_id() ] = $order;
            }
        }

        if ( ! empty( $customer_names ) && count( $orders ) < $limit && function_exists( 'wc_get_orders' ) ) {
            $query_args = array(
                'limit'   => 100,
                'orderby' => 'date',
                'order'   => 'desc',
                'return'  => 'objects',
            );
            if ( '' !== $after ) {
                $query_args['date_created'] = '>=' . $after;
            }
            if ( '' !== $before ) {
                $query_args['date_created'] = isset( $query_args['date_created'] ) ? $query_args['date_created'] . '...' . $before : '<=' . $before;
            }

            foreach ( wc_get_orders( $query_args ) as $order ) {
                if ( ! is_a( $order, 'WC_Order' ) || isset( $orders[ $order->get_id() ] ) ) {
                    continue;
                }
                $name = trim( (string) $order->get_billing_first_name() . ' ' . (string) $order->get_billing_last_name() );
                if ( $this->order_attribution_name_matches( $name, $customer_names ) ) {
                    $orders[ $order->get_id() ] = $order;
                }
                if ( count( $orders ) >= $limit ) {
                    break;
                }
            }
        }

        return array_slice( array_values( $orders ), 0, $limit );
    }

    private function order_attribution_name_matches( $billing_name, $customer_names ) {
        $billing_name = $this->normalize_order_attribution_match_text( $billing_name );
        if ( '' === $billing_name ) {
            return false;
        }
        foreach ( $customer_names as $name ) {
            $needle = $this->normalize_order_attribution_match_text( $name );
            if ( '' !== $needle && ( $billing_name === $needle || false !== strpos( $billing_name, $needle ) || false !== strpos( $needle, $billing_name ) ) ) {
                return true;
            }
        }

        return false;
    }

    private function normalize_order_attribution_match_text( $text ) {
        $text = function_exists( 'remove_accents' ) ? remove_accents( (string) $text ) : (string) $text;
        $text = function_exists( 'mb_strtolower' ) ? mb_strtolower( $text, 'UTF-8' ) : strtolower( $text );
        return trim( preg_replace( '/\s+/', ' ', $text ) );
    }

    private function build_order_attribution_evidence( $order, $include_events, $event_limit ) {
        $session_meta_key = class_exists( 'Niwa_AI_Traffic_Conversion_Tracker' ) ? Niwa_AI_Traffic_Conversion_Tracker::ORDER_SESSION_META : '_niwa_ai_traffic_session';
        $attr_meta_key    = class_exists( 'Niwa_AI_Traffic_Conversion_Tracker' ) ? Niwa_AI_Traffic_Conversion_Tracker::ORDER_ATTR_META : '_niwa_ai_traffic_attribution';
        $session_id       = method_exists( $order, 'get_meta' ) ? sanitize_text_field( (string) $order->get_meta( $session_meta_key, true ) ) : '';
        $niwa_attr        = $this->decode_order_attribution_meta( method_exists( $order, 'get_meta' ) ? $order->get_meta( $attr_meta_key, true ) : '' );
        $conversion       = $this->get_order_attribution_conversion_row( (int) $order->get_id() );
        if ( '' === $session_id && ! empty( $conversion['session_id'] ) ) {
            $session_id = sanitize_text_field( (string) $conversion['session_id'] );
        }

        $session     = '' !== $session_id ? $this->get_order_attribution_session_row( $session_id ) : array();
        $touchpoints = '' !== $session_id ? $this->get_order_attribution_touchpoints( $session_id, $event_limit ) : array();
        $events      = $include_events && '' !== $session_id ? $this->get_order_attribution_events( $session_id, $event_limit ) : array();
        $created     = method_exists( $order, 'get_date_created' ) ? $order->get_date_created() : null;

        return array(
            'order'               => array(
                'id'            => (int) $order->get_id(),
                'status'        => method_exists( $order, 'get_status' ) ? (string) $order->get_status() : '',
                'date_created'  => $created ? $created->date( 'Y-m-d H:i:s' ) : '',
                'total'         => method_exists( $order, 'get_total' ) ? (string) $order->get_total() : '',
                'currency'      => method_exists( $order, 'get_currency' ) ? (string) $order->get_currency() : '',
                'customer_name' => trim( (string) $order->get_billing_first_name() . ' ' . (string) $order->get_billing_last_name() ),
            ),
            'primary_attribution' => $this->summarize_order_attribution_source( $conversion, $session, $niwa_attr, $this->get_woo_order_attribution_meta( $order ) ),
            'order_meta'          => array(
                'niwa_session_id'    => $session_id,
                'niwa_attribution'   => $niwa_attr,
                'woo_attribution'    => $this->get_woo_order_attribution_meta( $order ),
            ),
            'niwa_conversion'     => $conversion,
            'niwa_session'        => $session,
            'niwa_touchpoints'    => $touchpoints,
            'niwa_events'         => $events,
        );
    }

    private function decode_order_attribution_meta( $raw ) {
        if ( is_array( $raw ) ) {
            return $raw;
        }
        $decoded = json_decode( (string) $raw, true );
        return is_array( $decoded ) ? $decoded : array();
    }

    private function get_woo_order_attribution_meta( $order ) {
        $keys = array(
            '_wc_order_attribution_source_type',
            '_wc_order_attribution_referrer',
            '_wc_order_attribution_utm_source',
            '_wc_order_attribution_utm_medium',
            '_wc_order_attribution_utm_campaign',
            '_wc_order_attribution_utm_content',
            '_wc_order_attribution_utm_term',
            '_wc_order_attribution_session_entry',
            '_wc_order_attribution_session_start_time',
            '_wc_order_attribution_session_pages',
            '_wc_order_attribution_session_count',
            '_wc_order_attribution_device_type',
        );
        $meta = array();
        foreach ( $keys as $key ) {
            $value = method_exists( $order, 'get_meta' ) ? $order->get_meta( $key, true ) : '';
            if ( '' !== (string) $value ) {
                $meta[ $key ] = is_scalar( $value ) ? sanitize_text_field( (string) $value ) : $value;
            }
        }

        return $meta;
    }

    private function summarize_order_attribution_source( $conversion, $session, $niwa_attr, $woo_attr ) {
        $source   = isset( $conversion['source'] ) ? (string) $conversion['source'] : '';
        $medium   = isset( $conversion['medium'] ) ? (string) $conversion['medium'] : '';
        $campaign = isset( $conversion['campaign'] ) ? (string) $conversion['campaign'] : '';
        $channel  = isset( $conversion['channel'] ) ? (string) $conversion['channel'] : '';
        $basis    = ! empty( $conversion ) ? 'niwa_conversion' : '';

        if ( '' === $source && ! empty( $session ) ) {
            $source   = isset( $session['last_source'] ) ? (string) $session['last_source'] : '';
            $medium   = isset( $session['last_medium'] ) ? (string) $session['last_medium'] : '';
            $campaign = isset( $session['last_campaign'] ) ? (string) $session['last_campaign'] : '';
            $channel  = isset( $session['last_channel'] ) ? (string) $session['last_channel'] : '';
            $basis    = 'niwa_session_last_touch';
        }
        if ( '' === $source && ! empty( $niwa_attr ) ) {
            $source   = isset( $niwa_attr['source'] ) ? (string) $niwa_attr['source'] : '';
            $medium   = isset( $niwa_attr['medium'] ) ? (string) $niwa_attr['medium'] : '';
            $campaign = isset( $niwa_attr['campaign'] ) ? (string) $niwa_attr['campaign'] : '';
            $channel  = isset( $niwa_attr['channel'] ) ? (string) $niwa_attr['channel'] : '';
            $basis    = 'niwa_order_meta';
        }
        if ( '' === $source && ! empty( $woo_attr ) ) {
            $source   = isset( $woo_attr['_wc_order_attribution_utm_source'] ) ? (string) $woo_attr['_wc_order_attribution_utm_source'] : '';
            $medium   = isset( $woo_attr['_wc_order_attribution_utm_medium'] ) ? (string) $woo_attr['_wc_order_attribution_utm_medium'] : '';
            $campaign = isset( $woo_attr['_wc_order_attribution_utm_campaign'] ) ? (string) $woo_attr['_wc_order_attribution_utm_campaign'] : '';
            $channel  = isset( $woo_attr['_wc_order_attribution_source_type'] ) ? (string) $woo_attr['_wc_order_attribution_source_type'] : '';
            $basis    = 'woocommerce_order_attribution';
        }

        return array(
            'source'   => sanitize_text_field( $source ),
            'medium'   => sanitize_text_field( $medium ),
            'campaign' => sanitize_text_field( $campaign ),
            'channel'  => sanitize_text_field( $channel ),
            'basis'    => sanitize_key( $basis ),
        );
    }

    private function get_order_attribution_conversion_row( $order_id ) {
        if ( ! class_exists( 'Niwa_AI_Traffic_DB' ) || ! $this->order_attribution_table_exists( Niwa_AI_Traffic_DB::CONVERSIONS ) ) {
            return array();
        }
        global $wpdb;
        $table = Niwa_AI_Traffic_DB::table( Niwa_AI_Traffic_DB::CONVERSIONS );
        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
        $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE order_id = %d ORDER BY occurred_at DESC LIMIT 1", $order_id ), ARRAY_A );
        return is_array( $row ) ? $row : array();
    }

    private function get_order_attribution_session_row( $session_id ) {
        if ( ! class_exists( 'Niwa_AI_Traffic_DB' ) || ! $this->order_attribution_table_exists( Niwa_AI_Traffic_DB::SESSIONS ) ) {
            return array();
        }
        global $wpdb;
        $table = Niwa_AI_Traffic_DB::table( Niwa_AI_Traffic_DB::SESSIONS );
        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
        $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE session_id = %s LIMIT 1", $session_id ), ARRAY_A );
        return is_array( $row ) ? $row : array();
    }

    private function get_order_attribution_touchpoints( $session_id, $limit ) {
        if ( $limit <= 0 || ! class_exists( 'Niwa_AI_Traffic_DB' ) || ! $this->order_attribution_table_exists( Niwa_AI_Traffic_DB::TOUCHPOINTS ) ) {
            return array();
        }
        global $wpdb;
        $table = Niwa_AI_Traffic_DB::table( Niwa_AI_Traffic_DB::TOUCHPOINTS );
        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
        $rows = $wpdb->get_results( $wpdb->prepare( "SELECT occurred_at,event_type,page_path,source,medium,campaign,channel FROM {$table} WHERE session_id = %s ORDER BY occurred_at ASC LIMIT %d", $session_id, $limit ), ARRAY_A );
        return is_array( $rows ) ? $rows : array();
    }

    private function get_order_attribution_events( $session_id, $limit ) {
        if ( $limit <= 0 || ! class_exists( 'Niwa_AI_Traffic_DB' ) || ! $this->order_attribution_table_exists( Niwa_AI_Traffic_DB::EVENTS ) ) {
            return array();
        }
        global $wpdb;
        $table = Niwa_AI_Traffic_DB::table( Niwa_AI_Traffic_DB::EVENTS );
        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
        $rows = $wpdb->get_results( $wpdb->prepare( "SELECT occurred_at,event_type,page_path,referrer_host,source,medium,campaign,channel,click_id_name FROM {$table} WHERE session_id = %s ORDER BY occurred_at ASC LIMIT %d", $session_id, $limit ), ARRAY_A );
        return is_array( $rows ) ? $rows : array();
    }

    private function order_attribution_table_exists( $slug ) {
        if ( ! class_exists( 'Niwa_AI_Traffic_DB' ) ) {
            return false;
        }
        global $wpdb;
        $table = Niwa_AI_Traffic_DB::table( $slug );
        return $table === $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) );
    }

    /* ------------------------------------------------------------------
     *  2. woo_report_sales — Sales report with period filtering
     * ------------------------------------------------------------------ */

    private function preview_woo_report_sales( $args ) {
        if ( ! class_exists( 'WooCommerce' ) ) {
            return array(
                'success' => false,
                'error'   => 'WooCommerce nije aktivan na ovom sajtu.',
            );
        }

        $period   = isset( $args['period'] ) ? sanitize_text_field( (string) $args['period'] ) : '';
        $date_min = isset( $args['date_min'] ) ? sanitize_text_field( (string) $args['date_min'] ) : '';
        $date_max = isset( $args['date_max'] ) ? sanitize_text_field( (string) $args['date_max'] ) : '';

        $allowed_periods = array( 'week', 'month', 'last_month', 'year' );
        if ( '' !== $period && ! in_array( $period, $allowed_periods, true ) ) {
            return array(
                'success' => false,
                'error'   => 'Nevalidan period. Dozvoljeni: ' . implode( ', ', $allowed_periods ) . '.',
            );
        }

        $summary_parts   = array();
        $summary_parts[] = 'WooCommerce izvestaj o prodaji';
        if ( '' !== $period ) {
            $summary_parts[] = 'Period: ' . $period;
        }
        if ( '' !== $date_min ) {
            $summary_parts[] = 'Od: ' . $date_min;
        }
        if ( '' !== $date_max ) {
            $summary_parts[] = 'Do: ' . $date_max;
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'woo_report_sales',
                'label'            => 'WooCommerce izvestaj o prodaji',
                'summary'          => implode( ' | ', $summary_parts ),
                'rollback_plan'    => 'Read-only operation, no rollback needed.',
                'rollback_support' => 'none',
                'targets'          => array(),
                'args'             => array(
                    'period'   => $period,
                    'date_min' => $date_min,
                    'date_max' => $date_max,
                ),
            ),
        );
    }

    private function execute_woo_report_sales_action( $action ) {
        if ( ! class_exists( 'WooCommerce' ) ) {
            return array(
                'success' => false,
                'error'   => 'WooCommerce nije aktivan na ovom sajtu.',
            );
        }

        $args = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();

        $params = array();
        if ( ! empty( $args['period'] ) ) {
            $params['period'] = (string) $args['period'];
        }
        if ( ! empty( $args['date_min'] ) ) {
            $params['date_min'] = (string) $args['date_min'];
        }
        if ( ! empty( $args['date_max'] ) ) {
            $params['date_max'] = (string) $args['date_max'];
        }

        $result = $this->execute_woo_rest_report( '/wc/v3/reports/sales', $params );

        if ( empty( $result['success'] ) ) {
            return $result;
        }

        $data    = isset( $result['data'] ) ? $result['data'] : array();
        $report  = is_array( $data ) && isset( $data[0] ) ? $data[0] : ( is_array( $data ) ? $data : array() );

        $summary_parts = array( 'Izvestaj o prodaji ucitan' );
        if ( isset( $report['total_sales'] ) ) {
            $summary_parts[] = 'Ukupna prodaja: ' . (string) $report['total_sales'];
        }
        if ( isset( $report['total_orders'] ) ) {
            $summary_parts[] = 'Ukupno porudzbina: ' . (string) $report['total_orders'];
        }

        return array(
            'success'          => true,
            'summary'          => implode( ' | ', $summary_parts ) . '.',
            'data'             => $report,
            'executed_actions' => array(
                array(
                    'type' => 'woo_report_sales',
                ),
            ),
            'rollback_entries' => array(),
        );
    }

    /* ------------------------------------------------------------------
     *  3. woo_report_orders_totals — Order counts by status
     * ------------------------------------------------------------------ */

    private function preview_woo_report_orders_totals( $args ) {
        if ( ! class_exists( 'WooCommerce' ) ) {
            return array(
                'success' => false,
                'error'   => 'WooCommerce nije aktivan na ovom sajtu.',
            );
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'woo_report_orders_totals',
                'label'            => 'WooCommerce ukupni broj porudzbina po statusu',
                'summary'          => 'Citanje broja porudzbina po statusima (pending, processing, completed, itd.).',
                'rollback_plan'    => 'Read-only operation, no rollback needed.',
                'rollback_support' => 'none',
                'targets'          => array(),
                'args'             => array(),
            ),
        );
    }

    private function execute_woo_report_orders_totals_action( $action ) {
        if ( ! class_exists( 'WooCommerce' ) ) {
            return array(
                'success' => false,
                'error'   => 'WooCommerce nije aktivan na ovom sajtu.',
            );
        }

        $result = $this->execute_woo_rest_report( '/wc/v3/reports/orders/totals' );

        if ( empty( $result['success'] ) ) {
            return $result;
        }

        $data = isset( $result['data'] ) && is_array( $result['data'] ) ? $result['data'] : array();

        $total_orders = 0;
        foreach ( $data as $status_entry ) {
            if ( isset( $status_entry['total'] ) ) {
                $total_orders += intval( $status_entry['total'] );
            }
        }

        return array(
            'success'          => true,
            'summary'          => 'Ukupno porudzbina po statusima ucitano (' . count( $data ) . ' statusa, ' . $total_orders . ' porudzbina).',
            'data'             => $data,
            'executed_actions' => array(
                array(
                    'type' => 'woo_report_orders_totals',
                ),
            ),
            'rollback_entries' => array(),
        );
    }

    /* ------------------------------------------------------------------
     *  4. woo_report_products_totals — Product counts by type
     * ------------------------------------------------------------------ */

    private function preview_woo_report_products_totals( $args ) {
        if ( ! class_exists( 'WooCommerce' ) ) {
            return array(
                'success' => false,
                'error'   => 'WooCommerce nije aktivan na ovom sajtu.',
            );
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'woo_report_products_totals',
                'label'            => 'WooCommerce ukupni broj proizvoda po tipu',
                'summary'          => 'Citanje broja proizvoda po tipovima (simple, variable, grouped, itd.).',
                'rollback_plan'    => 'Read-only operation, no rollback needed.',
                'rollback_support' => 'none',
                'targets'          => array(),
                'args'             => array(),
            ),
        );
    }

    private function execute_woo_report_products_totals_action( $action ) {
        if ( ! class_exists( 'WooCommerce' ) ) {
            return array(
                'success' => false,
                'error'   => 'WooCommerce nije aktivan na ovom sajtu.',
            );
        }

        $result = $this->execute_woo_rest_report( '/wc/v3/reports/products/totals' );

        if ( empty( $result['success'] ) ) {
            return $result;
        }

        $data = isset( $result['data'] ) && is_array( $result['data'] ) ? $result['data'] : array();

        $total_products = 0;
        foreach ( $data as $type_entry ) {
            if ( isset( $type_entry['total'] ) ) {
                $total_products += intval( $type_entry['total'] );
            }
        }

        return array(
            'success'          => true,
            'summary'          => 'Ukupno proizvoda po tipovima ucitano (' . count( $data ) . ' tipova, ' . $total_products . ' proizvoda).',
            'data'             => $data,
            'executed_actions' => array(
                array(
                    'type' => 'woo_report_products_totals',
                ),
            ),
            'rollback_entries' => array(),
        );
    }

    /* ------------------------------------------------------------------
     *  5. woo_report_customers_totals — Customer counts
     * ------------------------------------------------------------------ */

    private function preview_woo_report_customers_totals( $args ) {
        if ( ! class_exists( 'WooCommerce' ) ) {
            return array(
                'success' => false,
                'error'   => 'WooCommerce nije aktivan na ovom sajtu.',
            );
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'woo_report_customers_totals',
                'label'            => 'WooCommerce ukupni broj kupaca',
                'summary'          => 'Citanje broja kupaca po tipu (paying, non-paying).',
                'rollback_plan'    => 'Read-only operation, no rollback needed.',
                'rollback_support' => 'none',
                'targets'          => array(),
                'args'             => array(),
            ),
        );
    }

    private function execute_woo_report_customers_totals_action( $action ) {
        if ( ! class_exists( 'WooCommerce' ) ) {
            return array(
                'success' => false,
                'error'   => 'WooCommerce nije aktivan na ovom sajtu.',
            );
        }

        $result = $this->execute_woo_rest_report( '/wc/v3/reports/customers/totals' );

        if ( empty( $result['success'] ) ) {
            return $result;
        }

        $data = isset( $result['data'] ) && is_array( $result['data'] ) ? $result['data'] : array();

        $total_customers = 0;
        foreach ( $data as $customer_entry ) {
            if ( isset( $customer_entry['total'] ) ) {
                $total_customers += intval( $customer_entry['total'] );
            }
        }

        return array(
            'success'          => true,
            'summary'          => 'Ukupno kupaca po tipovima ucitano (' . count( $data ) . ' tipova, ' . $total_customers . ' kupaca).',
            'data'             => $data,
            'executed_actions' => array(
                array(
                    'type' => 'woo_report_customers_totals',
                ),
            ),
            'rollback_entries' => array(),
        );
    }

    /* ------------------------------------------------------------------
     *  6. woo_report_coupons_totals — Coupon usage totals
     * ------------------------------------------------------------------ */

    private function preview_woo_report_coupons_totals( $args ) {
        if ( ! class_exists( 'WooCommerce' ) ) {
            return array(
                'success' => false,
                'error'   => 'WooCommerce nije aktivan na ovom sajtu.',
            );
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'woo_report_coupons_totals',
                'label'            => 'WooCommerce ukupni podaci o kuponima',
                'summary'          => 'Citanje podataka o koriscenju kupona.',
                'rollback_plan'    => 'Read-only operation, no rollback needed.',
                'rollback_support' => 'none',
                'targets'          => array(),
                'args'             => array(),
            ),
        );
    }

    private function execute_woo_report_coupons_totals_action( $action ) {
        if ( ! class_exists( 'WooCommerce' ) ) {
            return array(
                'success' => false,
                'error'   => 'WooCommerce nije aktivan na ovom sajtu.',
            );
        }

        $result = $this->execute_woo_rest_report( '/wc/v3/reports/coupons/totals' );

        if ( empty( $result['success'] ) ) {
            return $result;
        }

        $data = isset( $result['data'] ) && is_array( $result['data'] ) ? $result['data'] : array();

        $total_coupons = 0;
        foreach ( $data as $coupon_entry ) {
            if ( isset( $coupon_entry['total'] ) ) {
                $total_coupons += intval( $coupon_entry['total'] );
            }
        }

        return array(
            'success'          => true,
            'summary'          => 'Podaci o kuponima ucitani (' . count( $data ) . ' tipova, ' . $total_coupons . ' kupona).',
            'data'             => $data,
            'executed_actions' => array(
                array(
                    'type' => 'woo_report_coupons_totals',
                ),
            ),
            'rollback_entries' => array(),
        );
    }

    /* ------------------------------------------------------------------
     *  7. woo_report_reviews_totals — Review counts by rating
     * ------------------------------------------------------------------ */

    private function preview_woo_report_reviews_totals( $args ) {
        if ( ! class_exists( 'WooCommerce' ) ) {
            return array(
                'success' => false,
                'error'   => 'WooCommerce nije aktivan na ovom sajtu.',
            );
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'woo_report_reviews_totals',
                'label'            => 'WooCommerce ukupni broj recenzija po oceni',
                'summary'          => 'Citanje broja recenzija po ocenama (1-5 zvezdica).',
                'rollback_plan'    => 'Read-only operation, no rollback needed.',
                'rollback_support' => 'none',
                'targets'          => array(),
                'args'             => array(),
            ),
        );
    }

    private function execute_woo_report_reviews_totals_action( $action ) {
        if ( ! class_exists( 'WooCommerce' ) ) {
            return array(
                'success' => false,
                'error'   => 'WooCommerce nije aktivan na ovom sajtu.',
            );
        }

        $result = $this->execute_woo_rest_report( '/wc/v3/reports/reviews/totals' );

        if ( empty( $result['success'] ) ) {
            return $result;
        }

        $data = isset( $result['data'] ) && is_array( $result['data'] ) ? $result['data'] : array();

        $total_reviews = 0;
        foreach ( $data as $review_entry ) {
            if ( isset( $review_entry['total'] ) ) {
                $total_reviews += intval( $review_entry['total'] );
            }
        }

        return array(
            'success'          => true,
            'summary'          => 'Podaci o recenzijama ucitani (' . count( $data ) . ' kategorija, ' . $total_reviews . ' recenzija).',
            'data'             => $data,
            'executed_actions' => array(
                array(
                    'type' => 'woo_report_reviews_totals',
                ),
            ),
            'rollback_entries' => array(),
        );
    }
}
