<?php

if ( !defined( 'ABSPATH' ) ) {

    exit;
}

if ( !class_exists( 'Pricely_Checkout_Prices_Types_Prices' ) ) {

    class Pricely_Checkout_Prices_Types_Prices {

        private $totals_util;

        public function __construct() {

            $this->totals_util = new Pricely_Totals_Util();
        }

        public function can_calculate( $pricing_type ) {

            $pricing_types = array(
                'fixed_price_item',
                'per_price'
            );

            return in_array( $pricing_type, $pricing_types );
        }

        public function calculate_prices( $prices, $pricing_args, $items ) {

            if ( 'fixed_price_item' == $pricing_args[ 'pricing_type' ] ) {

                return $this->calculate_fixed_price_item( $prices, $pricing_args, $items );
            }

            if ( 'per_price' == $pricing_args[ 'pricing_type' ] ) {

                return $this->calculate_per_price( $prices, $pricing_args, $items );
            }

            return $prices;
        }

        private function calculate_fixed_price_item( $prices, $pricing_args, $items ) {

            $amount = 0;

            if ( is_numeric( $pricing_args[ 'amount' ] ) ) {

                $amount = $pricing_args[ 'amount' ];
            }

            if ( $amount < 0 ) {

                $amount = 0;
            }

            $split_args = $this->get_unit_split_args( $items );

            $item_totals = $this->totals_util->create_total_per_unit( $amount, $split_args, $this->create_zero_totals( $split_args ) );

            $keys = array_keys( $items );

            foreach ( $keys as $key ) {

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

                    continue;
                }

                $prices[ 'items' ][ $key ][ 'based_on' ] = 'regular_price';
                $prices[ 'items' ][ $key ][ 'qty' ] = $item_totals[ $key ][ 'qty' ];
                $prices[ 'items' ][ $key ][ 'prices' ] = $item_totals[ $key ][ 'totals' ];
            }

            return $prices;
        }

        private function calculate_per_price( $prices, $pricing_args, $items ) {

            $per_amount = 0;

            if ( is_numeric( $pricing_args[ 'amount' ] ) ) {

                $per_amount = $pricing_args[ 'amount' ];
            }


            if ( $per_amount < 0 ) {

                $per_amount = 0;
            }

            $split_args = $this->get_unit_split_args( $items );

            $item_prices = array();

            $keys = array_keys( $items );

            foreach ( $keys as $key ) {

                $item = $items[ $key ];

                $item_price = $this->get_item_price( $item );

                $item_prices[ $key ] = $this->totals_util->round( ($per_amount / 100) * $item_price );
            }

            $item_totals = $this->process_total_for_items( $item_prices, $split_args );

            foreach ( $keys as $key ) {

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

                    continue;
                }

                $prices[ 'items' ][ $key ][ 'based_on' ] = 'regular_price';
                $prices[ 'items' ][ $key ][ 'qty' ] = $item_totals[ $key ][ 'qty' ];
                $prices[ 'items' ][ $key ][ 'prices' ] = $item_totals[ $key ][ 'totals' ];
            }

            return $prices;
        }

        private function get_unit_split_args( $items ) {

            $split_args = array(
                'items' => array()
            );

            foreach ( $items as $key => $item ) {

                $qty = $this->get_item_quantity( $item );

                $split_args[ 'items' ][ $key ][ 'qty' ] = $qty;
            }

            return $split_args;
        }

        private function get_item_quantity( $item ) {

            if ( isset( $item[ 'pricing_quantity' ] ) ) {

                return $item[ 'pricing_quantity' ];
            }

            return 1;
        }

        private function get_item_price( $item ) {

            if ( isset( $item[ 'source_prices' ][ 'regular_price' ] ) ) {

                $price = $item[ 'source_prices' ][ 'regular_price' ];

                if ( is_numeric( $price ) ) {

                    return $price;
                }
            }

            if ( isset( $item[ 'wc' ][ 'product' ][ 'regular_price' ] ) ) {

                $price = $item[ 'wc' ][ 'product' ][ 'regular_price' ];

                if ( is_numeric( $price ) ) {

                    return $price;
                }
            }

            return 0;
        }

        private function create_zero_totals( $split_args ) {

            $item_totals = array();

            foreach ( $split_args[ 'items' ] as $item_key => $item ) {

                $item_totals[ $item_key ][ 'qty' ] = $item[ 'qty' ];

                for ( $i = 0; $i < $item[ 'qty' ]; $i++ ) {

                    $item_totals[ $item_key ][ 'totals' ][] = 0;
                }
            }

            return $item_totals;
        }

        private function process_total_for_items( $item_prices, $split_args ) {

            $item_totals = array();

            foreach ( $split_args[ 'items' ] as $item_key => $item ) {

                if ( !isset( $item_prices[ $item_key ] ) ) {

                    continue;
                }

                $item_totals[ $item_key ][ 'qty' ] = $item[ 'qty' ];

                for ( $i = 0; $i < $item[ 'qty' ]; $i++ ) {

                    $item_totals[ $item_key ][ 'totals' ][] = $item_prices[ $item_key ];
                }
            }

            return $item_totals;
        }

    }

}