<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
class Dspilot_Helper {

    /**
     * Evaluate a condition based on target, compare operator, and value.
     *
     * @param mixed $target The value to compare against.
     * @param string $compare The comparison operator (e.g., 'less_than', 'greater_than').
     * @param mixed $value The value to compare with.
     * @return bool True if the condition is met, false otherwise.
     */
    public static function evaluate_condition_compare( $target, $compare, $value ) {

        // error_log('evaluate_condition_compare: ' . print_r(array(
        //     'target' => $target,
        //     'compare' => $compare,
        //     'value' => $value
        // ), true));




        switch ( $compare ) {
            case 'less_than':
                return $target < $value;
            case 'less_equal_to':
                return $target <= $value;
            case 'greater_than':
                return $target > $value;
            case 'greater_equal_to':
                return $target >= $value;
            case 'equal_to':
            case 'yes':
            case 'in':
                if ( is_array( $target ) && is_array( $value ) ) {

                    return ! empty( array_intersect( $target, $value ) );
                   
                } elseif ( is_array( $target ) ) {
                    return in_array( $value, $target );
                } elseif ( is_array( $value ) ) {
                    return in_array( $target, $value );
                } else {
                    return $target == $value;
                }
            case 'not_equal_to':
            case 'no':
            case 'not_in':
                if ( is_array( $target ) && is_array( $value ) ) {
                    return empty( array_intersect( $target, $value ) );
                } elseif ( is_array( $target ) ) {
                    return ! in_array( $value, $target );
                } elseif ( is_array( $value ) ) {
                    return ! in_array( $target, $value );
                } else {
                    return $target != $value;
                }
            default:
                return false;
        }
        
        return true;
    }

    public static function get_trending_product_ids() {
        $all_orders = wc_get_orders(
            array(
                'limit' => -1,
                'status' => wc_get_is_paid_statuses(),
                'date_after' => gmdate( 'Y-m-d', strtotime( '-15 days' ) ),
                'return' => 'ids',
            )
        );
        if ( ! $all_orders ) return;
        $trending = array();
        foreach ( $all_orders as $all_order ) {
            $order = wc_get_order( $all_order );
            $items = $order->get_items();
            foreach ( $items as $item ) {
                $product_id = $item->get_product_id();
                if ( ! $product_id ) continue;
                $trending[$product_id] = $product_id;
            }
        }
        
        return $trending;
    }

    public static function get_discount_by_id( $id ) {
        $discounts = Dspilot_Plugin::get_plugin_options( 'discounts' );
        if ( ! is_array( $discounts ) || empty( $discounts ) ) {
            return [];
        }

        foreach ( $discounts as $discount ) {
            if ( isset( $discount['id'] ) && $discount['id'] === $id ) {
                return $discount;
            }
        }

        return [];
    }

    public static function get_all_product($args = [], $only_featured = false, $only_onsale = false) {
        $defaults = [
            'post_type'      => 'product',
            'post_status'    => 'publish',
            'posts_per_page' => -1,
            'fields'         => 'all', // default
        ];

        $args = wp_parse_args($args, $defaults);

        if ($only_featured) {
            $args['tax_query'][] = [
                'taxonomy' => 'product_visibility',
                'field'    => 'name',
                'terms'    => 'featured',
                'operator' => 'IN',
            ];
        }

        // Determine if we need product IDs from on-sale filter early
        $onsale_ids = [];
        if ($only_onsale) {
            $onsale_ids = wc_get_product_ids_on_sale();
            if (empty($onsale_ids)) {
                // No on-sale products, so return early
                return [];
            }
        }

        $query_args = $args;
        if ($args['fields'] === 'ids') {
            $query_args['fields'] = 'ids';
        } else {
            unset($query_args['fields']);
        }

        $query = new WP_Query($query_args);

        if ($args['fields'] === 'ids') {
            if (empty($query->posts) || !is_array($query->posts)) {
                return [];
            }
            $product_ids = $query->posts;

            if ($only_onsale) {
                // Intersection with on-sale IDs
                $product_ids = array_values(array_intersect($product_ids, $onsale_ids));
            }

            return $product_ids;
        }

        $products = [];
        $posts = $query->posts ?? [];

        if ($only_onsale) {
            // Filter posts by on-sale IDs (using a lookup for faster in_array)
            $onsale_lookup = array_flip($onsale_ids);
            $posts = array_filter($posts, function($post) use ($onsale_lookup) {
                return isset($onsale_lookup[$post->ID]);
            });
        }

        if (empty($posts)) {
            return [];
        }

        foreach ($posts as $post) {
            $products[$post->ID] = get_the_title($post->ID);
        }

        return $products;
    }

    public static function get_all_product_ids($args = [], $only_featured = false, $only_onsale = false) {
        $defaults = [
            'post_type'      => 'product',
            'post_status'    => 'publish',
            'posts_per_page' => -1,
            'fields'         => 'ids',
        ];

        // Merge arguments
        $args = wp_parse_args($args, $defaults);

        // Featured products filter
        if ($only_featured) {
            $args['tax_query'][] = [
                'taxonomy' => 'product_visibility',
                'field'    => 'name',
                'terms'    => 'featured',
                'operator' => 'IN',
            ];
        }

        // Get products via WP_Query
        $query = new WP_Query($args);
        $product_ids = $query->posts;

        // Filter only on-sale products
        if ($only_onsale) {
            $onsale_ids = wc_get_product_ids_on_sale();
            $product_ids = array_intersect($product_ids, $onsale_ids);
        }

        return array_values($product_ids); // reindex array
    }

