<?php
    /**
     * Class to handle WP_Query params
     * 
     * @package Blog Bee
     * @since 1.0.0
     */

    namespace BBE;

    use BBE\Helpers as Helpers;
    use BBE\Customizer\Theme_Defaults as Theme_Defaults;
    use BBE\Customizer\Section\Post_Button as Post_Button;
    use BBE\Customizer\Section\Archives as Archives;
    use WP_Query;

    use function esc_attr;
    use function get_post_class;
    use function get_title;
    use function esc_url;
    use function get_permalink;
    use function get_the_excerpt;
    use function esc_html__;
    use function get_the_ID;
    use function get_categories;
    use function esc_html;
    use function has_post_thumbnail;
    use function get_post_format;

    if( ! class_exists( __NAMESPACE__ . '\\Query_Manager' ) ){
        /**
         * Query_Manager class
         */
        class Query_Manager {
            /**
             * Post ids
             * 
             * @var array
             * @since 1.0.0
             */
            private static $post_ids = [];

            /**
             * Post ids getter
             * 
             * @since 1.0.0
             */
            public static function get_post_ids() {
                return array_unique( self::$post_ids );
            }

            /**
             * Get read time number
             * 
             * @since 1.0.0
             */
            public static function get_read_time_number() {
                $read_time = 0;
                $words_to_read_per_minute = 200;
                $tagless_content = wp_strip_all_tags( get_the_content() );
                if( ! $tagless_content ) return 0;
                $word_count = str_word_count( $tagless_content );
                $read_time = apply_filters( 'blog_bee_content_read_time', ceil( $word_count / $words_to_read_per_minute ), 2 );
                return ( $read_time == 0 ) ? 1 : $read_time;
            }
            
            /**
             * Get opening article
             * 
             * @since 1.0.0
             */
            public static function get_opening_article_tag() {
                echo '<article class="bbe-article ' . esc_attr( implode( ' ', get_post_class() ) ) . '">';
            }

            /**
             * Get closing article
             * 
             * @since 1.0.0
             */
            public static function get_closing_article_tag() {
                echo '</article>';
            }

            /**
             * Get opening figure
             * 
             * @since 1.0.0
             */
            public static function get_opening_figure_tag() {
                echo '<figure class="bbe-article-figure">';
            }

            /**
             * Get closing figure
             * 
             * @since 1.0.0
             */
            public static function get_closing_figure_tag() {
                echo '</figure>';
            }

            /**
             * Get featured image
             * 
             * @since 1.0.0
             */
            public static function get_featured_image( $size = 'thumbnail', $args = [] ) {
                if( ! has_post_thumbnail() && ! isset( $args[ 'attachment_id' ] ) && ! isset( $args[ 'post_id' ] ) ) return;
                $loading = isset( $args[ 'loading' ] ) ? $args[ 'loading' ] : 'lazy';
                $default_thumb_args = [
                    'class' =>  'bbe-article-thumb',
                    'loading'   =>  $loading
                ];
                /**
                 * We don't add loading attribute when we are inside the global wp_query loop
                 * because wordpress automatically adds fetchpriority="high" and loading="lazy",
                 * so we don't have to handle it in global query.
                 * 
                 * But we do need to handle these attributes manually in our custom wp_query loops.
                 */
                if( isset( $args[ 'add_loading' ] ) && ! $args[ 'add_loading' ] ) unset( $default_thumb_args[ 'loading' ] );
                $post_format_option = isset( $args[ 'post_format' ] ) ? $args[ 'post_format' ] : true;
                if( ! empty( $args ) && is_array( $args ) ) {
                    if( isset( $args[ 'class' ] ) ) {
                        $default_thumb_args[ 'class' ] = 'bbe-article-thumb' . ' ' . $args[ 'class' ];
                        $default_thumb_args = array_merge( $args, $default_thumb_args );
                    }
                }

                $enable_link = isset( $args[ 'enable_link' ] ) ? $args[ 'enable_link' ] : true;

                if( isset( $args[ 'skip_filter' ] ) && $args[ 'skip_filter' ] ) {
                    $filtered_args = $default_thumb_args;
                } else {
                    $filtered_args = apply_filters( 'blog_bee_thumbnail_attr_filters', $default_thumb_args );
                }
                if( $enable_link ) echo '<a href="' . esc_url( get_permalink() ) . '" rel="bookmark" aria-label="' . esc_attr( get_the_title() ) . '">'; 

                    if( isset( $args[ 'attachment_id' ] ) ) {
                        $filtered_args[ 'alt' ] = esc_html( get_the_title( $args[ 'attachment_id' ] ) );
                        echo wp_get_attachment_image( $args[ 'attachment_id' ], $size, false, $filtered_args );
                    } elseif( isset( $args[ 'post_id' ] ) ) {
                        $filtered_args[ 'alt' ] = esc_html( get_the_title( $args[ 'post_id' ] ) );
                        echo get_the_post_thumbnail( $args[ 'post_id' ], $size, $filtered_args );
                    } else {
                        $filtered_args[ 'alt' ] = the_title_attribute( [ 'echo' => false ] );
                        the_post_thumbnail( $size, $filtered_args );
                    }

                if( $enable_link ) echo '</a>';
            }

            /**
             * Get title
             * 
             * @param bool $link Whether or not to add link to title
             * @since 1.0.0
             */
            public static function get_title( $link = true ) {
                if ( is_singular() && ! $link ) {
                    the_title( '<h1 class="entry-title">', '</h1>' );
                } else {
                    the_title( '<h2 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h2>' );
                }
            }

            /**
             * Get excerpt
             * 
             * @since 1.0.0
             */
            public static function get_excerpt( $length = 25 ) {
                echo '<div class="entry-excerpt"><p>' . esc_html( wp_trim_words( get_the_excerpt(), $length ) ) . '</p></div>';
            }

            /**
             * Get read more button
             * 
             * @since 1.0.0
             */
            public static function get_read_more_button() {
                Post_Button::get_instance()->render_html();
            }

            /**
             * Get comments
             * 
             * @since 1.0.0
             */
            public static function get_comments() {
                $comments_icon_attrs = [
                    'tag'   =>  'span',
                    'class' =>  'comments-icon'
                ];
                $comments_icon_attrs = array_merge( Theme_Defaults::get_theme_option( 'comment_icon_picker' ), $comments_icon_attrs );

                echo '<div class="entry-comment">';
                
                    echo Helpers::get_icon_html( $comments_icon_attrs );

                    echo '<span class="count">' . esc_html( get_comments_number() ) . '</span>';

                echo '</div>';
            }

            /**
             * Get author
             * 
             * @since 1.0.0
             */
            public static function get_author() {
                $author_icon_attrs = [
                    'tag'   =>  'span',
                    'class' =>  'user-icon'
                ];
                $author_icon_attrs = array_merge( Theme_Defaults::get_theme_option( 'author_icon_picker' ), $author_icon_attrs );
                echo '<div class="entry-author">';

                    echo Helpers::get_icon_html( $author_icon_attrs );

                    blog_bee_posted_by();

                echo '</div>';
            }

            /**
             * Get date
             * 
             * @since 1.0.0
             */
            public static function get_date() {
                $date_icon_attrs = [
                    'tag'   =>  'span',
                    'class' =>  'date-icon'
                ];
                $date_icon_attrs = array_merge( Theme_Defaults::get_theme_option( 'date_icon_picker' ), $date_icon_attrs );
                echo '<div class="entry-date">';

                    echo Helpers::get_icon_html( $date_icon_attrs );

                    blog_bee_posted_on();

                echo '</div>';
            }

            /**
             * Get read time
             * 
             * @since 1.0.0
             */
            public static function get_read_time() {
                $read_time_icon_attrs = [
                    'tag'   =>  'span',
                    'class' =>  'read-time-icon'
                ];
                $read_time_icon_attrs = array_merge( Theme_Defaults::get_theme_option( 'read_time_icon_picker' ), $read_time_icon_attrs );
                $time = self::get_read_time_number();
                $suffix = $time > 1 ? 'mins' : 'min';
                $label = $time . ' ' . $suffix;

                echo '<div class="entry-read-time">';
                
                    echo Helpers::get_icon_html( $read_time_icon_attrs );

                    echo '<span class="count">' . esc_html( $label ) . '</span>';

                echo '</div>';
            }

            /**
             * Get categories
             * 
             * @since 1.0.0
             */
            public static function get_categories() {
                $category_attributes = [
                    'taxonomy'  =>  'category',
                    'fields'    =>  'id=>name',
                    'update_term_meta_cache'    =>  false,
                    'number'    =>  2,
                    'object_ids'    =>  get_the_ID()
                ];
                $categories = get_categories( $category_attributes );
                if( empty( $categories ) && ! is_array( $categories ) ) return;
                ?>

                    <ul class="entry-categories">

                        <?php

                            foreach( $categories as $cat_id => $cat_name ) :

                                echo '<li class="cat-item cat-item-' . esc_attr( $cat_id ) . '">';

                                    echo '<a href="' . esc_url( get_category_link( $cat_id ) ) . '" class="cat-item-link">' . esc_html( $cat_name ) . '</a>';

                                echo '</li>';

                            endforeach;

                        ?>

                    </ul>

                <?php
            }

            /**
             * Get async multiselect control id
             * 
             * @since 1.0.0
             */
            public static function get_ids_only( $arr ) {
                if( empty( $arr ) || ! is_array( $arr ) ) return  [];
                return implode( ',', array_column( $arr, 'value' ) );
            }

            /**
             * Fine tune query attributes
             * 
             * @since 1.0.0
             */
            public static function fine_tune_query_attrs( $query, $override = false ): WP_Query {
                $query_attrs = [
                    'post_type'   =>  'post',
                    'post_status'   =>  'publish',
                    'ignore_sticky_posts'   =>  true,
                    'fields'    =>  'ids',
                    'no_found_rows' =>  true,
                    'update_post_meta_cache'    =>  false,
                    'update_post_term_cache'    =>  false,
                ];

                if( $override ){

                    // Order By
                    if( isset( $query[ 'orderby' ] ) ) {
                        $exploded_orderby = explode( '-', $query[ 'orderby' ] );
                        $query_attrs[ 'orderby' ] = $exploded_orderby[ 0 ];
                        $query_attrs[ 'order' ] = $exploded_orderby[ 1 ];
                        unset( $query[ 'orderby' ] );
                    }

                    // Query parameters
                    if( isset( $query[ 'post_source' ] ) ) {
                        $post_source = $query[ 'post_source' ];
                        switch( $post_source ){
                            case 'categories':
                                    if( isset( $query[ 'cat' ] ) ) {
                                        $category = $query[ 'cat' ];
                                        $query_attrs[ 'cat' ] = self::get_ids_only( $category );
                                    }
                                break;
                            case 'post_tags':
                                    if( isset( $query[ 'tag__in' ] ) ) {
                                        $tag__in = $query[ 'tag__in' ];
                                        if( $tag__in ) $query_attrs[ 'tag__in' ] = array_column( $tag__in, 'value' );
                                    }
                                break;
                            case 'authors':
                                    if( isset( $query[ 'author' ] ) ) {
                                        $author = $query[ 'author' ];
                                        if( $author ) $query_attrs[ 'author' ] = self::get_ids_only( $author );
                                    }
                                break;
                            case 'manual':
                                    if( isset( $query[ 'post__in' ] ) ) {
                                        $post__in = $query[ 'post__in' ];
                                        if( $post__in ) $query_attrs[ 'post__in' ] = array_column( $post__in, 'value' );
                                    }
                                break;
                            case 'featured':
                                    $sticky = get_option( 'sticky_posts' );
                                    if( $sticky ) $query_attrs[ 'post__in' ] = $sticky;
                                break;
                            default:
                                    // for latest do nothing
                                break;
                        }
                    }

                    // Hide if no featured image exists
                    if( isset( $query[ 'hide_featured' ] ) && $query[ 'hide_featured' ] ) {
                        $query_attrs[ 'meta_query' ] = [
                            [
                                'key'   =>  '_thumbnail_id',
                                'compare'   =>  'EXISTS'
                            ]
                        ];
                    }
                    unset( $query[ 'post_source' ] );
                    unset( $query[ 'cat' ] );
                    unset( $query[ 'tag__in' ] );
                    unset( $query[ 'author' ] );
                    unset( $query[ 'post__in' ] );
                    unset( $query[ 'hide_featured' ] );
                    $query_attrs = array_merge( $query_attrs, $query );
                } else {
                    // Posts per page
                    if( isset( $query[ 'posts_per_page' ] ) ) {
                        $query_attrs[ 'posts_per_page' ] = absint( Theme_Defaults::get_theme_option( $query[ 'posts_per_page' ] ) );
                        unset( $query[ 'posts_per_page' ] );
                    }

                    // Offset
                    if( isset( $query[ 'offset' ] ) ) {
                        $query_attrs[ 'offset' ] = absint( Theme_Defaults::get_theme_option( $query[ 'offset' ] ) );
                        unset( $query[ 'offset' ] );
                    }

                    // Order By
                    if( isset( $query[ 'orderby' ] ) ) {
                        $exploded_orderby = explode( '-', Theme_Defaults::get_theme_option( $query[ 'orderby' ] ) );
                        $query_attrs[ 'orderby' ] = $exploded_orderby[ 0 ];
                        $query_attrs[ 'order' ] = $exploded_orderby[ 1 ];
                        unset( $query[ 'orderby' ] );
                    }

                    // Query parameters
                    if( isset( $query[ 'post_source' ] ) ){
                        $post_source = Theme_Defaults::get_theme_option( $query[ 'post_source' ] );
                        switch( $post_source ){
                            case 'categories':
                                    if( isset( $query[ 'cat' ] ) ) {
                                        $category = Theme_Defaults::get_theme_option( $query[ 'cat' ] );
                                        if( $category ) $query_attrs[ 'cat' ] = self::get_ids_only( $category );
                                    }
                                break;
                            case 'post_tags':
                                    if( isset( $query[ 'tag__in' ] ) ) {
                                        $tag__in = Theme_Defaults::get_theme_option( $query[ 'tag__in' ] );
                                        if( $tag__in ) $query_attrs[ 'tag__in' ] = array_column( $tag__in, 'value' );
                                    }
                                break;
                            case 'authors':
                                    if( isset( $query[ 'author' ] ) ) {
                                        $author = Theme_Defaults::get_theme_option( $query[ 'author' ] );
                                        if( $author ) $query_attrs[ 'author' ] = self::get_ids_only( $author );
                                    }
                                break;
                            case 'manual':
                                    if( isset( $query[ 'post__in' ] ) ) {
                                        $post__in = Theme_Defaults::get_theme_option( $query[ 'post__in' ] );
                                        if( $post__in ) $query_attrs[ 'post__in' ] = array_column( $post__in, 'value' );
                                    }
                                break;
                            case 'featured':
                                    $sticky = get_option( 'sticky_posts' );
                                    if( $sticky ) $query_attrs[ 'post__in' ] = $sticky;
                                break;
                            default:
                                    // for latest do nothing
                                break;
                        }
                        unset( $query[ 'post_source' ] );
                        unset( $query[ 'cat' ] );
                        unset( $query[ 'tag__in' ] );
                        unset( $query[ 'author' ] );
                        unset( $query[ 'post__in' ] );
                    }

                    // Hide if no featured image exists
                    if( isset( $query[ 'hide_featured' ] ) && Theme_Defaults::get_theme_option( $query[ 'hide_featured' ] ) ) {
                        $query_attrs[ 'meta_query' ] = [
                            [
                                'key'   =>  '_thumbnail_id',
                                'compare'   =>  'EXISTS'
                            ]
                        ];
                        unset( $query[ 'hide_featureds' ] );
                    }

                    $query_attrs = array_merge( $query_attrs, $query );
                }
                $filtered_query = apply_filters( 'blog_bee_query_attrs_filter', $query_attrs );
                $query_instance = new WP_Query( $filtered_query );
                if( $query_instance->have_posts() ) {
                    self::$post_ids = array_merge( self::$post_ids, $query_instance->posts );
                }
                return $query_instance;
            }

            /**
             * Get archive opener
             * 
             * @since 1.0.0
             */
            public static function get_archive_opener() {
                $archives = Archives::get_instance();
                $layout = $archives->get_layout();
                $overlay_option = $archives->get_overlay();
                $columns = $archives->get_column();

                $block_class[] = 'blog-bee-main-wrap';
                $block_class[] = 'layout--' . $layout;
                $block_class[] = 'ratio--' . Theme_Defaults::get_theme_option( 'archives_image_ratio' );
                $block_class[] = 'card--' . Theme_Defaults::get_theme_option( 'archives_container' );
                $block_class[] = 'align--' . Theme_Defaults::get_theme_option( 'archives_alignment' );
                if( $layout === 'grid' ) {
                    $masonry = $archives->get_masonry();
                    if( $masonry ) $block_class[] = 'masonry--on';
                    if( isset( $columns[ 'desktop' ] ) ) $block_class[] = 'column--' . Helpers::convert_number_to_word( $columns[ 'desktop' ] );
                    if( isset( $columns[ 'tablet' ] ) ) $block_class[] = 'tab-column--' . Helpers::convert_number_to_word( $columns[ 'tablet' ] );
                    if( isset( $columns[ 'mobile' ] ) ) $block_class[] = 'mobile-column--' . Helpers::convert_number_to_word( $columns[ 'mobile' ] );
                } else {
                    $block_class[] = 'column--' . Helpers::convert_number_to_word( $columns );
                }
                if( ! $overlay_option ) {
                    $image_alter = $archives->get_image_alter();

                    if( $image_alter ) {
                        $block_class[] = 'alter--enabled';
                    } else {
                        $image_position = Theme_Defaults::get_theme_option( 'archives_image_position' );
                        $block_class[] = 'position--' . $image_position;
                    }
                } else {
                    $block_class[] = 'overlay--enabled';
                }
                echo '<div class="' . esc_attr( implode( ' ', $block_class ) ) . '">';
                    echo '<div class="bbe-container">';
                        echo '<div class="row">';
            }

            /**
             * Get archive closer
             * 
             * @since 1.0.0
             */
            public static function get_archive_closer() {
                        echo '</div>';
                    echo '</div>';
                echo '</div><!-- .blog-bee-main-wrap -->';
            }

            /**
             * Get query attributes for wp_query or get_posts
             * 
             * @param array $query The query parameters
             * @see WP_Query
             * @since 1.0.0
             */
            private static function get_query_attrs( $query = [] ): array {
                $query_attrs = [
                    'post_type'   =>  'post',
                    'post_status'   =>  'publish',
                    'ignore_sticky_posts'   =>  true,
                    'fields'    =>  'ids',
                    'no_found_rows' =>  true,
                    'update_post_meta_cache'    =>  false,
                    'update_post_term_cache'    =>  false,
                    'posts_per_page'    =>  1,
                    'orderby'   =>  'rand'
                ];
                return array_merge( $query_attrs, $query );
            }

            /**
             * Get random post Id
             * 
             * @since 1.0.0
             */
            public static function get_random_post_id(): int {
                $query_attrs = self::get_query_attrs();
                $posts = get_posts( $query_attrs );

                return ! empty( $posts ) ? $posts[ 0 ] : 0;
            }

            /**
             * Get random page Id
             * 
             * @since 1.0.0
             */
            public static function get_random_page_id(): int {
                $query_args = [ 
                    'post_type' =>  'page',
                    'meta_query'    =>  [
                        [
                            'key'     => '_wp_page_template',
                            'value'   => 'web-stories.php', // the template file to exclude
                            'compare' => '!=',
                        ]
                    ]
                ];
                
                $query_attrs = self::get_query_attrs( $query_args );
                $pages = get_posts( $query_attrs );

                return ! empty( $pages ) ? $pages[ 0 ] : 0;
            }

            /**
             * Add post format icon 
             * 
             * @since 1.0.0
             */
            public static function get_post_format_icon() {
                $post_format = get_post_format();
                switch( $post_format ) {
                    case 'audio':
                            $icon = Theme_Defaults::get_theme_option( 'audio_icon_picker' );
                        break;
                    case 'gallery':
                            $icon = Theme_Defaults::get_theme_option( 'gallery_icon_picker' );
                        break;
                    case 'image':
                            $icon = Theme_Defaults::get_theme_option( 'image_icon_picker' );
                        break;
                    case 'quote':
                            $icon = Theme_Defaults::get_theme_option( 'quote_icon_picker' );
                        break;
                    case 'video':
                            $icon = Theme_Defaults::get_theme_option( 'video_icon_picker' );
                        break;
                    default:
                            $icon = Theme_Defaults::get_theme_option( 'standard_icon_picker' );
                        break;
                }
                $icon[ 'tag' ] = 'span';
                $icon[ 'class' ] = 'post-format-icon';
                echo Helpers::get_icon_html( $icon );
            }
        }
        new Query_Manager;
    }