<?php
if ( ! defined( 'ABSPATH' ) ) { exit; }

class KNSDD_Campaign_Validator {
    /** @var string|null Son doğrulama hatası */
    private $last_error = null;

    /**
     * Son hata mesajını döndürür.
     */
    public function get_last_error() {
        return $this->last_error;
    }

    /**
     * Yardımcı: Hata durumunu ayarla.
     */
    private function set_error( $message ) {
        $this->last_error = $message;
    }

    /**
     * İndirim tavan/floor validasyonu.
     * - percentage: 0 <= value < 100
     * - amount: value > 0
     */
    public function validate_discount_caps( $rule ) {
        $this->last_error = null;
        $discount_type = isset( $rule['discount_type'] ) ? $rule['discount_type'] : 'amount';
        $value = isset( $rule['discount_value'] ) ? floatval( $rule['discount_value'] ) : 0;

        if ( ! is_finite( $value ) ) { $value = 0; }
        if ( $discount_type === 'percentage' ) {
            if ( $value >= 100 ) {
                $this->set_error( __( 'İndirim oranı %100 veya üzeri olamaz.', 'kns-dynamic-discounts-for-woocommerce' ) );
                return false;
            }
            if ( $value <= 0 ) {
                $this->set_error( __( 'İndirim oranı sıfırdan büyük olmalıdır.', 'kns-dynamic-discounts-for-woocommerce' ) );
                return false;
            }
        } else { // amount
            if ( $value <= 0 ) {
                $this->set_error( __( 'İndirim tutarı sıfırdan büyük olmalıdır.', 'kns-dynamic-discounts-for-woocommerce' ) );
                return false;
            }
        }

        return true;
    }
    /**
     * Özel kampanyaların (X Al Y Öde vb.) sepetteki koşulları karşılayıp karşılamadığını kontrol eder.
     * Mesaj gösteriminden önce bu kontrol yapılmalı.
     */
    public function is_special_campaign_applicable_for_cart( $rule ) {
        if ( empty( $rule['campaign_type'] ) ) {
            return true; // Kampanya tipi yoksa varsayılan olarak geçerli kabul et
        }

        switch ( $rule['campaign_type'] ) {
            case 'buy_x_pay_y':
                return $this->validate_buy_x_pay_y_campaign( $rule );
            case 'nth_percent_off':
                return $this->validate_nth_percent_off_campaign( $rule );
            case 'cart_total_discount':
                return $this->validate_cart_total_discount_campaign( $rule );
            case 'buy_x_get_y_discount':
                return $this->validate_bogo_campaign( $rule );
            default:
                return true; // Bilinmeyen kampanya tiplerini varsayılan olarak geçerli kabul et
        }
    }

    /**
     * Özel kampanyaların belirli bir ürün için uygulanabilir olup olmadığını kontrol eder.
     * Kategori bazlı kampanyalarda her ürün için ayrı kontrol gerekir.
     * 
     * @param array $rule Kural verisi
     * @param int $product_id Ürün ID
     * @param int $quantity Sepetteki miktar
     * @return bool
     */
    public function is_special_campaign_applicable_for_product( $rule, $product_id, $quantity ) {
        if ( empty( $rule['campaign_type'] ) ) {
            return true;
        }

        $campaign_type = $rule['campaign_type'];
        
        // Kategori bazlı mı kontrol et
        $is_category_based = empty( $rule['products'] ) && ! empty( $rule['category'] );
        
        if ( ! $is_category_based ) {
            // Ürün bazlı kampanyalarda sepet geneli kontrol yeterli
            return $this->is_special_campaign_applicable_for_cart( $rule );
        }

        // Kategori bazlı kampanyalarda ürün bazında kontrol
        switch ( $campaign_type ) {
            case 'buy_x_pay_y':
                $buy_x = isset( $rule['buy_x'] ) ? (int) $rule['buy_x'] : 0;
                return $quantity >= $buy_x;
                
            case 'nth_percent_off':
                $nth = isset( $rule['nth'] ) ? (int) $rule['nth'] : 0;
                return $quantity >= $nth;
                
            case 'buy_x_get_y_discount':
                // BOGO için sepet geneli kontrol yeterli
                return $this->validate_bogo_campaign( $rule );
                
            case 'cart_total_discount':
                // Sepet tutarı için sepet geneli kontrol yeterli
                return $this->validate_cart_total_discount_campaign( $rule );
                
            default:
                return true;
        }
    }

