<?php

if ( !defined( 'ABSPATH' ) ) {

    exit;
}

if ( !class_exists( 'Pricely_Product_Promotions_Data' ) ) {

    class Pricely_Product_Promotions_Data {

        public function process_data( $promotions_data ) {

            if ( !is_array( $promotions_data ) ) {

                return false;
            }

            $promotions = array(
                'data' => $this->get_all_data( $promotions_data ),
                'views' => $this->get_all_views( $promotions_data )
            );

            if ( false === $promotions[ 'data' ] && false === $promotions[ 'views' ] ) {

                return false;
            }

            return $promotions;
        }

        private function get_all_data( $promotions_data ) {

            $data = array();

            foreach ( $promotions_data as $promotion_data ) {

                $data = $this->get_data( $data, $promotion_data );
            }

            if ( !count( $data ) ) {

                return false;
            }

            return $data;
        }

        private function get_all_views( $promotions_data ) {

            $views = array();

            foreach ( $promotions_data as $promotion_data ) {

                $views = $this->get_views( $views, $promotion_data );
            }

            if ( !count( $views ) ) {

                return false;
            }

            return $this->process_overridden_views( $views );
        }

        private function get_data( $data, $promotion_data ) {

            foreach ( $promotion_data as $promo_data ) {

                if ( !$promo_data[ 'data' ] ) {

                    continue;
                }

                $default_data = array(
                    'id' => $promo_data[ 'id' ],
                    'setting_id' => $promo_data[ 'setting_id' ],
                    'data_source' => $promo_data[ 'promotion_type' ],
                );

                $data = $this->get_add_data( $data, $default_data, $promo_data );
            }

            return $data;
        }

        private function get_add_data( $data, $default_data, $promo_data ) {

            $excl_keys = array_keys( $default_data );

            foreach ( $promo_data[ 'data' ] as $key => $new_data ) {

                $data[ $key ] = $this->merge_array_values( $default_data, $new_data, $excl_keys );
                $data[ $key ][ 'product' ] = $promo_data[ 'product' ];
            }

            return $data;
        }

        private function process_overridden_views( $in_views ) {

            $view_sources = array();

            $views = array();

            foreach ( $in_views as $key => $in_view ) {


                $view_source = $in_view[ 'view_source' ];

                if ( $in_view[ 'override' ] && isset( $view_sources[ $view_source ] ) ) {

                    $views = $this->remove_prev_views( $views, $view_sources[ $view_source ] );

                    unset( $view_sources[ $view_source ] );
                }

                $views[ $key ] = $in_view;

                $view_sources[ $in_view[ 'view_source' ] ][] = $key;
            }

            return array_values( $views );
        }

        private function remove_prev_views( $views, $view_keys ) {

            foreach ( $view_keys as $view_key ) {

                if ( isset( $views[ $view_key ] ) ) {

                    unset( $views[ $view_key ] );
                }
            }

            return $views;
        }

        private function get_views( $views, $promotion_data ) {

            $in_views = array();

            foreach ( $promotion_data as $promo_data ) {

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

                    continue;
                }

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

                $in_views = $this->get_add_views( $in_views, $default_view, $promo_data );
            }

            if ( !count( $in_views ) ) {

                return $views;
            }

            foreach ( $in_views as $in_view ) {

                $views[] = $in_view;
            }

            return $views;
        }

        private function get_add_views( $views, $default_view, $promo_data ) {

            $excl_keys = array( 'view_id' );

            $view = $default_view;

            foreach ( $promo_data[ 'views' ] as $key => $new_view ) {

                if ( false === $new_view ) {

                    continue;
                }

                if ( isset( $new_view[ 'view_id' ] ) ) {

                    $view[ $key ][ 'view_id' ] = $new_view[ 'view_id' ];
                }

                $view[ $key ] = $this->merge_array_values( $view[ $key ], $new_view, $excl_keys );
                $view[ $key ][ 'product' ] = $promo_data[ 'product' ];
            }


            $views[] = $view;

            return $views;
        }

        private function merge_array_values( $values, $new_values, $excl_keys ) {

            if ( !is_array( $new_values ) ) {

                return $values;
            }

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

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

                    continue;
                }

                $values[ $key ] = $value;
            }

            return $values;
        }

    }

}