<?php

/**
 * Class LEAPIN_Query
 *
 * @author LeapIn Corp.
 * @since 1.0.0
 */
class LEAPIN_Query
{
    public $layout_type;
    public $font_color;
    public $tax_decor;
    public $title;
    public $show_date;
    public $show_taxonomy;
    public $show_view_count;
    public $post_type;
    public $post_ids;
    public $post_id;
    public $posts_per_page;
    public $theme_color;
    public $grayscale;
    public $thumbnail_size;
    public $related_post;
    public $paged;
    public $args;
    public $the_query;
    public $call_with_ajax = false;
    public $exclude_post_ids;
    public $term_ids_or_slugs;
    public $custom_fields;
    public $more;
    public $taxonomy;
    public $order_by;
    public $call_type;
    public $year;
    public $month;
    public $day;
    public $s;
    public $author;
    public $call_position;
    public $is_big_thumbnail;
    public $ajax_on_load_call;
    public $widget_id;
    public $widget_args = [];
    public $loop;
    public $disp_excerpt;
    public $is_read_more_button;
    public $meta_dot;
    public $is_swipper;
    public $is_magazine;
    public $is_swipper_separated;
    public $more_label;
    public $font_size;
    public $base_onImage;
    public $base_layout;

    public function __construct($instance = false, $args = [], $the_query = false)
    {
        $this->set_post_params($instance);
        $this->set_display_params();
        $this->set_related_query_args($instance);
        $this->set_widget_args($args);
        $this->query_args_factory($the_query);
    }


    public function is_first_loop($the_query)
    {
        return $the_query->current_post == 0;
    }

    public function is_first_in_group()
    {
        $group = LEAPIN_Query_Params::$MAGAZINE_POSTS_PER_GROUP;
        $trigger = 0;
        if ($this->loop == 0) {
            return true;
        } else {
            foreach ($group as $n) {
                $trigger += $n;
                if ($this->loop == $trigger) {
                    return true;
                }
            }
        }
        return false;
    }

    public function is_last_in_group()
    {
        $group = LEAPIN_Query_Params::$MAGAZINE_POSTS_PER_GROUP;
        $trigger = -1;
        foreach ($group as $n) {
            $trigger += $n;
            if ($this->loop == $trigger) {
                return true;
            }
        }
        return false;
    }

    public function is_last_loop($the_query)
    {
        return ($the_query->current_post + 1) == $the_query->post_count;
    }

    public function is_more_posts($the_query)
    {
        $posts_per_page = $this->posts_per_page;
        return $the_query->post_count >= $posts_per_page;
    }

    public static function the_leapin_excerpt()
    {
        /**
         * this is for siteorigin
         */
        global $post;
        $old_value = apply_filters('siteorigin_panels_filter_content_enabled', true);//remember old settings
        add_filter('siteorigin_panels_filter_content_enabled', function () {
            return false;
        });
        $post_excerpt = apply_filters('the_excerpt', $post->post_excerpt);
        if (empty($post_excerpt)) {
            $post_excerpt = get_the_excerpt();
        }
        add_filter('siteorigin_panels_filter_content_enabled', function () use ($old_value) {
            return $old_value;
        });
        echo apply_filters('leapin_the_excerpt', wp_strip_all_tags($post_excerpt));
    }

    public static function get_read_more_label()
    {
        $id = get_the_ID();
        $read_more_label = leapin_get_post_meta(LEAPIN_IDs::$leapin_read_more_label_key, $id);
        $default_read_more_label = LEAPIN_Theme_Mod::get_instance()->get(LEAPIN_IDs::$leapin_widget_post_read_more_label, LEAPIN_Theme_Mod::$default_leapin_widget_post_read_more_label);
        $read_more_label = !empty($read_more_label) ? $read_more_label : $default_read_more_label;
        return $read_more_label;
    }

