<?php

if ( !defined( 'ABSPATH' ) ) {

    exit;
}

if ( !class_exists( 'Pricely_Cart_Discounts' ) ) {

    class Pricely_Cart_Discounts {

        private $data_key;
        private $cart_discounts_engine;
        private $cart_discounts_data;
        private $items_list;
        private $discounts_list;
        private $item_data_is_set;

        public function __construct() {

            $this->data_key = 'cart_discounts';
            $this->items_list = array();
            $this->discounts_list = false;
            $this->item_data_is_set = false;
        }

        private function init() {

            if ( $this->cart_discounts_engine ) {

                return;
            }

            $this->cart_discounts_engine = new Pricely_Cart_Discounts_Engine();
            $this->cart_discounts_data = new Pricely_Cart_Discounts_Data();
        }

        public function clear_cache() {

            //initialise all
            $this->init();
            $this->items_list = array();
            $this->discounts_list = false;
            $this->item_data_is_set = false;

            $this->cart_discounts_engine->clear_cache();
        }

        public function get_cache( $data, $context ) {

            //initialise all
            $this->init();
            $this->discounts_list = false;

            //get cache discounts from engine
            $cache_discounts = $this->cart_discounts_engine->get_cache( $context );

            if ( $cache_discounts ) {

                $data[ $this->data_key ] = $cache_discounts;

                $this->set_item_discounts( $cache_discounts );
            }

            return $data;
        }

        public function get_product_cache( $data ) {

            //initialise all
            $this->init();

            //check whether discounts was previously calculated 
            if ( !$this->discounts_list ) {

                return $data;
            }

            //get discount key
            $key = '';

            if ( isset( $data[ 'wc' ][ 'product' ][ 'key' ] ) ) {

                $key = $data[ 'wc' ][ 'product' ][ 'key' ];
            }

            if ( empty( $key ) ) {

                return $data;
            }

            //set the discount
            if ( isset( $this->discounts_list[ $key ] ) ) {

                $data[ $this->data_key ] = $this->discounts_list[ $key ];
            }

            return $data;
        }

        public function process_product_data( $data ) {

            //initialise all
            $this->init();
            $this->set_items_list( $data );

            //check whether discounts was previously calculated 
            if ( !$this->discounts_list ) {

                return $data;
            }

            //get discount key
            $key = '';

            if ( isset( $data[ 'wc' ][ 'product' ][ 'key' ] ) ) {

                $key = $data[ 'wc' ][ 'product' ][ 'key' ];
            }

            if ( empty( $key ) ) {

                return $data;
            }

            //set the discount
            if ( isset( $this->discounts_list[ $key ] ) ) {

                $data[ $this->data_key ] = $this->discounts_list[ $key ];
            }

            return $data;
        }

        public function process_data( $data, $context ) {

            //initialise all
            $this->init();
            $this->discounts_list = false;

            //get cache discounts from engine
            $cache_discounts = $this->cart_discounts_engine->get_cache( $context );

            if ( $cache_discounts ) {

                $data[ $this->data_key ] = $cache_discounts;

                $this->set_item_discounts( $cache_discounts );

                return $data;
            }


            //process data from engine
            $discounts_data = $this->cart_discounts_engine->get_data( $data, $context, $this->items_list );

            if ( !is_array( $discounts_data ) ) {

                $this->cart_discounts_engine->store_cache( false );

                return $data;
            }

            //process data as discounts and store as cache
            $discounts = $this->cart_discounts_data->process_data( $discounts_data );

            if ( $discounts ) {

                $data[ $this->data_key ] = $discounts;

                $this->set_item_discounts( $discounts );

                $this->cart_discounts_engine->store_cache( $discounts );
            }

            return $data;
        }

        private function set_items_list( $data ) {

            if ( !isset( $data[ 'items_in_cart' ][ 'quantity' ] ) ) {

                return;
            }

            if ( !isset( $data[ 'wc' ][ 'product' ][ 'key' ] ) ) {

                return;
            }

            $item_key = $data[ 'wc' ][ 'product' ][ 'key' ];

            if ( isset( $this->items_list[ $item_key ] ) && $this->item_data_is_set ) {

                return;
            }

            $this->items_list[ $item_key ] = $data;
        }

        private function set_item_discounts( $discounts ) {

            if ( !isset( $discounts[ 'discounts' ] ) ) {

                return;
            }

            $coupon_codes = $this->get_coupon_codes( $discounts );

            $item_discounts = array();

            foreach ( $discounts[ 'discounts' ] as $discount ) {

                $item_discounts = $this->process_item_discount( $item_discounts, $discount, $coupon_codes );
            }

            if ( count( $item_discounts ) ) {

                $this->item_data_is_set = true;

                $this->discounts_list = $item_discounts;
            }
        }

        private function process_item_discount( $item_discounts, $discount, $coupon_codes ) {

            foreach ( $discount[ 'totals' ] as $item_key => $item_totals ) {

                $coupon_id = $discount[ 'coupon_id' ];

                $item_discount = array(
                    'discount_id' => $discount[ 'discount_id' ],
                    'inclusive_tax' => $discount[ 'inclusive_tax' ],
                    'total' => $item_totals[ 'total' ],
                    'taxes' => $item_totals[ 'taxes' ],
                    'total_tax' => $item_totals[ 'total_tax' ],
                    'coupon_id' => $coupon_id,
                    'coupon_code' => $coupon_codes[ $coupon_id ]
                );


                $item_discounts[ $item_key ][] = $item_discount;
            }

            return $item_discounts;
        }

        private function get_coupon_codes( $discounts ) {

            $coupon_codes = array();

            if ( !isset( $discounts[ 'coupons' ] ) ) {

                return $coupon_codes;
            }


            foreach ( $discounts[ 'coupons' ] as $coupon_data ) {

                $coupon_id = $coupon_data[ 'id' ];

                $coupon_code = $coupon_data[ 'coupon_code' ];

                $coupon_codes[ $coupon_id ] = $coupon_code;
            }

            return $coupon_codes;
        }

    }

}
