<?php

if ( !defined( 'ABSPATH' ) ) {

    exit;
}

if ( !class_exists( 'Pricely_Pipeline_Product' ) ) {

    class Pricely_Pipeline_Product {

        private static $instance;
        private $promotions_key;
        private $context;
        private $pipeline;

        public static function get_instance(): self {

            if ( !self::$instance ) {

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

            return self::$instance;
        }

        public function __construct() {

            $this->promotions_key = 'promotions';
            $this->context = 'promotions';
        }

        public function get_views( $page_id, $position_id, $product, $variation ) {

            $views = $this->process_views( $page_id, $position_id, $product, $variation );

            if ( !$views ) {

                return false;
            }

            return apply_filters( 'pricely_get-pipeline-product-views', $views, $page_id, $position_id );
        }

        private function process_views( $page_id, $position_id, $product, $variation ) {

            $pipeline_data = $this->get_pipeline_data( $product, $variation );

            if ( !isset( $pipeline_data[ 'views' ] ) ) {

                return false;
            }

            if ( !$pipeline_data[ 'views' ] ) {

                return false;
            }

            $views = array();

            foreach ( $pipeline_data[ 'views' ] as $pipeline_data_views ) {

                $view = $this->process_view( $pipeline_data_views, $page_id, $position_id );

                if ( !$view ) {

                    continue;
                }

                $views[] = $view;
            }


            if ( count( $views ) ) {

                return $views;
            }

            return false;
        }

        private function process_view( $pipeline_data_views, $page_id, $position_id ) {

            if ( !isset( $pipeline_data_views[ $page_id ] ) ) {

                return false;
            }


            $view_position = $pipeline_data_views[ $page_id ][ 'position' ];

            if ( $position_id != $view_position ) {

                return false;
            }

            $default_view = array(
                'id' => $pipeline_data_views[ 'id' ],
                'setting_id' => $pipeline_data_views[ 'setting_id' ],
                'view_source' => $pipeline_data_views[ 'view_source' ],
                'override' => $pipeline_data_views[ 'override' ],
            );

            return $this->merge_array_values( $default_view, $pipeline_data_views[ $page_id ] );
        }

        private function get_pipeline_data( $product, $variation ) {

            $product_id = $product->get_id();
            $variation_id = 0;

            $parent_id = 0;

            if ( !is_null( $variation ) ) {

                $variation_id = $variation->get_id();
            }

            if ( 0 == $variation_id ) {

                $parent_id = $product->get_parent_id();
            }

            if ( $parent_id > 0 && 'variation' == $product->get_type() ) {

                $product_id = $parent_id;
                $variation_id = $product->get_id();
            }

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

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


            $cache_data = $this->pipeline->get_product_cache( $product_id, $variation_id, $this->context );

            if ( isset( $cache_data[ $this->promotions_key ] ) ) {

                return $cache_data[ $this->promotions_key ];
            }

            $data = $this->pipeline->get_product_data( $product, $variation, $this->context );


            if ( isset( $data[ $this->promotions_key ] ) ) {

                return $data[ $this->promotions_key ];
            }

            return false;
        }

        private function merge_array_values( $values, $new_values ) {

            $excl_keys = array_keys( $values );

            foreach ( $new_values as $key => $value ) {

                if ( in_array( $key, $excl_keys ) ) {

                    continue;
                }

                $values[ $key ] = $value;
            }

            return $values;
        }

    }

}