    private function set_post_params($instance)
    {
        $instance = is_array($instance) ? $instance : $_POST;

        $this->ajax_on_load_call = isset($instance['ajax_on_load_call']) ? $instance['ajax_on_load_call'] : 0;
        if (leapin_is_barba_call()) {
            $this->ajax_on_load_call = false;
        }
        $this->paged = isset($instance['paged']) ? $instance['paged'] : 0;
        $this->call_type = isset($instance['call_type']) ? $instance['call_type'] : false;
        $this->show_taxonomy = isset($instance['show_taxonomy']) ? $instance['show_taxonomy'] : false;
        $this->show_view_count = isset($instance['show_view_count']) ? $instance['show_view_count'] : false;
        $this->show_date = isset($instance['show_date']) ? $instance['show_date'] : false;
        $this->title = !empty($instance['title']) ? $instance['title'] : false;
        $this->layout_type = isset($instance['layout_type']) ? $instance['layout_type'] : false;
        $this->posts_per_page = isset($instance['posts_per_page']) ? $instance['posts_per_page'] : 5;
        $this->theme_color = isset($instance['theme_color']) ? $instance['theme_color'] : false;
        $this->grayscale = isset($instance['grayscale']) && $instance['grayscale'] !== 0 ? $instance['grayscale'] : 0;
        $this->post_id = isset($instance['post_id']) ? $instance['post_id'] : false;
        $this->related_post = isset($instance['related_post']) ? $instance['related_post'] : false;
        $this->call_position = isset($instance['call_position']) ? $instance['call_position'] : false;
        $this->year = isset($instance['year']) ? $instance['year'] : false;
        $this->month = isset($instance['month']) ? $instance['month'] : false;
        $this->day = isset($instance['day']) ? $instance['day'] : false;
        $this->author = isset($instance['author']) ? $instance['author'] : false;
        $this->s = isset($instance['s']) ? $instance['s'] : '';
        $this->custom_fields = isset($instance['custom_fields']) ? $instance['custom_fields'] : '';
        $this->thumbnail_size = isset($instance['thumbnail_size']) ? $instance['thumbnail_size'] : "leapin-medium";
        $this->post_ids = !empty($instance['post_ids']) ? explode(",", $instance['post_ids']) : [];
        foreach ($this->post_ids as &$item) $item = trim($item);
        $this->exclude_post_ids = !empty($instance['exclude_post_ids']) ? explode(",", $instance['exclude_post_ids']) : [];
        $this->taxonomy = isset($instance['taxonomy']) ? $instance['taxonomy'] : '';
        foreach ($this->exclude_post_ids as &$item) $item = trim($item);
        $this->term_ids_or_slugs = !empty($instance['term_ids_or_slugs']) ? explode(",", $instance['term_ids_or_slugs']) : [];
        foreach ($this->term_ids_or_slugs as &$item) $item = trim($item);
        $this->more = isset($instance['more']) ? (bool)$instance['more'] : false;
        $this->post_type = isset($instance['post_type']) ? $instance['post_type'] : false;
        $this->order_by = isset($instance['order_by']) ? $instance['order_by'] : LEAPIN_Query_Params::$default_order_by;
        $this->loop = 0;
    }