    /**
     * "X Al, Y Öde" kampanyasının sepetteki koşulları karşılayıp karşılamadığını kontrol eder.
     * PERFORMANS OPTİMİZASYONU: Batch processing kullanır.
     */
    public function validate_buy_x_pay_y_campaign( $rule ) {
        $buy_x = isset( $rule['buy_x'] ) ? (int) $rule['buy_x'] : 0;
        $pay_y = isset( $rule['pay_y'] ) ? (int) $rule['pay_y'] : 0;

        // Kampanya ayarları geçersizse false dön
        if ( $buy_x <= 0 || $pay_y < 0 || $buy_x <= $pay_y ) {
            return false;
        }

        // Kategori bazlı kampanyalarda: Her üründen en az buy_x adet olmalı
        $is_category_based = empty( $rule['products'] ) && ! empty( $rule['category'] );
        
        // Optimize edilmiş batch processing varsa onu kullan
        if ( class_exists( 'KNSDD_Performance_Optimizer' ) ) {
            $cart_data = KNSDD_Performance_Optimizer::batch_load_cart_rules();
            
            if ( $is_category_based ) {
                // Kategori bazlı: Her ürün için ayrı kontrol
                foreach ( $cart_data as $data ) {
                    if ( $data['rule'] && $data['rule']['rule_id'] === $rule['rule_id'] ) {
                        if ( $data['quantity'] >= $buy_x ) {
                            return true; // En az bir ürün koşulu sağlıyor
                        }
                    }
                }
                return false;
            } else {
                // Ürün bazlı: Toplam miktar kontrolü
                $total_eligible_quantity = 0;
                foreach ( $cart_data as $data ) {
                    if ( $data['rule'] && $data['rule']['rule_id'] === $rule['rule_id'] ) {
                        $total_eligible_quantity += $data['quantity'];
                    }
                }
                return $total_eligible_quantity >= $buy_x;
            }
        }

        // Fallback: Eski yöntem (performans sorunu var)
        if ( $is_category_based ) {
            // Kategori bazlı: Her ürün için ayrı kontrol
            foreach ( WC()->cart->get_cart() as $cart_item ) {
                $product_id = $cart_item['product_id'];
                $quantity = $cart_item['quantity'];
                
                // Bu ürün kurala uygun mu?
                $product_rule = KNSDD_Discount_Engine::get_best_applicable_rule( $product_id, 1 );
                if ( $product_rule && isset( $product_rule['rule_id'] ) && $product_rule['rule_id'] === $rule['rule_id'] ) {
                    if ( $quantity >= $buy_x ) {
                        return true; // En az bir ürün koşulu sağlıyor
                    }
                }
            }
            return false;
        } else {
            // Ürün bazlı: Toplam miktar kontrolü
            $total_eligible_quantity = 0;
            
            foreach ( WC()->cart->get_cart() as $cart_item ) {
                $product_id = $cart_item['product_id'];
                $quantity = $cart_item['quantity'];
                
                // Bu ürün kurala uygun mu?
                $product_rule = KNSDD_Discount_Engine::get_best_applicable_rule( $product_id, 1 );
                if ( $product_rule && isset( $product_rule['rule_id'] ) && $product_rule['rule_id'] === $rule['rule_id'] ) {
                    $total_eligible_quantity += $quantity;
                }
            }

            // Toplam miktar kampanya koşulunu karşılıyor mu?
            return $total_eligible_quantity >= $buy_x;
        }
    }

    /**
     * "N'inci Ürüne % İndirim" kampanyasının koşullarını kontrol eder.
     * PERFORMANS OPTİMİZASYONU: Batch processing kullanır.
     */
    public function validate_nth_percent_off_campaign( $rule ) {
        $nth = isset( $rule['nth'] ) ? (int) $rule['nth'] : 0;
        if ( $nth <= 0 ) { return false; }

        // Discount caps validation
        if ( ! $this->validate_discount_caps( $rule ) ) {
            return false;
        }

        // Kategori bazlı kampanyalarda: Her üründen en az nth adet olmalı
        $is_category_based = empty( $rule['products'] ) && ! empty( $rule['category'] );

        // Optimize edilmiş validasyon kullan (yalnızca miktar eşiği)
        if ( class_exists( 'KNSDD_Performance_Optimizer' ) ) {
            if ( $is_category_based ) {
                // Kategori bazlı: Her ürün için ayrı kontrol
                $cart_data = KNSDD_Performance_Optimizer::batch_load_cart_rules();
                foreach ( $cart_data as $data ) {
                    if ( $data['rule'] && $data['rule']['rule_id'] === $rule['rule_id'] ) {
                        if ( $data['quantity'] >= $nth ) {
                            return true;
                        }
                    }
                }
                return false;
            } else {
                return KNSDD_Performance_Optimizer::validate_nth_percent_off_optimized( $rule );
            }
        }

        // Fallback: Eski yöntem (performans maliyetli)
        if ( $is_category_based ) {
            // Kategori bazlı: Her ürün için ayrı kontrol
            foreach ( WC()->cart->get_cart() as $cart_item ) {
                $product_id = $cart_item['product_id'];
                $quantity   = $cart_item['quantity'];
                $product_rule = KNSDD_Discount_Engine::get_best_applicable_rule( $product_id, 1 );
                if ( $product_rule && isset( $product_rule['rule_id'] ) && $product_rule['rule_id'] === $rule['rule_id'] ) {
                    if ( $quantity >= $nth ) {
                        return true;
                    }
                }
            }
            return false;
        } else {
            // Ürün bazlı: Toplam miktar kontrolü
            $total_eligible_quantity = 0;
            foreach ( WC()->cart->get_cart() as $cart_item ) {
                $product_id = $cart_item['product_id'];
                $quantity   = $cart_item['quantity'];
                $product_rule = KNSDD_Discount_Engine::get_best_applicable_rule( $product_id, 1 );
                if ( $product_rule && isset( $product_rule['rule_id'] ) && $product_rule['rule_id'] === $rule['rule_id'] ) {
                    $total_eligible_quantity += $quantity;
                }
            }
            return $total_eligible_quantity >= $nth;
        }
    }