    public static function get_product_meta_value($product_id, $meta_key) {
        if ( ! function_exists( 'wc_get_product' ) || ! $product_id || ! $meta_key ) {
            return '';
        }

        $product = wc_get_product( $product_id );
        if ( ! $product ) {
            return '';
        }

        // Get the meta value
        $meta_value = get_post_meta( $product_id, $meta_key, true );

        // If the meta value is empty, return an empty string
        return is_string( $meta_value ) ? trim( $meta_value ) : '';
    }

    public static function get_product_stock_quantity($product_id){
        if ( ! function_exists( 'wc_get_product' ) || ! $product_id ) {
            return 0;
        }

        $product = wc_get_product( $product_id );
        if ( ! $product ) {
            return 0;
        }

        // Get stock quantity
        $stock_quantity = $product->get_stock_quantity();
        
        // If stock management is enabled, return the stock quantity
        if ( $product->managing_stock() ) {
            return $stock_quantity ? intval( $stock_quantity ) : 0;
        }

        // If stock management is not enabled, return -1 to indicate unlimited stock
        return -1;
    }

    public static function get_product_price($product_id, $regular_price = false) {
        if ( ! function_exists( 'wc_get_product' ) || ! $product_id ) {
            return 0;
        }

        $product = wc_get_product( $product_id );
        if ( ! $product ) {
            // error_log( 'Product not found for ID: ' . $product_id );
            return 0;
        }

        // Simple products
        if ( $product->is_type( 'simple' ) ) {
            $price = $regular_price ? $product->get_regular_price() : $product->get_price();
        }

        // Variable products
        elseif ( $product->is_type( 'variable' ) ) {
            if ( $regular_price ) {
                $prices = $product->get_variation_prices( true )['regular_price'];
            } else {
                $prices = $product->get_variation_prices( true )['price'];
            }

            if ( ! empty( $prices ) ) {
                $min_price = min( $prices );
                $max_price = max( $prices );

                // Return both min & max if different
                $price = ( $min_price != $max_price ) 
                    ? array( 'min' => floatval( $min_price ), 'max' => floatval( $max_price ) )
                    : floatval( $min_price );
            } else {
                $price = 0;
            }
        }

        // Other product types (fallback)
        else {
            $price = $regular_price ? $product->get_regular_price() : $product->get_price();
        }

        return $price;
    }

    public static function get_taxonomy_ids_by_product_id($product_id, $taxonomy_name = 'product_cat') {
        if ( ! function_exists( 'wc_get_product' ) || ! $product_id ) {
            return [];
        }

        $product = wc_get_product( $product_id );
        if ( ! $product ) {
            return [];
        }

        $taxonomy_ids = [];

        // Get all taxonomies associated with the product
        $terms = get_the_terms( $product_id, $taxonomy_name );
        if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) {
            foreach ( $terms as $term ) {
                if ( isset( $term->term_id ) ) {
                    $taxonomy_ids[] = $term->term_id;
                }
            }
        }