    private function set_display_params()
    {

        $layout_type = $this->layout_type;
        $this->loop = $this->paged * $this->posts_per_page;
        $this->disp_excerpt = in_array($layout_type, [LEAPIN_Query_Params::$TILE_VER2, LEAPIN_Query_Params::$SWIPER_VER3]) ? "" : " no";
        $this->is_read_more_button = in_array($layout_type, [LEAPIN_Query_Params::$SWIPER_VER1, LEAPIN_Query_Params::$SWIPER_VER3, LEAPIN_Query_Params::$SWIPER_VER4]) ? true : false;
        $this->meta_dot = in_array($layout_type, [LEAPIN_Query_Params::$SWIPER_VER1, LEAPIN_Query_Params::$SWIPER_VER3, LEAPIN_Query_Params::$SWIPER_VER4]) ? " dot" : "";
        $this->is_swipper = in_array($layout_type, [LEAPIN_Query_Params::$SWIPER_VER1, LEAPIN_Query_Params::$SWIPER_VER2, LEAPIN_Query_Params::$SWIPER_VER3, LEAPIN_Query_Params::$SWIPER_VER4, LEAPIN_Query_Params::$SWIPER_VER5, LEAPIN_Query_Params::$TILE_VER3, LEAPIN_Query_Params::$TILE_VER6]) ? true : false;
        $this->is_swipper_separated = in_array($layout_type, [LEAPIN_Query_Params::$SWIPER_VER4]) ? true : false;
        $this->is_big_thumbnail = in_array($layout_type, [LEAPIN_Query_Params::$SWIPER_VER1, LEAPIN_Query_Params::$SWIPER_VER4]) ? true : false;
        $this->is_magazine = in_array($layout_type, [LEAPIN_Query_Params::$TILE_VER3, LEAPIN_Query_Params::$SWIPER_VER5]) ? true : false;
        $this->more_label = LEAPIN_Theme_Mod::get_instance()->get(LEAPIN_IDs::$leapin_widget_post_more_label, 'More');

        // font size
        if (in_array($layout_type,
            [LEAPIN_Query_Params::$TILE_VER1
                , LEAPIN_Query_Params::$TILE_VER4
                , LEAPIN_Query_Params::$TILE_VER5
                , LEAPIN_Query_Params::$TILE_VER6
                , LEAPIN_Query_Params::$SWIPER_VER2
                , LEAPIN_Query_Params::$SIDEBAR_VER1])) {

            $this->font_size = LEAPIN_Query_Params::$FONT_XSMALL;

        } else if (in_array($layout_type, [
            LEAPIN_Query_Params::$TILE_VER2
            , LEAPIN_Query_Params::$SWIPER_VER5])) {

            $this->font_size = LEAPIN_Query_Params::$FONT_MEDIUM;

        } else if (in_array($layout_type,
            [LEAPIN_Query_Params::$SWIPER_VER1
                , LEAPIN_Query_Params::$SWIPER_VER3
                , LEAPIN_Query_Params::$SWIPER_VER4])) {

            $this->font_size = LEAPIN_Query_Params::$FONT_XLARGE;

        }

        // base layout
        if ($this->is_magazine
            || in_array($layout_type, [
                LEAPIN_Query_Params::$SIDEBAR_VER1
                , LEAPIN_Query_Params::$TILE_VER1
                , LEAPIN_Query_Params::$TILE_VER2
                , LEAPIN_Query_Params::$TILE_VER4
                , LEAPIN_Query_Params::$TILE_VER5])) {
            // grid
            $this->base_layout = LEAPIN_Query_Params::$LAYOUT_BASE_GRID;
        } elseif (in_array($layout_type, [LEAPIN_Query_Params::$TILE_VER4])) {
            // flex
            $this->base_layout = LEAPIN_Query_Params::$LAYOUT_BASE_FLEX;
        } else {
            // normal
        }

        // taxonomy meta decoration
        if (in_array($layout_type, [LEAPIN_Query_Params::$SWIPER_VER5])) {
            $this->tax_decor = " meta_bg";
        } elseif (in_array($layout_type, [LEAPIN_Query_Params::$TILE_VER1])) {
            $this->tax_decor = LEAPIN_Query_Params::$TILE1_META_DECOR;
        } else {
            $this->tax_decor = " meta_font";
        }

        if ($this->is_magazine) {
            $this->posts_per_page = (int)array_sum(LEAPIN_Query_Params::$MAGAZINE_POSTS_PER_GROUP);
        }
    }

    private function set_widget_args($args)
    {

        $this->widget_args = array_merge(['before_widget' => LEAPIN_Query_Params::$BEFORE_WIDGET,
                'after_widget' => LEAPIN_Query_Params::$AFTER_WIDGET,
                'before_title' => LEAPIN_Query_Params::$BEFORE_WIDGET_TITLE,
                'after_title' => LEAPIN_Query_Params::$AFTER_WIDGET_TITLE,
                'widget_id' => LEAPIN_Query_Params::$WIDGET_DUMMY_ID,
            ]
            , $args);
        $this->widget_id = $this->widget_args['widget_id'];
    }

