<?php
namespace CSSIgniter\Ignition\Elementor;

class Widgets_Helper {

	/**
	 * Builds the query arguments.
	 *
	 * @since 1.0.0
	 */
	public static function get_query_args( $control_id, $settings ) {
		$defaults = array(
			$control_id . '_post_type' => 'post',
			$control_id . '_posts_ids' => array(),
			'orderby'                  => '',
			'order'                    => 'desc',
			'posts_per_page'           => 3,
		);

		$settings = wp_parse_args( $settings, $defaults );

		$post_type = $settings[ $control_id . '_post_type' ];

		$query_args = array(
			'orderby'             => $settings['orderby'],
			'order'               => $settings['order'],
			'ignore_sticky_posts' => 1,
			'post_status'         => 'publish',
		);

		if ( 'by_id' === $post_type ) {
			$query_args['post_type'] = array_keys( self::element_post_types() );
			$query_args['post__in']  = $settings[ $control_id . '_posts_ids' ];

			if ( empty( $query_args['post__in'] ) ) {
				// If no selection - return an empty query
				$query_args['post__in'] = array( 0 );
			}
		} else {
			$query_args['post_type']      = $post_type;
			$query_args['posts_per_page'] = $settings['posts_per_page'];

			if ( intval( $settings['offset'] ) > 0 ) {
				$query_args['offset'] = $settings['offset'];
			}

			$taxonomies = get_object_taxonomies( $post_type, 'objects' );

			$tax_query_args = array();
			// These will be joined conditionally to give the correct tax query.
			$selected_tax_args           = array();
			$product_visibility_tax_args = array();

			foreach ( $taxonomies as $object ) {
				$setting_key = $control_id . '_' . $object->name . '_ids';

				if ( ! empty( $settings[ $setting_key ] ) ) {
					$selected_tax_args[] = array(
						'taxonomy' => $object->name,
						'field'    => 'term_id',
						'terms'    => $settings[ $setting_key ],
					);
				}
			}

			if ( count( $selected_tax_args ) > 1 ) {
				$selected_tax_args['relation'] = 'OR';
			}

			if ( 'product' === $post_type && taxonomy_exists( 'product_visibility' ) ) {
				$product_visibility_tax_args[] = array(
					'taxonomy' => 'product_visibility',
					'field'    => 'slug',
					'terms'    => array( 'exclude-from-catalog' ),
					'operator' => 'NOT IN',
				);
			}

			if ( count( $selected_tax_args ) >= 1 && count( $product_visibility_tax_args ) >= 1 ) {
				$tax_query_args = array(
					'relation' => 'AND',
					$selected_tax_args,
					$product_visibility_tax_args,
				);
			} elseif ( count( $selected_tax_args ) >= 1 ) {
				$tax_query_args = $selected_tax_args;
			} elseif ( count( $product_visibility_tax_args ) >= 1 ) {
				$tax_query_args = $product_visibility_tax_args;
			}

			if ( count( $tax_query_args ) >= 1 ) {
				$query_args['tax_query'] = $tax_query_args;
			}
		}

		if ( ! empty( $settings[ $control_id . '_authors' ] ) ) {
			$query_args['author__in'] = $settings[ $control_id . '_authors' ];
		}

		if ( 'by_id' !== $post_type ) {
			$post__not_in = array();
			foreach ( self::element_post_types() as $name => $label ) {
				if ( ! empty( $settings[ 'post__not_in_' . $name ] ) ) {
					$post__not_in               = array_merge( $post__not_in, $settings[ 'post__not_in_' . $name ] );
					$query_args['post__not_in'] = $post__not_in;
				}
			}

			$post__in = array();
			foreach ( self::element_post_types() as $name => $label ) {
				if ( ! empty( $settings[ 'post__in_' . $name ] ) ) {
					$post__in               = array_merge( $post__in, $settings[ 'post__in_' . $name ] );
					$query_args['post__in'] = $post__in;
				}
			}

			if ( 'ignition-event' === $post_type ) {
				// Provide context to the query.
				$query_args['ignition_event_query'] = $settings[ $control_id . '_ignition_event_query_type' ];
			}
		}

		if ( 'yes' === $settings['pagination'] ) {
			$query_args['paged'] = self::get_page_var();
		}

		return $query_args;
	}

