<?php

if ( !defined( 'ABSPATH' ) ) {

    exit;
}

if ( !class_exists( 'Pricely_View_Data_Tables_Volumetric_Price_Range' ) ) {

    class Pricely_View_Data_Tables_Volumetric_Price_Range {

        private $view_data;
        private $quantity_util;
        private $price_ranges;

        public function __construct() {

            $this->quantity_util = Pricely_Quantity_Util::get_instance();
        }

        public function get_data( $price_options, $product ) {

            $this->price_ranges = false;

            $pricing_id = 0;
            $mode = '';

            foreach ( $price_options as $price_option ) {

                $pricing_id = $price_option[ 'pricing_id' ];
                $mode = $price_option[ 'mode' ];

                $this->price_ranges = $this->get_price_ranges( $price_option[ 'ranges' ], $product );
            }

            if ( false === $this->price_ranges ) {

                return false;
            }

            return array(
                'pricing_id' => $pricing_id,
                'mode' => $mode,
                'ranges' => $this->price_ranges
            );
        }

        private function get_price_ranges( $ranges, $product ) {

            $price_ranges = array();

            $price_key = 'price';

            if ( 'variable' == $product[ 'type' ] ) {

                $price_key = 'prices';
            }

            foreach ( $this->get_ranges( $ranges ) as $range ) {

                $prices = $this->get_prices( $range[ 'price_args' ], $product );

                $price_range = array(
                    'id' => $range[ 'id' ],
                    'min' => $range[ 'min' ],
                );

                if ( isset( $range[ 'max' ] ) ) {

                    $price_range[ 'max' ] = $range[ 'max' ];
                } else {

                    $price_range[ 'max' ] = false;
                }

                $price_range[ 'excluded' ] = $range[ 'excluded' ];
                $price_range[ $price_key ] = $prices;

                $price_ranges[] = $price_range;
            }

            return $price_ranges;
        }

        private function get_ranges( $price_ranges ) {

            $processed_ranges = $this->quantity_util->process_ranges( $this->get_range_args( $price_ranges ), false );

            if ( !$processed_ranges ) {

                return false;
            }

            $ranges = array();

            foreach ( $processed_ranges as $range ) {

                $range_id = -1;
                $price_args = false;

                if ( isset( $range[ 'id' ] ) ) {

                    $range_id = $range[ 'id' ];
                }

                if ( isset( $price_ranges[ $range_id ] ) ) {

                    $price_args = $this->get_price_args( $price_ranges[ $range_id ] );
                }

                $range[ 'id' ] = $range_id;
                $range[ 'excluded' ] = false;
                $range[ 'price_args' ] = $price_args;

                $ranges[] = $range;
            }

            if ( !count( $ranges ) ) {

                return false;
            }

            return $ranges;
        }

        private function get_range_args( $ranges ) {

            $range_args = array();

            foreach ( $ranges as $range_id => $range ) {

                $range_arg = array(
                    'id' => $range_id
                );

                $min = 1;

                if ( is_numeric( $range[ 'min' ] ) ) {

                    $min = $range[ 'min' ];
                }

                $range_arg[ 'min' ] = $min;

                if ( is_numeric( $range[ 'max' ] ) ) {

                    $range_arg[ 'max' ] = $range[ 'max' ];
                }

                $range_args[] = $range_arg;
            }

            return $range_args;
        }

        private function get_price_args( $price_range ) {

            return array(
                'pricing_type' => $price_range[ 'pricing_type' ],
                'amount' => $price_range[ 'amount' ],
                'per_based_on' => $price_range[ 'per_based_on' ],
            );
        }

        private function get_prices( $price_args, $product ) {

            if ( 'variable' == $product[ 'type' ] ) {

                return $this->get_variation_prices( $price_args, $product );
            }

            $product_id = $product[ 'product_id' ];
            $variation_id = $product[ 'variation_id' ];

            return $this->get_price_at_checkout( $price_args, $product_id, $variation_id );
        }

        private function get_variation_prices( $price_args, $product ) {

            $product_id = $product[ 'product_id' ];

            $prices = array();

            foreach ( $this->get_variation_ids_by_id( $product_id ) as $variation_id ) {

                $price = $this->get_price_at_checkout( $price_args, $product_id, $variation_id );

                $prices[ $variation_id ] = $price;
            }

            return $prices;
        }

        private function get_variation_ids_by_id( $product_id ) {

            return Pricely_Product::get_instance()->get_variation_ids_by_id( $product_id );
        }

        private function get_price_at_checkout( $price_args, $product_id, $variation_id ) {

            if ( is_null( $this->view_data ) ) {

                $this->view_data = Pricely_View_Data::get_instance();
            }

            $price = $this->view_data->get_price_at_checkout( $price_args, $product_id, $variation_id );

            $limit_args = false;

            return apply_filters( 'pricely_view-data_get-price-at-checkout', $price, $price_args, $limit_args, $product_id, $variation_id );
        }

    }

}