<?php

if ( !defined( 'ABSPATH' ) ) {

    exit;
}

if ( !class_exists( 'Pricely_Product_Promotion_Types' ) ) {

    require_once dirname( __FILE__ ) . '/promotion-types-prices/price-at-checkout.php';
    require_once dirname( __FILE__ ) . '/promotion-types-countdown/countdown.php';
    require_once dirname( __FILE__ ) . '/promotion-types-tables/volumetric-price-table.php';
    require_once dirname( __FILE__ ) . '/promotion-types-label.php';

    class Pricely_Product_Promotion_Types {

        private static $instance;
        private $product_filter_types;
        //Promotion Type
        private $promotion_type_countdown;
        private $promotion_type_volumetric_price_table;
        private $promotion_type_label;

        public static function get_instance(): self {

            if ( !self::$instance ) {

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

            return self::$instance;
        }

        public function __construct() {

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

            //Promotion Types
            $this->promotion_type_countdown = new Pricely_Product_Promotion_Type_CountDown();
            $this->promotion_type_volumetric_price_table = new Pricely_Product_Promotion_Type_Volumetric_Price_Table();
            $this->promotion_type_label = new Pricely_Product_Promotion_Type_Label();
        }

        public function get_promotions( $promotions_args, $data ) {

            $promotions = array();

            $setting_id = $promotions_args[ 'setting_id' ];

            foreach ( $promotions_args[ 'promotions' ] as $promotion_args ) {

                if ( !$this->validate_product( $promotion_args, $data ) ) {

                    continue;
                }


                $promotion_args[ 'setting_id' ] = $setting_id;
                $promotion = $this->get_promotion( $promotion_args, $data );

                if ( !$promotion ) {

                    continue;
                }


                $promotion_id = $promotion_args[ 'id' ];
                $promotions[ $promotion_id ] = $promotion;
            }

            if ( !count( $promotions ) ) {

                return false;
            }

            return $promotions;
        }

        private function get_promotion( $promotion_args, $data ) {

            $default_promotion_data = array(
                'id' => $promotion_args[ 'id' ],
                'setting_id' => $promotion_args[ 'setting_id' ],
                'promotion_type' => $promotion_args[ 'promotion_type' ],
                'product' => $this->get_product_data( $data ),
                'data' => false,
                'views' => false,
                'override' => true,
            );

            $promotion_data = $this->process_data( $default_promotion_data, $promotion_args, $data );

            if ( !$promotion_data[ 'data' ] && !$promotion_data[ 'views' ] ) {

                return false;
            }

            return $promotion_data;
        }

        private function process_data( $promotion_data, $promotion_args, $data ) {

            $promotion_type = $promotion_args[ 'promotion_type' ];

            if ( $this->promotion_type_countdown->can_process_data( $promotion_type ) ) {

                $promotion_data = $this->promotion_type_countdown->process_data( $promotion_data, $promotion_args, $data );
            }

            if ( $this->promotion_type_volumetric_price_table->can_process_data( $promotion_type ) ) {

                $promotion_data = $this->promotion_type_volumetric_price_table->process_data( $promotion_data, $promotion_args, $data );
            }

            if ( $this->promotion_type_label->can_process_data( $promotion_type ) ) {

                $promotion_data = $this->promotion_type_label->process_data( $promotion_data, $promotion_args, $data );
            }

            return apply_filters( 'pricely_product-promotions_process-promotion-data', $promotion_data, $promotion_args, $data );
        }

        private function validate_product( $promotion_args, $data ) {

            $product_args = $this->get_product_args( $promotion_args );

            //defualt all applies to all products
            if ( !$product_args ) {

                return true;
            }

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

        private function get_product_args( $promotion_args ) {

            if ( !isset( $promotion_args[ 'product_args' ] ) ) {

                return false;
            }

            return $promotion_args[ 'product_args' ];
        }

        private function get_product_data( $data ) {

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

                return false;
            }

            return array(
                'type' => $data[ 'wc' ][ 'product' ][ 'type' ],
                'product_id' => $data[ 'wc' ][ 'product' ][ 'product_id' ],
                'variation_id' => $data[ 'wc' ][ 'product' ][ 'variation_id' ],
            );
        }

    }

}
