<?php

if ( !defined( 'ABSPATH' ) ) {

    exit;
}

if ( !class_exists( 'Pricely_Cart_Discounts_Coupons_Util' ) ) {

    class Pricely_Cart_Discounts_Coupons_Util {

        public function get_coupon_discounts( $discount_data, $coupon_id, $coupon_code, $discounts, $in_prev_totals ) {

            //process previous coupon discount totals
            $prev_totals = $this->add_prev_totals( $this->process_prev_totals( $in_prev_totals, $coupon_code ), $discount_data[ 'totals' ] );

            //go through all discount totals and process them
            foreach ( $discounts as $discount ) {

                //check whether coupon ID is valid
                if ( !isset( $discount[ 'coupon_id' ] ) ) {

                    continue;
                }

                if ( $coupon_id != $discount[ 'coupon_id' ] ) {

                    continue;
                }

                //Process totals
                $totals = $this->process_discount_totals( $discount[ 'totals' ], $prev_totals );

                //add totals to previous totals
                $prev_totals = $this->add_prev_totals( $prev_totals, $totals );

                //prepare discount toals
                $cart_discount = array(
                    'discount_id' => $discount[ 'discount_id' ],
                    'totals' => $totals,
                    'total' => array_sum( $totals ),
                );

                $discount_data[ 'cart_discounts' ][] = $cart_discount;

                $coupon_totals = $this->process_coupon_totals( $discount_data[ 'totals' ], $totals );

                $discount_data[ 'totals' ] = $coupon_totals;

                $discount_data[ 'total' ] = array_sum( $coupon_totals );
            }

            return $discount_data;
        }

        private function process_discount_totals( $discount_totals, $prev_totals ) {

            $totals = array();

            foreach ( $discount_totals as $item_key => $item_totals ) {

                $item_total = $this->adjust_discount_item_total( $item_totals[ 'total' ], $item_key, $prev_totals );

                $totals[ $item_key ] = $item_total;
            }

            return $totals;
        }

        private function process_coupon_totals( $coupon_totals, $totals ) {

            foreach ( $totals as $key => $total ) {

                if ( !isset( $coupon_totals[ $key ] ) ) {

                    $coupon_totals[ $key ] = 0;
                }

                $coupon_totals[ $key ] += $total;
            }

            return $coupon_totals;
        }

        private function adjust_discount_item_total( $item_total, $item_key, $prev_totals ) {

            if ( !isset( $prev_totals[ 'subtotals' ][ $item_key ] ) ) {

                return $item_total;
            }

            $prev_subtotal = $prev_totals[ 'subtotals' ][ $item_key ];

            $discount = 0;

            if ( isset( $prev_totals[ 'discounts' ][ $item_key ] ) ) {

                $discount = $prev_totals[ 'discounts' ][ $item_key ];
            }

            $remainder = $prev_subtotal - $discount;

            if ( $remainder <= 0 ) {

                return 0;
            }

            if ( $remainder < $item_total ) {

                return $remainder;
            }

            return $item_total;
        }

        private function process_prev_totals( $in_prev_totals, $coupon_code ) {

            $prev_totals = array(
                'subtotals' => array(),
                'discounts' => array()
            );

            if ( isset( $in_prev_totals[ 'subtotals' ] ) ) {

                $prev_totals[ 'subtotals' ] = $in_prev_totals[ 'subtotals' ];
            }

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

                return $prev_totals;
            }

            foreach ( $in_prev_totals[ 'coupons' ] as $code => $coupon_totals ) {

                if ( $code == $coupon_code ) {

                    return $prev_totals;
                }

                $prev_totals[ 'discounts' ] = $this->merge_totals( $prev_totals[ 'discounts' ], $coupon_totals );
            }

            return $prev_totals;
        }

        private function add_prev_totals( $prev_totals, $new_totals ) {

            $prev_totals[ 'discounts' ] = $this->merge_totals( $prev_totals[ 'discounts' ], $new_totals );

            return $prev_totals;
        }

        private function merge_totals( $totals, $new_totals ) {

            foreach ( $new_totals as $key => $total ) {

                if ( !isset( $totals[ $key ] ) ) {

                    $totals[ $key ] = 0;
                }

                $totals[ $key ] += $total;
            }

            return $totals;
        }

    }

}