        return array_unique( $taxonomy_ids );
    }

    public static function get_variation_count_by_product_id( $product_id ) {
        if ( ! function_exists( 'wc_get_product' ) || ! $product_id ) {
            return 0;
        }

        $product = wc_get_product( $product_id );
        if ( ! $product || ! $product->is_type( 'variable' ) ) {
            return 0;
        }

        $variations = $product->get_children();
        return is_array( $variations ) ? count( $variations ) : 0;
    }

    public static function get_product_variations( $variable_product_id = null, $output_type = 'all') {
        $result = [];

        // If specific product ID is valid and is variable, return its variations
        if ( $variable_product_id ) {
            $product = wc_get_product( $variable_product_id );

            if ( $product && 'variable' === $product->get_type() ) {
                $variations = [];

                if( $output_type === 'ids' ) {
                    foreach ( $product->get_children() as $variation_id ) {
                        $variations[] = $variation_id;
                    }
                    if ( ! empty( $variations ) ) {
                        return $variations;
                    }
                } else {
                    // If output type is names, return variation names
                    foreach ( $product->get_children() as $variation_id ) {
                        $variation = wc_get_product( $variation_id );
                        if ( $variation ) {
                            $variations[ $variation_id ] = $variation->get_name();
                        }
                    }
                    if ( ! empty( $variations ) ) {
                        return $result[ $product->get_name() ] = $variations;
                    }
                }

                

            } else {
                return []; // Not a variable product
            }
        }

        // If no valid product ID, fetch all variable products and return their variations
        $args = [
            'post_type'      => 'product',
            'post_status'    => 'publish',
            'posts_per_page' => -1,
            'fields'         => 'ids',
        ];

        $variable_product_ids = get_posts( $args );

        foreach ( $variable_product_ids as $product_id ) {
            //$product = wc_get_product( $product_id );
            $product = wc_get_product( $product_id );

            if ( $product && 'variable' === $product->get_type() ) {
                $variations = [];

                if( $output_type === 'ids' ) {
                    foreach ( $product->get_children() as $variation_id ) {
                        $variations[] = $variation_id;
                    }
                    return ! empty( $variations ) ? $variations : [];
                } else {
                    // If output type is names, return variation names
                    foreach ( $product->get_children() as $variation_id ) {
                    $variation = wc_get_product( $variation_id );
                        if ( $variation ) {
                            $variations[ $variation_id ] = $variation->get_name();
                        }
                    }
                    if ( ! empty( $variations ) ) {
                        $result[ $product->get_name() ] = $variations;
                    }
                }
                

                
            }
        }

        return $result;
    }

    public static function get_product_variations_cached( $variable_product_id = null ) {
        $variations = get_transient( 'dspilot_wc_product_variations' );

        return is_array( $variations ) ? $variations : [];
    }

    public static function get_selected_shipping_zone() {
        if ( ! class_exists( 'WC_Shipping_Zones' ) || ! function_exists( 'WC' ) || ! WC()->customer ) {
            return null;
        }
    
        $zone = WC_Shipping_Zones::get_zone_matching_package( [
            'destination' => [
                'country'   => WC()->customer->get_shipping_country(),
                'state'     => WC()->customer->get_shipping_state(),
                'postcode'  => WC()->customer->get_shipping_postcode(),
                'city'      => WC()->customer->get_shipping_city(),
                'address'   => WC()->customer->get_shipping_address(),
                'address_2' => WC()->customer->get_shipping_address_2(),
            ],
        ] );
    
        return $zone->get_id(); // WC_Shipping_Zone object or null
    }
    
    public static function get_all_wc_shipping_zones() {
        if ( ! class_exists( 'WC_Shipping_Zone' ) || ! class_exists( 'WC_Shipping_Zones' ) ) {
            return [];
        }

        if ( ! function_exists( 'WC' ) || ! WC() ) {
            return [];
        }

        // Check if shipping is already initialized properly
        if ( ! isset( WC()->shipping ) || ! ( WC()->shipping instanceof WC_Shipping ) ) {
            // Shipping not initialized yet — safe to return empty now
            return [];
        }

        try {
            $zones_data = WC_Shipping_Zones::get_zones();

            $zones = [];
            foreach ( $zones_data as $zone_arr ) {
                if ( isset( $zone_arr['zone_id'] ) && is_numeric( $zone_arr['zone_id'] ) ) {
                    $zones[] = new WC_Shipping_Zone( intval( $zone_arr['zone_id'] ) );
                }
            }

            // Add default zone manually
            $default_zone = new WC_Shipping_Zone( 0 );
            $zones[] = $default_zone;

            $result = [];
            foreach ( $zones as $zone ) {
                if ( is_object( $zone ) && method_exists( $zone, 'get_zone_name' ) ) {
                    $result[ $zone->get_id() ] = $zone->get_zone_name();
                }
            }

            return $result;
        } catch ( Exception $e ) {
            return [];
        }
    }

    public static function get_all_wc_shipping_zones_cached() {
        $zones = get_transient( 'dspilot_shipping_zones' );
        return is_array( $zones ) ? $zones : [];
    }
    
    public static function get_all_wc_countries_and_states() {
        if ( ! class_exists( 'WC_Countries' ) ) {
            return [
                'countries' => [],
                'states'    => [],
            ];
        }
    
        //$wc_countries = new WC_Countries();
    
        // Get all countries (country_code => country_name)
        $countries = WC()->countries->get_countries();
    
        // Get all states grouped by country (country_code => [state_code => state_name])
        $states = WC()->countries->get_states();

        // Remove empty state arrays
        $states = array_filter( $states, function( $state_arr ) {
            return ! empty( $state_arr );
        });
    
        return [
            'countries' => $countries,
            'states'    => $states,
        ];
    }

    public static function get_all_wc_countries_and_states_cached() {
        $countries = get_transient( 'dspilot_wc_countries' );  
        $states = get_transient( 'dspilot_wc_states' );
        if ( is_array( $countries ) && is_array( $states ) ) {
            return [
                'countries' => $countries,
                'states'    => $states,
            ];
        }
        
        return [
            'countries' => [],
            'states'    => [],
        ];
    }
    
    public static function get_selected_shipping_address_and_zone() {
        $country  = WC()->customer->get_shipping_country();
        $state    = WC()->customer->get_shipping_state();
        $city     = WC()->customer->get_shipping_city();
        $postcode = WC()->customer->get_shipping_postcode();
    
        $package = array(
            'destination' => array(
                'country'   => $country,
                'state'     => $state,
                'postcode'  => $postcode,
                'city'      => $city,
                'address'   => '',
                'address_2' => '',
            ),
        );
    
        $zone = WC_Shipping_Zones::get_zone_matching_package( $package );
        $zone_name = $zone ? $zone->get_zone_name() : '';
    
        return array(
            'country'  => $country,
            'state'    => $state,
            'city'     => $city,
            'postcode' => $postcode,
            'zone'     => $zone_name,
        );
    }
    
    public static function get_selected_shipping_method() {
        $chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
        if ( ! empty( $chosen_methods ) ) {
            $full_method_id = $chosen_methods[0];  // string like "flat_rate:3"
            $parts = explode( ':', $full_method_id );
            return $parts[0]; 
        }
        return null;
    }
    
    public static function get_all_wc_shipping_methods() {
        if ( ! class_exists( 'WC_Shipping' ) ) {
            return [];
        }
    
        $shipping_methods = [];
    
        // Get all registered shipping methods from WooCommerce
        $all_methods = WC()->shipping()->load_shipping_methods();
    
        foreach ( $all_methods as $method ) {
            $shipping_methods[ $method->id ] = $method->get_method_title();
        }
    
        return $shipping_methods;
    }
    
    public static function get_wc_payment_methods() {
        if ( ! function_exists( 'WC' ) ) {
            return [];
        }
    
        $methods = [];
        $gateways = WC()->payment_gateways->get_available_payment_gateways();
    
        foreach ( $gateways as $gateway_id => $gateway ) {
            $methods[ $gateway_id ] = $gateway->get_title();
        }
    
        return $methods;
    }
    
    public static function get_current_user_review_count() {
        $user_id = get_current_user_id();
    
        if ( ! $user_id ) {
            return 0; // Not logged in
        }
    
        global $wpdb;
    
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $count = $wpdb->get_var( $wpdb->prepare("
            SELECT COUNT(*) FROM $wpdb->comments c
            INNER JOIN $wpdb->posts p ON c.comment_post_ID = p.ID
            WHERE c.user_id = %d
            AND p.post_type = 'product'
            AND c.comment_approved = '1'
        ", $user_id ) );
    
        return intval( $count );
    }
    
    public static function split_string_if_separator_exists( $str, $separator = ',' ) {
        if ( strpos( $str, $separator ) !== false ) {
            return explode( $separator, $str );
        } else {
            return array( $str );
        }
    }
    
    public static function shipping_classes_in_cart() {
        if ( ! function_exists( 'WC' ) || WC()->cart == null ) {
            return [];
        }

        $class_ids = [];

        foreach ( WC()->cart->get_cart() as $cart_item ) {
            $product = $cart_item['data'];

            if ( ! $product instanceof WC_Product ) {
                continue;
            }

            $shipping_class_id = $product->get_shipping_class_id();

            if ( $shipping_class_id ) {
                $class_ids[] = $shipping_class_id;
            }
        }

        return array_unique( $class_ids );
    }

    public static function get_taxonomy_quantity_by_taxonomy( $taxonomy_name = 'product_cat', $taxonomy_ids = [] ) {
        if ( ! function_exists( 'WC' ) || WC()->cart == null || empty( $taxonomy_ids ) ) {
            return 0;
        }

        $total_quantity = 0;

        foreach ( WC()->cart->get_cart() as $cart_item ) {
            $product_id = $cart_item['product_id'];

            $terms = get_the_terms( $product_id, $taxonomy_name );

            if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) {
                foreach ( $terms as $term ) {
                    if ( in_array( $term->term_id, $taxonomy_ids ) ) {
                        $total_quantity += $cart_item['quantity'];
                        break; // Avoid double counting if product has multiple matching terms
                    }
                }
            }
        }

        return $total_quantity;
    }

    public static function get_cart_subtotal_by_taxonomy( $taxonomy_name = 'product_cat', $taxonomy_ids = [], $include_tax = true ) {
        if ( ! function_exists( 'WC' ) || WC()->cart == null || empty( $taxonomy_ids ) ) {
            return 0;
        }

        $subtotal = 0;

        foreach ( WC()->cart->get_cart() as $cart_item ) {
            $product_id = $cart_item['product_id'];

            $terms = get_the_terms( $product_id, $taxonomy_name );

            if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) {
                $matched = false;

                foreach ( $terms as $term ) {
                    if ( in_array( $term->term_id, $taxonomy_ids ) ) {
                        $matched = true;
                        break;
                    }
                }

                if ( $matched ) {
                    $subtotal += $cart_item['line_total'];

                    if ( $include_tax ) {
                        $subtotal += $cart_item['line_tax'];
                    }
                }
            }
        }

        return $subtotal;
    }

    public static function get_wc_brands() {
        global $wpdb;
    
        $brands = array();
    
        $taxonomy = 'product_brand'; // change to 'pwb-brand' if needed
    
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $results = $wpdb->get_results( $wpdb->prepare( "
            SELECT t.term_id, t.name 
            FROM {$wpdb->terms} AS t
            INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id
            WHERE tt.taxonomy = %s
            ORDER BY t.name ASC
        ", $taxonomy ) );
    
        if ( ! empty( $results ) ) {
            foreach ( $results as $row ) {
                $brands[ $row->term_id ] = $row->name;
            }
        }
    
        return $brands;
    }
    
    public static function get_cart_product_brands( $return = 'ids' ) {
        $brands = [];

        if ( ! function_exists( 'WC' ) || is_admin() || WC()->cart == null ) {
            return $brands;
        }

        foreach ( WC()->cart->get_cart() as $cart_item ) {
            $product_id = $cart_item['product_id'];

            // Get brand term(s) for this product
            $terms = get_the_terms( $product_id, 'product_brand' );

            if ( $terms && ! is_wp_error( $terms ) ) {
                foreach ( $terms as $term ) {
                    if ( $return === 'names' ) {
                        $brands[] = $term->name;
                    } else {
                        $brands[] = $term->term_id;
                    }
                }
            }
        }

        return array_unique( $brands );
    }

    public static function amount_of_bought_taxonomies( $taxonomy_name = 'product_cat', $taxonomy_ids = [] ) {
        if ( ! function_exists( 'wc_get_orders' ) ) {
            return 0;
        }

        $user_id = get_current_user_id();
        if ( ! $user_id || empty( $taxonomy_ids ) ) {
            return 0;
        }

        $total_amount = 0;

        $customer_orders = wc_get_orders( [
            'customer_id' => $user_id,
            'status'      => [ 'completed', 'processing' ],
            'limit'       => -1,
            'return'      => 'ids',
        ] );

        foreach ( $customer_orders as $order_id ) {
            $order = wc_get_order( $order_id );
            if ( ! $order ) {
                continue;
            }

            foreach ( $order->get_items() as $item ) {
                $product = $item->get_product();
                if ( ! $product ) {
                    continue;
                }

                $product_tax_ids = wc_get_product_term_ids( $product->get_id(), $taxonomy_name );

                if ( array_intersect( $taxonomy_ids, $product_tax_ids ) ) {
                    $total_amount += $item->get_total() + $item->get_total_tax(); // include tax
                }
            }
        }

        return $total_amount;
    }

    public static function amount_of_bought_variations( $variation_ids = [] ) {
        if ( ! function_exists( 'wc_get_orders' ) ) {
            return 0;
        }

        $user_id = get_current_user_id();
        if ( ! $user_id ) {
            return 0;
        }

        $total_amount = 0;

        $customer_orders = wc_get_orders( [
            'customer_id' => $user_id,
            'status'      => [ 'completed', 'processing' ],
            'limit'       => -1,
            'return'      => 'ids',
        ] );

        foreach ( $customer_orders as $order_id ) {
            $order = wc_get_order( $order_id );
            if ( ! $order ) {
                continue;
            }

            foreach ( $order->get_items() as $item ) {
                $variation_id = $item->get_variation_id();

                if ( ! $variation_id ) {
                    continue;
                }

                // If variation filter is set and doesn't match, skip
                if ( ! empty( $variation_ids ) && ! in_array( $variation_id, $variation_ids ) ) {
                    continue;
                }

                // Add item total (including tax)
                $total_amount += $item->get_total() + $item->get_total_tax();
            }
        }

        return $total_amount;
    }

    public static function amount_of_bought_products( $product_ids = [] ) {
        if ( ! function_exists( 'wc_get_orders' ) ) {
            return 0;
        }

        $user_id = get_current_user_id();
        if ( ! $user_id ) {
            return 0;
        }

        $total_amount = 0;

        $customer_orders = wc_get_orders( [
            'customer_id' => $user_id,
            'status'      => [ 'completed', 'processing' ],
            'limit'       => -1,
            'return'      => 'ids',
        ] );

        foreach ( $customer_orders as $order_id ) {
            $order = wc_get_order( $order_id );
            if ( ! $order ) {
                continue;
            }

            foreach ( $order->get_items() as $item ) {
                $product_id = $item->get_product_id();
                $variation_id = $item->get_variation_id();

                // Skip if it's a variation
                if ( $variation_id ) {
                    continue;
                }

                // If product IDs filter is set and doesn't match, skip
                if ( ! empty( $product_ids ) && ! in_array( $product_id, $product_ids ) ) {
                    continue;
                }

                $total_amount += $item->get_total() + $item->get_total_tax(); // Includes tax
            }
        }

        return $total_amount;
    }

    public static function quantity_of_bought_taxonomies( $taxonomy_name = 'product_cat', $taxonomy_ids = [] ) {
        if ( ! function_exists( 'wc_get_orders' ) ) {
            return 0;
        }

        $user_id = get_current_user_id();
        if ( ! $user_id || empty( $taxonomy_ids ) ) {
            return 0;
        }

        $total_quantity = 0;

        $customer_orders = wc_get_orders( [
            'customer_id' => $user_id,
            'status'      => [ 'completed', 'processing' ],
            'limit'       => -1,
            'return'      => 'ids',
        ] );

        foreach ( $customer_orders as $order_id ) {
            $order = wc_get_order( $order_id );
            if ( ! $order ) {
                continue;
            }

            foreach ( $order->get_items() as $item ) {
                $product = $item->get_product();

                if ( ! $product ) {
                    continue;
                }

                $product_tax_ids = wc_get_product_term_ids( $product->get_id(), $taxonomy_name );

                if ( array_intersect( $taxonomy_ids, $product_tax_ids ) ) {
                    $total_quantity += $item->get_quantity();
                }
            }
        }

        return $total_quantity;
    }

    public static function quantity_of_bought_variations( $variation_ids = [] ) {
        if ( ! function_exists( 'wc_get_orders' ) ) {
            return 0;
        }

        $user_id = get_current_user_id();
        if ( ! $user_id ) {
            return 0;
        }

        $total_quantity = 0;

        $customer_orders = wc_get_orders( [
            'customer_id' => $user_id,
            'status'      => [ 'completed', 'processing' ],
            'limit'       => -1,
            'return'      => 'ids',
        ] );

        foreach ( $customer_orders as $order_id ) {
            $order = wc_get_order( $order_id );
            if ( ! $order ) {
                continue;
            }

            foreach ( $order->get_items() as $item ) {
                $variation_id = $item->get_variation_id();

                if ( $variation_id && $variation_id > 0 ) {
                    if ( ! empty( $variation_ids ) && ! in_array( $variation_id, $variation_ids ) ) {
                        continue;
                    }

                    $total_quantity += $item->get_quantity();
                }
            }
        }

        return $total_quantity;
    }

    public static function quantity_of_bought_products( $product_ids = [], $user_id = null ) {
        if ( empty( $product_ids ) ) {
            return 0; // Nothing to check
        }
    
        if ( is_null( $user_id ) ) {
            $user_id = get_current_user_id();
        }
    
        if ( ! $user_id ) {
            return 0; // Not logged in
        }
    
        $product_ids = array_map( 'absint', (array) $product_ids );
        $orders = wc_get_orders([
            'customer_id' => $user_id,
            'status'      => ['wc-completed', 'wc-processing'],
            'limit'       => -1,
            'return'      => 'objects',
        ]);
    
        $total_quantity = 0;
    
        foreach ( $orders as $order ) {
            foreach ( $order->get_items() as $item ) {
                $product_id = $item->get_product_id();
                if ( in_array( $product_id, $product_ids ) ) {
                    $total_quantity += $item->get_quantity();
                }
            }
        }
    
        return $total_quantity;
    }
    
    public function get_product_taxonomies (){}

    public static function bought_product_taxonomies( $taxonomy_name = 'product_cat', $user_id = null ) {
        if ( ! function_exists( 'wc_get_orders' ) ) {
            return [];
        }

        if ( empty( $user_id ) ) {
            $user_id = get_current_user_id();
        }

        if ( ! $user_id ) {
            return [];
        }

        $taxonomy_ids = [];

        $customer_orders = wc_get_orders( [
            'customer_id' => $user_id,
            'status'      => [ 'completed', 'processing' ],
            'limit'       => -1,
            'return'      => 'ids',
        ] );

        foreach ( $customer_orders as $order_id ) {
            $order = wc_get_order( $order_id );
            if ( ! $order ) {
                continue;
            }

            foreach ( $order->get_items() as $item ) {
                $product_id = $item->get_product_id();
                $product = wc_get_product( $product_id );

                if ( ! $product ) {
                    continue;
                }

                $product_tax_ids = wc_get_product_term_ids( $product->get_id(), $taxonomy_name );
                if ( ! empty( $product_tax_ids ) ) {
                    $taxonomy_ids = array_merge( $taxonomy_ids, $product_tax_ids );
                }
            }
        }

        return array_unique( $taxonomy_ids );
    }

    public static function bought_products( $user_id = null, $only_featured = false, $only_onsale = false ) {
        if ( ! function_exists( 'wc_get_orders' ) ) {
            return [];
        }

        if ( empty( $user_id ) ) {
            $user_id = get_current_user_id();
        }

        if ( ! $user_id ) {
            return [];
        }

        $product_ids = [];

        $customer_orders = wc_get_orders( [
            'customer_id' => $user_id,
            'status'      => [ 'completed', 'processing' ],
            'limit'       => -1,
            'return'      => 'ids',
        ] );

        foreach ( $customer_orders as $order_id ) {
            $order = wc_get_order( $order_id );
            if ( ! $order ) {
                continue;
            }

            foreach ( $order->get_items() as $item ) {
                $product_id = $item->get_product_id();
                $variation_id = $item->get_variation_id();

                $product = wc_get_product( $variation_id ? $variation_id : $product_id );

                if ( ! $product ) {
                    continue;
                }

                // Filter featured products if needed
                if ( $only_featured && ! $product->is_featured() ) {
                    continue;
                }

                // Filter on-sale products if needed
                if ( $only_onsale && ! $product->is_on_sale() ) {
                    continue;
                }

                $product_ids[] = $product->get_id();
            }
        }

        return array_unique( $product_ids );
    }

    public static function average_money_spent_per_order( $user_id = null ) {
        if ( ! function_exists( 'wc_get_orders' ) ) {
            return 0;
        }

        if ( empty( $user_id ) ) {
            $user_id = get_current_user_id();
        }

        if ( ! $user_id ) {
            return 0;
        }

        $customer_orders = wc_get_orders( [
            'customer_id' => $user_id,
            'status'      => [ 'completed', 'processing' ],
            'limit'       => -1,
            'return'      => 'ids',
        ] );

        $order_count = count( $customer_orders );
        if ( $order_count === 0 ) {
            return 0;
        }

        $total_spent = 0;
        foreach ( $customer_orders as $order_id ) {
            $order = wc_get_order( $order_id );
            if ( $order ) {
                $total_spent += $order->get_total();
            }
        }

        return $total_spent / $order_count;
    }

    public static function last_order_amount( $user_id = null ) {
        if ( ! function_exists( 'wc_get_orders' ) ) {
            return 0;
        }

        if ( empty( $user_id ) ) {
            $user_id = get_current_user_id();
        }

        if ( ! $user_id ) {
            return 0;
        }

        // Get the most recent completed or processing order
        $orders = wc_get_orders( [
            'customer_id' => $user_id,
            'status'      => [ 'completed', 'processing' ],
            'limit'       => 1,
            'orderby'     => 'date',
            'order'       => 'DESC',
            'return'      => 'ids',
        ] );

        if ( empty( $orders ) ) {
            return 0;
        }

        $order = wc_get_order( $orders[0] );

        return $order ? $order->get_total() : 0;
    }

    public static function number_of_orders( $user_id = null ) {
        if ( ! function_exists( 'wc_get_orders' ) ) {
            return 0;
        }

        if ( empty( $user_id ) ) {
            $user_id = get_current_user_id();
        }

        if ( ! $user_id ) {
            return 0;
        }

        $customer_orders = wc_get_orders( [
            'customer_id' => $user_id,
            'status'      => [ 'completed', 'processing' ],
            'limit'       => -1,
            'return'      => 'ids',
        ] );

        return count( $customer_orders );
    }

    public static function money_spent_amount( $user_id = null ) {
        if ( ! function_exists( 'wc_get_orders' ) ) {
            return 0;
        }

        if ( empty( $user_id ) ) {
            $user_id = get_current_user_id();
        }

        if ( ! $user_id ) {
            return 0;
        }

        $total_spent = 0;

        // Get all completed and processing orders of the user
        $customer_orders = wc_get_orders( [
            'customer_id' => $user_id,
            'status'      => [ 'completed', 'processing' ],
            'limit'       => -1,
            'return'      => 'ids',
        ] );

        foreach ( $customer_orders as $order_id ) {
            $order = wc_get_order( $order_id );
            if ( $order ) {
                $total_spent += $order->get_total(); // Includes tax & shipping
            }
        }

        return $total_spent;
    }

    public static function get_current_user_last_order_date() {
        if ( ! is_user_logged_in() ) {
            return false;
        }
    
        $user_id = get_current_user_id();
    
        $customer_orders = wc_get_orders([
            'customer_id' => $user_id,
            'limit'       => 1,
            'orderby'     => 'date_created',
            'order'       => 'DESC',
            'return'      => 'objects',
        ]);
    
        if ( ! empty( $customer_orders ) ) {
            $order = current( $customer_orders );
            return $order->get_date_created()->date('d-m-Y');
        }
    
        return false; // No orders found
    }
    
    public static function get_current_user_email_address() {
        if ( ! is_user_logged_in() ) {
            return null;
        }

        $user = wp_get_current_user();

        return isset( $user->user_email ) ? $user->user_email : null;
    }

    public static function get_all_user_meta_keys() {
        global $wpdb;
    
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $keys = $wpdb->get_col( "
            SELECT DISTINCT meta_key 
            FROM {$wpdb->usermeta}
            WHERE meta_key NOT LIKE '\_%'
        " );
    
        $assoc = [];
        foreach ( $keys as $key ) {
            $assoc[ $key ] = $key;
        }
    
        return $assoc;
    }
    
    public static function current_user_has_meta( $meta_key ) {
        if ( ! is_user_logged_in() || empty( $meta_key ) ) {
            return false;
        }

        $user_id = get_current_user_id();
        $meta_value = get_user_meta( $user_id, $meta_key, true );

        if ( ! empty( $meta_value ) ) {
            return $meta_value;
        }

        return false;
    }

    public static function get_current_user_capabilities() {
        // Get the current user object
        $user = wp_get_current_user();
    
        // Check if a user is logged in
        if ( ! $user || 0 === $user->ID ) {
            return []; // Not logged in, return empty array
        }
    
        // Get all capabilities of the current user
        $capabilities = [];
    
        if ( isset( $user->allcaps ) && is_array( $user->allcaps ) ) {
            foreach ( $user->allcaps as $cap => $has_cap ) {
                if ( $has_cap ) {
                    $capabilities[] = $cap;
                }
            }
        }
    
        return $capabilities;
    }
    
    public static function get_current_user_role() {
        if ( ! is_user_logged_in() ) {
            return null;
        }

        $user = wp_get_current_user();

        // A user can technically have multiple roles, but we return the first one
        return ! empty( $user->roles ) ? $user->roles[0] : null;
    }

    public static function get_quantity_of_products_by_ids( $product_ids = [], $variation_ids = [], $category_ids = [] ) {
        $total_quantity = 0;

        if ( ! WC()->cart ) {
            return $total_quantity;
        }

        foreach ( WC()->cart->get_cart() as $cart_item ) {
            $product_id   = $cart_item['product_id'];
            $variation_id = $cart_item['variation_id'];
            $quantity     = $cart_item['quantity'];

            $product = wc_get_product( $variation_id ? $variation_id : $product_id );
            if ( ! $product ) {
                continue;
            }

            $match = false;

            // Match by product ID
            if ( ! empty( $product_ids ) && in_array( $product_id, $product_ids ) ) {
                $match = true;
            }

            // Match by variation ID
            if ( ! empty( $variation_ids ) && in_array( $variation_id, $variation_ids ) ) {
                $match = true;
            }

            // Match by category ID
            if ( ! empty( $category_ids ) ) {
                $product_cat_ids = wc_get_product_term_ids( $product->get_id(), 'product_cat' );
                if ( array_intersect( $category_ids, $product_cat_ids ) ) {
                    $match = true;
                }
            }

            if ( $match ) {
                $total_quantity += $quantity;
            }
        }

        return $total_quantity;
    }

    public static function get_cart_subtotal_by_product_ids( $product_ids = [], $include_tax = true, $only_onsale = false ) {
        $subtotal = 0;

        if ( ! WC()->cart || empty( $product_ids ) ) {
            return $subtotal;
        }

        foreach ( WC()->cart->get_cart() as $cart_item ) {
            $product_id = $cart_item['product_id'];

            // Skip if not in target IDs
            if ( ! in_array( $product_id, $product_ids ) ) {
                continue;
            }

            // Skip if only_onsale is true and product is not on sale
            if ( $only_onsale && ! wc_get_product( $product_id )->is_on_sale() ) {
                continue;
            }

            // Add subtotal based on tax inclusion
            if ( $include_tax ) {
                $subtotal += $cart_item['line_total'] + $cart_item['line_tax'];
            } else {
                $subtotal += $cart_item['line_total'];
            }
        }

        return $subtotal;
    }

    public static function get_cart_subtotal_by_variation_ids( $variation_ids = [], $include_tax = true, $only_onsale = false ) {
        $subtotal = 0;

        if ( ! WC()->cart || empty( $variation_ids ) ) {
            return $subtotal;
        }

        foreach ( WC()->cart->get_cart() as $cart_item ) {
            $variation_id = $cart_item['variation_id'];

            // Skip if not in target variation IDs
            if ( ! in_array( $variation_id, $variation_ids ) ) {
                continue;
            }

            // Check if variation is on sale (if required)
            if ( $only_onsale && ! wc_get_product( $variation_id )->is_on_sale() ) {
                continue;
            }

            // Add subtotal based on tax inclusion
            if ( $include_tax ) {
                $subtotal += $cart_item['line_total'] + $cart_item['line_tax'];
            } else {
                $subtotal += $cart_item['line_total'];
            }
        }

        return $subtotal;
    }

    public static function get_cart_subtotal_by_category_ids( $category_ids = [], $include_tax = true, $only_onsale = false ) {
        $subtotal = 0;

        if ( ! WC()->cart || empty( $category_ids ) ) {
            return $subtotal;
        }

        foreach ( WC()->cart->get_cart() as $cart_item ) {
            $product = wc_get_product( $cart_item['product_id'] );

            if ( ! $product ) {
                continue;
            }

            // Get the product's category IDs
            $product_category_ids = wc_get_product_term_ids( $product->get_id(), 'product_cat' );

            // Check if product belongs to any of the target categories
            if ( empty( array_intersect( $category_ids, $product_category_ids ) ) ) {
                continue;
            }

            // Skip if only_onsale is true and product is not on sale
            if ( $only_onsale && ! $product->is_on_sale() ) {
                continue;
            }

            // Add subtotal based on tax inclusion
            if ( $include_tax ) {
                $subtotal += $cart_item['line_total'] + $cart_item['line_tax'];
            } else {
                $subtotal += $cart_item['line_total'];
            }
        }

        return $subtotal;
    }

    public static function get_user_capabilities(){
        $capabilities = [];
        
        // Get all WordPress user roles
        $wp_roles = wp_roles();
        
        if ( $wp_roles && is_object( $wp_roles ) ) {
            // Get all capabilities from all roles
            foreach ( $wp_roles->roles as $role ) {
                if ( isset( $role['capabilities'] ) && is_array( $role['capabilities'] ) ) {
                    foreach ( $role['capabilities'] as $capability => $has_cap ) {
                        if ( $has_cap && !isset( $capabilities[$capability] ) ) {
                            // Convert capability name to a more readable format
                            $capability_name = str_replace( '_', ' ', $capability );
                            $capability_name = ucwords( $capability_name );
                            $capabilities[$capability] = $capability_name;
                        }
                    }
                }
            }
        }
        
        // Sort capabilities alphabetically by name
        asort( $capabilities );
        
        return $capabilities;
    }

    public static function get_user_roles() {
        $roles = [];
        
        // Get all WordPress user roles
        $wp_roles = wp_roles();
        
        if ( $wp_roles && is_object( $wp_roles ) ) {
            foreach ( $wp_roles->get_names() as $role_id => $role_name ) {
                $roles[$role_id] = $role_name;
            }
        }
        
        return $roles;
    }

    public static function get_shipping_classes() {
        global $wpdb;
        $shipping_classes_array = [];
        
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $classes = $wpdb->get_results( "
            SELECT * FROM {$wpdb->prefix}terms as t
            INNER JOIN {$wpdb->prefix}term_taxonomy as tt ON t.term_id = tt.term_id
            WHERE tt.taxonomy = 'product_shipping_class'
        " );
        
        if ( is_array($classes) && !empty($classes) ) {
            foreach ( $classes as $class ) {
                $shipping_classes_array[$class->term_id] = $class->name;
            }
        }
    
        return $shipping_classes_array;
    }
    

    /**
    * Get all product IDs from the WooCommerce cart.
    *
    * @param bool $include_variations Whether to include variation IDs instead of parent IDs.
    * @return array Array of unique product IDs.
    */
    public static function get_cart_product_ids( $include_variations = false ) {
       $ids = [];
   
       if ( ! WC()->cart ) return $ids;
   
       foreach ( WC()->cart->get_cart() as $cart_item ) {
           $ids[] = $include_variations
               ? ( $cart_item['variation_id'] ?: $cart_item['product_id'] )
               : $cart_item['product_id'];
       }
   
       return array_unique( $ids );
    }
   
   /**
     * Get all variation product IDs from WooCommerce cart.
     *
     * @return array Array of unique variation IDs.
     */
    public static function get_cart_product_variation_ids() {
        $ids = [];

        if ( ! WC()->cart ) return $ids;

        foreach ( WC()->cart->get_cart() as $cart_item ) {
            if ( ! empty( $cart_item['variation_id'] ) ) {
                $ids[] = $cart_item['variation_id'];
            }
        }

        return array_unique( $ids );
    }

    /**
     * Get all product category IDs from WooCommerce cart items.
     *
     * @return array Array of unique product category IDs.
     */
    public static function get_cart_product_taxonomies($taxonomy_name = 'product_cat') {
        $category_ids = [];

        if ( ! WC()->cart ) {
            return $category_ids;
        }

        foreach ( WC()->cart->get_cart() as $cart_item ) {
            $product_id = $cart_item['product_id'];
            $cats = wp_get_post_terms( $product_id, $taxonomy_name, ['fields' => 'ids'] );

            if ( ! is_wp_error( $cats ) ) {
                $category_ids = array_merge( $category_ids, $cats );
            }
        }

        return array_unique( $category_ids );
    }


    public static function get_total_products_bought_by_current_user() {
        if ( ! is_user_logged_in() ) {
            return 0;
        }

        $user_id = get_current_user_id();
        $customer_orders = wc_get_orders([
            'customer_id' => $user_id,
            'status'      => ['completed', 'processing'], // Include only paid/valid orders
            'limit'       => -1, // No limit
            'return'      => 'ids',
        ]);

        $total_products = 0;

        foreach ( $customer_orders as $order_id ) {
            $order = wc_get_order( $order_id );

            foreach ( $order->get_items() as $item ) {
                $total_products += $item->get_quantity();
            }
        }

        return $total_products;
    }
    /**
     * Get the maximum width and height from WooCommerce cart items.
     *
     * @return array Associative array with keys 'max_width' and 'max_height'
     */
    public static function get_cart_max_width_height() {
        $max_width  = 0;
        $max_height = 0;

        if ( ! WC()->cart ) {
            return [
                'max_width'  => $max_width,
                'max_height' => $max_height,
            ];
        }

        foreach ( WC()->cart->get_cart() as $cart_item ) {
            $product = $cart_item['data'];

            $width  = floatval( $product->get_width() );
            $height = floatval( $product->get_height() );

            if ( $width > $max_width ) {
                $max_width = $width;
            }

            if ( $height > $max_height ) {
                $max_height = $height;
            }
        }

        return [
            'max_width'  => $max_width,
            'max_height' => $max_height,
        ];
    }

    /**
     * Get the maximum length from WooCommerce cart items.
     *
     * @return float Max length found in cart (in WooCommerce's unit, e.g., cm)
     */
    public static function get_cart_max_length() {
        $max_length = 0;

        if ( ! WC()->cart ) {
            return $max_length;
        }

        foreach ( WC()->cart->get_cart() as $cart_item ) {
            $product = $cart_item['data'];

            $length = floatval( $product->get_length() );

            if ( $length > $max_length ) {
                $max_length = $length;
            }
        }

        return $max_length;
    }
    /**
     * Get the minimum stock quantity among all items in the cart.
     *
     * @return int|null Returns the minimum stock quantity or null if cart is empty or stock is unmanaged.
     */
    public static function get_min_stock_of_cart_items() {
        $min_stock = null;

        if ( ! WC()->cart ) {
            return null;
        }

        foreach ( WC()->cart->get_cart() as $cart_item ) {
            $product = $cart_item['data'];

            if ( $product->managing_stock() ) {
                $stock_qty = $product->get_stock_quantity();

                if ( $stock_qty !== null ) {
                    if ( $min_stock === null || $stock_qty < $min_stock ) {
                        $min_stock = $stock_qty;
                    }
                }
            }
        }

        return $min_stock;
    }

}