    private function set_related_query_args()
    {
        if ($this->related_post && is_single()) {
            $p = get_post();
            if (is_object($p)) {
                $terms = [];
                $wp_terms = [];
                $tax = '';
                $this->post_type = $p->post_type;
                $taxonomies = get_object_taxonomies($this->post_type, 'objects');
                switch (true) {
                    case $this->taxonomy && array_key_exists($this->taxonomy, $taxonomies) && is_object($taxonomies[$this->taxonomy]):

                        // get related terms and taxonomy_name
                        $wp_terms = get_the_terms($p->ID, $this->taxonomy);
                        $tax = $this->taxonomy;

                        if (!empty($wp_terms)) break;


                    case array_key_exists('post_tag', $taxonomies)
                        && is_object($taxonomies['post_tag'])
                        && get_the_terms($p->ID, 'post_tag') != false:

                        // get tag-related terms and taxonomy_name
                        $wp_terms = get_the_terms($p->ID, 'post_tag');
                        $tax = 'post_tag';
                        if (!empty($wp_terms)) break;


                    case array_key_exists('category', $taxonomies)
                        && is_object($taxonomies['category'])
                        && get_the_terms($p->ID, 'category') != false:

                        // get category-related terms and taxonomy_name
                        $wp_terms = get_the_terms($p->ID, 'category');
                        $tax = 'category';
                        if (!empty($wp_terms)) break;


                    default:
                        // get something-related terms and taxonomy_name
                        foreach ($taxonomies as $taxonomy_slug => $taxonomy) {
                            $wp_terms = get_the_terms($p->ID, $taxonomy_slug);
                            if (!empty($terms)) {
                                $tax = $taxonomy_slug;
                                break;
                            }
                        }
                }
                // set them to query instance
                if (!empty($wp_terms)) {
                    foreach ($wp_terms as &$wp_term) {
                        $terms[] = $wp_term->term_id;
                    }
                    $this->term_ids_or_slugs = $terms;
                    $this->taxonomy = $tax;
                    $this->exclude_post_ids[] = $p->ID;
                }
            }
        }
    }

    private function query_args_factory($the_query)
    {
        if (is_object($the_query)) {
            $this->the_query = $the_query;
            return;
        }
        $this->args = [
            'p' => $this->post_id,
            'post_type' => $this->post_type,
            'post__in' => $this->post_ids,
            'post__not_in' => $this->exclude_post_ids,
            'post_status' => 'publish',
            'no_found_rows' => true,
            'cache_results' => true,
            'ignore_sticky_posts' => true,
            'posts_per_page' => $this->posts_per_page,
            'offset' => (int)$this->posts_per_page * (int)$this->paged,
            'order' => 'DESC',
            'orderby' => $this->order_by
        ];
        if ($this->year)
            $this->args['year'] = $this->year;
        if ($this->month)
            $this->args['monthnum'] = $this->month;
        if ($this->day)
            $this->args['day'] = $this->day;
        if ($this->author)
            $this->args['author'] = $this->author;
        if ($this->s)
            $this->args['s'] = $this->s;


        $this->args['tax_query'] = $this->get_tax_query();
        $this->args['meta_query'] = $this->get_meta_query();
        return apply_filters('leapin_post_widget_query_args', $this->args, $the_query, $this);
    }

    private function get_meta_query()
    {
        $meta_query = [];
        $meta_arry = [];
        if (empty($this->custom_fields))
            return $meta_query;

        $cf = explode('=', $this->custom_fields);
        if (count($cf) > 0) {
            $meta_arry['key'] = trim($cf[0]);
            $values = explode(",", $cf[1]);
            $meta_arry['value'] = [];
            foreach ($values as $val) {
                $meta_arry['value'][] = trim($val);
            }
            $meta_arry['compare'] = 'IN';
            $meta_query[] = $meta_arry;
        }

        return $meta_query;
    }

    private function get_tax_query()
    {
        $tax_query = [];
        $is_term_id = false;
        if ($this->taxonomy == "" || count($this->term_ids_or_slugs) == 0)
            return $tax_query;

        foreach ($this->term_ids_or_slugs as $terms) {
            if (is_numeric($terms)) {
                $is_term_id = true;
            }
        }

        $tax_query[] = [
            'taxonomy' => $this->taxonomy,
            'field' => $is_term_id ? 'term_id' : 'slug',
            'terms' => $this->term_ids_or_slugs
        ];

        return $tax_query;
    }

}
