<?php

if ( !defined( 'ABSPATH' ) ) {

    exit;
}

if ( !class_exists( 'Pricely_Pipeline_Order_Usage_Counts' ) ) {

    class Pricely_Pipeline_Order_Usage_Counts {

        private $pipeline;
        private $last_context = 'cart_prices';
        private $adjusted_prices_key = 'adjusted_prices';
        private $calculated_prices_key = 'calculated_prices';
        private $store_key = 'pricely_usage_count';

        public function get_cart_data( $coupons_data ) {

            return $this->get_shop_pricing_ids( false, $coupons_data );
        }

        public function save_data( $usage_ids, $user_id ) {

            $this->save_count_data( $usage_ids );

            $this->save_user_count_data( $usage_ids, $user_id );
        }

        private function save_count_data( $usage_ids ) {

            $stored_usage_counts = get_option( $this->store_key, array() );

            if ( !is_array( $stored_usage_counts ) ) {

                $stored_usage_counts = array();
            }

            $usage_counts = $this->process_usage_counts( $stored_usage_counts, $usage_ids );

            update_option( $this->store_key, $usage_counts, false );
        }

        private function save_user_count_data( $usage_ids, $user_id ) {

            if ( $user_id <= 0 ) {

                return;
            }

            $stored_usage_counts = get_user_meta( $user_id, $this->store_key, true );

            if ( !is_array( $stored_usage_counts ) ) {

                $stored_usage_counts = array();
            }

            $usage_counts = $this->process_usage_counts( $stored_usage_counts, $usage_ids );

            update_user_meta( $user_id, $this->store_key, $usage_counts );
        }

        private function get_shop_pricing_ids( $usage_ids, $coupons_data ) {

            $data = $this->get_pipeline_data( $this->adjusted_prices_key );

            if ( !$data ) {

                return $this->get_cart_pricing_ids( $usage_ids, $coupons_data );
            }

            if ( !is_array( $data ) ) {

                return $this->get_cart_pricing_ids( $usage_ids, $coupons_data );
            }

            $pricing_ids = array();

            foreach ( $data as $item_data ) {

                if ( !isset( $item_data[ 'ids' ] ) ) {

                    continue;
                }

                $pricing_ids = $this->add_to_ids( $item_data[ 'ids' ], $pricing_ids );
            }

            if ( !count( $pricing_ids ) ) {

                return $this->get_cart_pricing_ids( $usage_ids, $coupons_data );
            }

            if ( false === $usage_ids ) {

                $usage_ids = array();
            }

            $usage_ids[ 'product_pricing' ] = $pricing_ids;

            return $this->get_cart_pricing_ids( $usage_ids, $coupons_data );
        }

        private function get_cart_pricing_ids( $usage_ids, $coupons_data ) {

            $data = $this->get_pipeline_data( $this->calculated_prices_key );

            if ( !$data ) {

                return $this->get_cart_discounts_ids( $usage_ids, $coupons_data );
            }

            if ( !isset( $data[ 'items' ] ) || !$data[ 'items' ] ) {

                return $this->get_cart_discounts_ids( $usage_ids, $coupons_data );
            }

            $pricing_ids = array();

            foreach ( $data[ 'items' ] as $item ) {

                if ( !isset( $item[ 'pricing_id' ] ) ) {

                    continue;
                }

                if ( !isset( $item[ 'coupon_id' ] ) ) {

                    continue;
                }


                $pricing_id = $item[ 'pricing_id' ];

                if ( in_array( $pricing_id, $pricing_ids ) ) {

                    continue;
                }

                $pricing_ids[] = $pricing_id;
            }


            if ( !count( $pricing_ids ) ) {

                return $this->get_cart_discounts_ids( $usage_ids, $coupons_data );
            }

            if ( false === $usage_ids ) {

                $usage_ids = array();
            }

            $usage_ids[ 'checkout_pricing' ] = $pricing_ids;

            return $this->get_cart_discounts_ids( $usage_ids, $coupons_data );
        }

        private function get_cart_discounts_ids( $usage_ids, $coupons_data ) {

            if ( !is_array( $coupons_data ) ) {

                return $usage_ids;
            }

            $discount_ids = array();

            foreach ( $coupons_data as $coupon_data ) {

                if ( !isset( $coupon_data[ 'cart_discounts' ] ) ) {

                    continue;
                }

                $discount_ids = $this->add_to_coupon_data_discount_to_ids( $discount_ids, $coupon_data[ 'cart_discounts' ] );
            }

            if ( !count( $discount_ids ) ) {

                return $usage_ids;
            }

            if ( false === $usage_ids ) {

                $usage_ids = array();
            }

            $usage_ids[ 'cart_discounts' ] = $discount_ids;

            return $usage_ids;
        }

        private function get_pipeline_data( $data_key ) {

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

                $this->pipeline = Pricely_Pipeline::get_instance();
            }


            $cache_data = $this->pipeline->get_cache( $this->last_context );

            if ( isset( $cache_data[ $data_key ] ) ) {

                return $cache_data[ $data_key ];
            }

            return false;
        }

        private function add_to_coupon_data_discount_to_ids( $discount_ids, $coupon_data ) {

            foreach ( $coupon_data as $data ) {

                if ( !isset( $data[ 'discount_id' ] ) ) {

                    continue;
                }

                $discount_id = $data[ 'discount_id' ];

                if ( in_array( $discount_id, $discount_ids ) ) {

                    continue;
                }

                $discount_ids[] = $discount_id;
            }

            return $discount_ids;
        }

        private function add_to_ids( $new_ids, $old_ids ) {

            foreach ( $new_ids as $new_id ) {

                if ( in_array( $new_id, $old_ids ) ) {

                    continue;
                }

                $old_ids[] = $new_id;
            }

            return $old_ids;
        }

        private function process_usage_counts( $usage_counts, $usage_ids ) {

            foreach ( $usage_ids as $module_id => $module_usage_ids ) {

                if ( !count( $module_usage_ids ) ) {

                    continue;
                }

                if ( !isset( $usage_counts[ $module_id ] ) ) {

                    $usage_counts[ $module_id ] = array();
                }

                $usage_counts[ $module_id ] = $this->process_module_usage_counts( $usage_counts[ $module_id ], $module_usage_ids );
            }

            return $usage_counts;
        }

        private function process_module_usage_counts( $module_usage_counts, $module_usage_ids ) {

            foreach ( $module_usage_ids as $usage_id ) {

                if ( !isset( $module_usage_counts[ $usage_id ] ) ) {

                    $module_usage_counts[ $usage_id ] = 0;
                }

                $module_usage_counts[ $usage_id ]++;
            }

            return $module_usage_counts;
        }

    }

}