	/**
	 * Get All Post Types
	 *
	 * @return array
	 */
	public static function element_post_types() {
		$return = 'objects';

		$cpts = get_post_types( array(
			'public'            => true,
			'show_in_nav_menus' => true,
		), $return );

		$excluded_cpts = apply_filters( 'ignition_elementor_widgets_widgets_helper_excluded_cpts', array(
			'elementor_library',
			'attachment',
			'ignition-gsection',
		) );

		foreach ( $excluded_cpts as $excluded_cpt ) {
			unset( $cpts[ $excluded_cpt ] );
		}

		$post_types = array_merge( $cpts );

		$post_types = apply_filters( 'ignition_elementor_widgets_widgets_helper_post_types_dropdown', $post_types, __CLASS__, $excluded_cpts, $return );

		$types = wp_list_pluck( $post_types, 'label', 'name' );

		return $types;
	}

	/**
	 * Get all types of post.
	 *
	 * @return array
	 */
	public static function get_all_post_type_items( $post_type = false ) {
		$post_type  = $post_type ? $post_type : array_keys( self::element_post_types() );
		$posts_args = array(
			'post_type'      => $post_type,
			'post_status'    => 'publish',
			'posts_per_page' => -1,
		);

		$posts = new \WP_Query( $posts_args );

		$post_list = wp_list_pluck( $posts->posts, 'post_title', 'ID' );

		return $post_list;
	}

	/**
	 * Post Orderby Options
	 *
	 * @return array
	 */
	public static function get_post_orderby_options() {
		$orderby = array(
			''              => __( 'Default', 'ignition-elementor-widgets' ),
			'ID'            => __( 'Post ID', 'ignition-elementor-widgets' ),
			'author'        => __( 'Post Author', 'ignition-elementor-widgets' ),
			'title'         => __( 'Title', 'ignition-elementor-widgets' ),
			'date'          => __( 'Date', 'ignition-elementor-widgets' ),
			'modified'      => __( 'Last Modified Date', 'ignition-elementor-widgets' ),
			'parent'        => __( 'Parent Id', 'ignition-elementor-widgets' ),
			'rand'          => __( 'Random', 'ignition-elementor-widgets' ),
			'comment_count' => __( 'Comment Count', 'ignition-elementor-widgets' ),
			'menu_order'    => __( 'Menu Order', 'ignition-elementor-widgets' ),
		);

		return apply_filters( 'ignition_elementor_widgets_widgets_helper_orderby_options', $orderby );
	}

	/**
	 * Returns the appropriate page(d) query variable to use in custom loops (needed for pagination).
	 *
	 * @uses get_query_var()
	 *
	 * @param int $default_return The default page number to return, if no query vars are set.
	 * @return int The appropriate paged value if found, else 0.
	 */
	public static function get_page_var( $default_return = 0 ) {
		$paged = get_query_var( 'paged', false );
		$page  = get_query_var( 'page', false );

		if ( false === $paged && false === $page ) {
			return $default_return;
		}

		return max( $paged, $page );
	}

	public static function get_template_part( $slug, $name = '', $args = array() ) {
		$templates = array();
		$name      = (string) $name;
		if ( '' !== $name ) {
			$templates[] = "{$slug}-{$name}.php";
		}

		$templates[] = "{$slug}.php";

		$located = self::locate_template( $templates, $args );

		if ( ! empty( $located ) ) {
			include $located;
		}
	}

	public static function locate_template( $templates, $args ) {
		$plugin_path = plugin_dir_path( __DIR__ );

		// The templates path in the plugin, i.e. /template-parts
		$default_path = untrailingslashit( $plugin_path ) . '/template-parts';

		// The templates path in the theme.
		$theme_path = apply_filters( 'ignition_elementor_widgets_locate_template_theme_path', 'template-parts/ignition-elementor-widgets' );

		$theme_templates = array();
		foreach ( $templates as $template ) {
			$theme_templates[] = trailingslashit( $theme_path ) . $template;
		}

		// Try to find a theme-overridden template.
		$located = locate_template( $theme_templates, false );
		$located = apply_filters( 'ignition_elementor_widgets_locate_template', $located, $theme_templates, $templates, $theme_path, $default_path, $args );

		if ( empty( $located ) ) {
			// Nope. Try the plugin templates instead.
			foreach ( $templates as $template ) {
				if ( file_exists( trailingslashit( $default_path ) . $template ) ) {
					$located = trailingslashit( $default_path ) . $template;
					break;
				}
			}
		}

		return $located;
	}

}
