<?php

if ( !defined( 'ABSPATH' ) ) {

    exit;
}

if ( !class_exists( 'Pricely_Product_Filter_Type_Product' ) ) {

    class Pricely_Product_Filter_Type_Product {

        private $taxonomy_util;
        private $validation_util;
        private $terms_validation_util;
        private $util;
        private $taxonomies;
        private $terms_prefix;

        public function __construct() {

            $this->terms_prefix = 'product_';
        }

        public function can_validate( $filter_type ) {

            $filter_types = array(
                'spec_products',
            );

            if ( in_array( $filter_type, $filter_types ) ) {

                return true;
            }

            return in_array( $filter_type, $this->get_taxonomy_ids() );
        }

        public function validate( $filter_args, $data ) {

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

                $this->validation_util = Pricely_Validation_Util::get_instance();
            }

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

                $this->terms_validation_util = Pricely_Terms_Validation_Util::get_instance();
            }

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

                $this->util = Pricely_Util::get_instance();
            }

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

                return false;
            }

            $product = $data[ 'wc' ][ 'product' ];

            $filter_type = $filter_args[ 'filter_type' ];

            if ( 'spec_products' == $filter_type ) {

                return $this->validate_specific_products( $filter_args, $product );
            }

            if ( in_array( $filter_type, $this->get_taxonomy_ids() ) ) {

                return $this->validate_product_terms( $filter_args, $product, $filter_type );
            }

            return false;
        }

        private function validate_specific_products( $filter_args, $product ) {

            if ( !isset( $filter_args[ 'product_slugs' ] ) ) {

                return false;
            }

            $filter_product_ids = $this->util->get_product_ids_by_slugs( $filter_args[ 'product_slugs' ] );

            if ( !count( $filter_product_ids ) ) {

                return false;
            }

            $filter_compare = $filter_args[ 'compare' ];

            $product_id = $product[ 'product_id' ];

            return $this->validation_util->validate_value_list( $product_id, $filter_product_ids, $filter_compare );
        }

        private function validate_product_terms( $filter_args, $product, $filter_type ) {

            $taxonomy_data = $this->get_taxonomy_by_id( $filter_type );

            if ( false === $taxonomy_data ) {

                return false;
            }

            if ( !isset( $filter_args[ 'term_slugs' ] ) ) {

                return false;
            }

            $filter_term_ids = $this->util->get_product_term_ids_by_slugs( $filter_args[ 'term_slugs' ], $taxonomy_data[ 'taxonomy' ] );

            if ( !count( $filter_term_ids ) ) {

                return false;
            }

            $filter_compare = $filter_args[ 'compare' ];

            $term_ids = $product[ $taxonomy_data[ 'terms_key' ] ];

            return $this->terms_validation_util->validate_list_list( $term_ids, $filter_term_ids, $filter_compare, $taxonomy_data[ 'taxonomy' ], $taxonomy_data[ 'use_ancestors' ] );
        }

        private function get_taxonomy_by_id( $taxonomy_id ) {

            $taxonomies = $this->get_taxonomies();

            if ( isset( $taxonomies[ $taxonomy_id ] ) ) {

                return $taxonomies[ $taxonomy_id ];
            }

            return false;
        }

        private function get_taxonomy_ids() {

            return array_keys( $this->get_taxonomies() );
        }

        private function get_taxonomies() {

            if ( !is_null( $this->taxonomies ) ) {

                return $this->taxonomies;
            }

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

                $this->taxonomy_util = Pricely_Taxonomy_Util::get_instance();
            }

            $this->taxonomies = array();

            foreach ( $this->taxonomy_util->get_taxonomies() as $taxonomy => $taxonomy_data ) {

                $taxonomy_id = $this->terms_prefix . $taxonomy;

                $data = array(
                    'taxonomy' => $taxonomy,
                    'terms_key' => $taxonomy_data[ 'terms_key' ],
                    'use_ancestors' => in_array( 'ancestors', $taxonomy_data[ 'supports' ] )
                );

                $this->taxonomies[ $taxonomy_id ] = $data;
            }

            return $this->taxonomies;
        }

    }

}
