<?php

if ( !defined( 'ABSPATH' ) ) {

    exit;
}

if ( !class_exists( 'Pricely_Checkout_Prices_Modes' ) ) {

    require_once (dirname( __FILE__ ) . '/checkout-price-mode-simple.php');
    require_once (dirname( __FILE__ ) . '/checkout-price-mode-range/range.php');

    class Pricely_Checkout_Prices_Modes {

        private static $instance;
        private $item_list;
        private $product_filter_types;
        private $pricing_mode_simple;
        private $pricing_mode_range;

        public static function get_instance(): self {

            if ( !self::$instance ) {

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

            return self::$instance;
        }

        public function __construct() {

            $this->item_list = array();

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

            $this->pricing_mode_simple = new Pricely_Checkout_Prices_Modes_Simple();
            $this->pricing_mode_range = new Pricely_Checkout_Prices_Modes_Range();
        }

        public function calculate_prices( $items, $prices_args ) {

            $prices = array(
                'pricing_id' => $prices_args[ 'pricing_id' ],
                'items' => array()
            );

            $this->item_list = $items;

            $pricing_mode = $prices_args[ 'mode' ];

            if ( $this->pricing_mode_simple->can_calculate( $pricing_mode ) ) {

                $prices = $this->pricing_mode_simple->calculate_prices( $prices, $prices_args );
            }

            if ( $this->pricing_mode_range->can_calculate( $pricing_mode ) ) {

                $prices = $this->pricing_mode_range->calculate_prices( $prices, $prices_args );
            }

            $filter_key = 'checkout-pricing_calculate-' . $pricing_mode . '-mode-prices';

            if ( has_filter( 'pricely_' . $filter_key ) ) {

                $prices = apply_filters( 'pricely_' . $filter_key, $prices, $prices_args );
            }

            return $this->process_prices( $prices );
        }

        public function get_items( $args ) {

            $items = array();

            //go through each item and validate them
            foreach ( $this->item_list as $key => $item ) {

                //set item contex
                $item[ 'wc' ][ 'context' ] = $args[ 'context' ];

                //validate item
                if ( !$this->validate_item( $item, $args[ 'product_args' ] ) ) {

                    continue;
                }

                $items[ $key ] = $item;
            }

            if ( $args[ 'group_by' ] ) {

                return $this->group_items_by_product_ids( $items );
            }

            return $items;
        }

        private function validate_item( $item, $product_args ) {

            //validation not applicable
            if ( !count( $product_args ) ) {

                return true;
            }

            //validate product
            return $this->product_filter_types->validate_product( $item, $product_args );
        }

        private function group_items_by_product_ids( $items ) {

            $grouped_items = array();

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

                $qty = $item[ 'items_in_cart' ][ 'quantity' ];

                $product_id = $item[ 'wc' ][ 'product' ][ 'product_id' ];

                if ( !isset( $grouped_items[ $product_id ][ 'qty' ] ) ) {

                    $grouped_items[ $product_id ][ 'qty' ] = 0;
                }

                $grouped_items[ $product_id ][ 'qty' ] += $qty;

                $grouped_items[ $product_id ][ 'items' ][ $key ] = $item;
            }

            return $grouped_items;
        }

        private function process_prices( $prices ) {

            if ( isset( $prices[ 'items' ] ) ) {

                $prices[ 'items' ] = $this->process_prices_items( $prices[ 'items' ] );
            }

            return $prices;
        }

        private function process_prices_items( $in_items ) {

            $items = array();

            foreach ( $in_items as $item_key => $item ) {

                $qty = $item[ 'qty' ];

                if ( isset( $this->item_list[ $item_key ][ 'items_in_cart' ][ 'quantity' ] ) ) {

                    $qty = $this->item_list[ $item_key ][ 'items_in_cart' ][ 'quantity' ];
                }

                $items[ $item_key ][ 'item_qty' ] = $qty;

                $items = $this->process_key_values( $items, $item_key, $item );
            }

            return $items;
        }

        private function process_key_values( $items, $item_key, $item ) {

            $keys = array_keys( $item );

            foreach ( $keys as $key ) {

                $items[ $item_key ][ $key ] = $item[ $key ];
            }

            return $items;
        }

    }

}

