<?php

//The heart of the magic
class SOFT79_Rule_Controller {
        
    public function __construct( $options = null ) {
        $this->options = $options;
        
    }  

    public function is_pro() {
        return is_a( $this, 'SOFT79_Rule_Controller_PRO' );
    } 
    
    public function get_valid_rules_for( $product ) {    
        $valid_rules = array();
        // For the free version the only valid rule would be the meta contained in the product or variations itself
        $valid_rules[] = array( new SOFT79_Bulk_Rule( $product->post ) ) ;

        if ( is_a( $product, 'WC_Product_Variation') ) {
            $valid_rules[] = new SOFT79_Bulk_Rule( $product->variation_id );
        }

    }
    
    //We cheat by setting the product price to bulk price 
    public function execute() {
        $cart = WC()->cart;
        
        foreach ( $cart->get_cart() as $cart_item_key => $values ) {
            $product = $values['data'];
            $qty = $values['quantity'];            
            $rule = new SOFT79_Bulk_Rule( $product->post );
            
            $total_discount = $rule->get_discount_for_product($product, $qty, $data);
            if ( $total_discount !== false ) {
                $this->set_temp_data( $product, 'stack_min_price', $data['min'] );
                $this->set_temp_data( $product, 'stack_max_price', $data['max'] );
                $this->set_product_bulk_price( $product, $data['avg'] );
            }
        }
    }

    /**
     *  If a discount applies for qty 1, get the discounted price. Otherwise returns false
     */
    public function get_sale_price( $product ) {
        $min_price = false;
        foreach ( $this->get_valid_rules_for( $product ) as $price_rule ) {
            $discount = $price_rule->get_discount_for_product( $product, 1, $data );
            if ( $discount !== false && ( $min_price === false || $data['avg'] < $min_price  ) ) {
                $min_price = $data['avg'];
            }
        }
        if ( $min_price !== false ) {
            return  $min_price;
        }
        return false;
    }    

// ===============================================================
// Apply temporary data to the products during cart calculations
// ===============================================================

    //All temporary data is stored here
    protected $product_temp_data = array();

    /**
     * Generate a key under which the temp data will be stored
     */
    protected function get_temp_key( $product ) {
        $temp_data_key = $product->id;
        if ( isset( $product->variation_id ) ) {
            $temp_data_key .= "#" . $product->variation_id;
        }
        return $temp_data_key;        
    }
        
    /**
     *  Append temporary metadata to the product for during the cart calculation
     */
    public function set_temp_data( $product, $key, $value ) {
        //error_log ( sprintf('set_product_temp_data %s %s %s', $product->id, $key, $value ));
        $this->product_temp_data[ $this->get_temp_key( $product ) ][$key] = $value;
    }
    
    /**
     *  Fetch temporary metadata from the product for during the cart calculation.
     *  Returns $default value if key not found
     */    
    public function get_temp_data( $product, $key, $default = null ) {
        $temp_data_key = $this->get_temp_key( $product );
        if ( isset( $this->product_temp_data[$temp_data_key][$key] ) ) {
            return $this->product_temp_data[$temp_data_key][$key];
        } else {
            return $default;
        }
    }    
    
    /**
     *  Set the product price and sale_price to the bulk price
     */
    public function set_product_bulk_price( $product, $bulk_price ) {
        //If no price change, don't do anything. This will avoid having a from_to string with the same prices
        if ( $bulk_price != $product->get_price() ) {
            if ( $this->get_temp_data( $product, 'original_price' ) === null ) {
                $this->set_temp_data( $product, 'original_price', $product->get_price() );
                $this->set_temp_data( $product, 'original_sale_price', $product->get_sale_price() );
            }
            $product->set_price( $bulk_price );
            $product->sale_price = $bulk_price;
        }
    }
    
    public function is_pricing_rule_applied( $product ) {
        return $this->get_temp_data( $product, 'original_price' ) !== null;
    }    
    
    public function get_original_price( $product ) {
        $orig_price = $this->get_temp_data( $product, 'original_price', $product->get_price() );
        //error_log("Orig: " . $orig_price);
        return $orig_price;
    }
    
    public function get_original_sale_price( $product ) {
        return $this->get_temp_data( $product, 'original_sale_price', $product->get_sale_price() );
    }        

}
