<?php

if ( !defined( 'ABSPATH' ) ) {

    exit;
}

if ( !class_exists( 'Pricely_Product_Promotion_Type_Volumetric_Price_Table_Range' ) ) {

    class Pricely_Product_Promotion_Type_Volumetric_Price_Table_Range {

        private static $instance;
        private $valid_options;
        private $product_filter_types;
        private $prices_options_key;
        private $prices_settings_key;

        private function __construct() {

            $this->product_filter_types = Pricely_Product_Filter_Types::get_instance();

            $this->valid_options = array();
            $this->prices_options_key = 'checkout_pricings';
            $this->prices_settings_key = 'checkout_pricings_settings';
        }

        public static function get_instance(): self {

            if ( !self::$instance ) {

                self::$instance = new self();
            }

            return self::$instance;
        }

        public function get_data( $pricing_args, $data ) {

            $settings = $this->get_settings();

            if ( 'no' == $settings[ 'mode' ] ) {

                return false;
            }

            return $this->get_valid_price_options( $pricing_args, $data );
        }

        private function get_valid_price_options( $pricing_args, $data ) {

            $promotion_id = $pricing_args[ 'promotion_id' ];
            $product_id = $data[ 'wc' ][ 'product' ][ 'product_id' ];

            // check for already validated options
            if ( isset( $this->valid_options[ $promotion_id ][ $product_id ] ) ) {

                return $this->valid_options[ $promotion_id ][ $product_id ];
            }

            // go through each options and validate them
            foreach ( $this->get_price_options() as $price_option ) {

                //validate price options
                if ( !$this->validate_price_option( $price_option, $data ) ) {

                    continue;
                }

                //process price options
                $valid_option = array(
                    'pricing_id' => $price_option[ 'pricing_id' ],
                    'mode' => $price_option[ 'mode' ],
                    'ranges' => $price_option[ 'ranges' ],
                );

                $this->valid_options[ $promotion_id ][ $product_id ][] = $valid_option;
            }

            //return all valid options
            if ( isset( $this->valid_options[ $promotion_id ][ $product_id ] ) ) {

                return $this->valid_options[ $promotion_id ][ $product_id ];
            }

            return false;
        }

        private function validate_price_option( $price_option, $data ) {

            // check whether option is active
            if ( 'no' == $price_option[ 'enable' ] ) {

                return false;
            }

            //check whether pricing type is bulk or tiered
            $pricing_types = array( 'bulk' );

            if ( !in_array( $price_option[ 'mode' ], $pricing_types ) ) {

                return false;
            }

            //check whether pricing ranges are set
            if ( !isset( $price_option[ 'ranges' ] ) || !count( $price_option[ 'ranges' ] ) ) {

                return false;
            }

            // validate product
            $product_args = false;

            if ( isset( $price_option[ 'product_args' ] ) ) {

                $product_args = $price_option[ 'product_args' ];
            }

            return $this->validate_product( $data, $product_args );
        }

        private function validate_product( $data, $product_args ) {

            if ( !$product_args ) {

                return true;
            }

            return $this->product_filter_types->validate_product( $data, $product_args );
        }

        private function get_price_options() {

            $rules = array();

            foreach ( $this->get_options( $this->prices_options_key, array() ) as $rule ) {

                $rules[] = $rule;
            }

            return $rules;
        }

        private function get_settings() {

            $default = array(
                'mode' => 'no',
            );

            return $this->get_options( $this->prices_settings_key, $default );
        }

        private function get_options( $option_key, $default ) {

            $pricely = Pricely::get_instance();

            return $pricely->get_options( $option_key, $default );
        }

    }

}