    /**
     * BOGO (A Al, B'ye İndirim) kampanyasının koşullarını kontrol eder.
     * Sepette hem tetikleyici hem hedef ürünler olmalı.
     */
    public function validate_bogo_campaign( $rule ) {
        $trigger_products = isset( $rule['trigger_products'] ) && is_array( $rule['trigger_products'] ) ? $rule['trigger_products'] : array();
        $trigger_category = isset( $rule['trigger_category'] ) ? absint( $rule['trigger_category'] ) : 0;
        $target_products = isset( $rule['target_products'] ) && is_array( $rule['target_products'] ) ? $rule['target_products'] : array();
        $target_category = isset( $rule['target_category'] ) ? absint( $rule['target_category'] ) : 0;
        
        $trigger_qty = isset( $rule['trigger_quantity'] ) ? (int) $rule['trigger_quantity'] : 1;
        
        // Sepette tetikleyici ürün var mı?
        $trigger_count = 0;
        $target_count = 0;
        
        foreach ( WC()->cart->get_cart() as $cart_item ) {
            $product_id = $cart_item['product_id'];
            $quantity = $cart_item['quantity'];
            
            // Tetikleyici kontrolü: Ürün öncelikli mantık
            $is_trigger = false;
            if ( ! empty( $trigger_products ) && in_array( $product_id, $trigger_products, true ) ) {
                $is_trigger = true;
            } elseif ( empty( $trigger_products ) && $trigger_category > 0 ) {
                // Kategori kontrolü: SADECE ürün listesi boşsa
                $product_cats = wc_get_product_term_ids( $product_id, 'product_cat' );
                if ( ! empty( $product_cats ) ) {
                    $expanded_product_cats = array_map( 'intval', $product_cats );
                    foreach ( $product_cats as $cat_id ) {
                        $ancestors = get_ancestors( (int) $cat_id, 'product_cat', 'taxonomy' );
                        if ( ! empty( $ancestors ) ) {
                            $expanded_product_cats = array_merge( $expanded_product_cats, array_map( 'intval', $ancestors ) );
                        }
                    }
                    $expanded_product_cats = array_unique( $expanded_product_cats );
                    $is_trigger = in_array( $trigger_category, $expanded_product_cats, true );
                }
            }
            
            // Hedef kontrolü: Ürün öncelikli mantık
            $is_target = false;
            if ( ! empty( $target_products ) && in_array( $product_id, $target_products, true ) ) {
                $is_target = true;
            } elseif ( empty( $target_products ) && $target_category > 0 ) {
                // Kategori kontrolü: SADECE ürün listesi boşsa
                $product_cats = wc_get_product_term_ids( $product_id, 'product_cat' );
                if ( ! empty( $product_cats ) ) {
                    $expanded_product_cats = array_map( 'intval', $product_cats );
                    foreach ( $product_cats as $cat_id ) {
                        $ancestors = get_ancestors( (int) $cat_id, 'product_cat', 'taxonomy' );
                        if ( ! empty( $ancestors ) ) {
                            $expanded_product_cats = array_merge( $expanded_product_cats, array_map( 'intval', $ancestors ) );
                        }
                    }
                    $expanded_product_cats = array_unique( $expanded_product_cats );
                    $is_target = in_array( $target_category, $expanded_product_cats, true );
                }
            }
            
            // Bir ürün hem tetikleyici hem hedef olamaz - sadece tetikleyici say
            if ( $is_trigger && $is_target ) {
                $trigger_count += $quantity;
                // Hedef olarak sayma
            } elseif ( $is_trigger ) {
                $trigger_count += $quantity;
            } elseif ( $is_target ) {
                $target_count += $quantity;
            }
        }
        
        // Koşul: Yeterli tetikleyici VE en az 1 hedef ürün olmalı
        return ( $trigger_count >= $trigger_qty && $target_count > 0 );
    }
    
    /**
     * "Sepet Tutarına Göre İndirim" kampanyasının koşullarını kontrol eder.
     */
    public function validate_cart_total_discount_campaign( $rule ) {
        $min_cart_total = isset( $rule['min_cart_total'] ) ? (float) $rule['min_cart_total'] : 0;
        
        if ( $min_cart_total <= 0 ) {
            return false;
        }

        // Sepet toplamını al
        $cart_total = (float) WC()->cart->get_subtotal();
        
        return $cart_total >= $min_cart_total;
    }
}
