<?php

/**
 * Single Episode.
 *
 * @link    https://aiopodcasting.com
 * @since   1.0.0
 *
 * @package AiO_Podcast_Studio
 */

// Exit if accessed directly
if ( ! defined( 'WPINC' ) ) {
	die;
}

/**
 * AIOPOD_Public_Episode class.
 *
 * @since 1.0.0
 */
class AIOPOD_Public_Episode {
	
	/**
	 * The default shortcode attribute values.
	 *
	 * @since  1.0.0
	 * @access private
	 * @var    array
	 */
	private $defaults = array();

	/**
	 * Get things started.
	 *
	 * @since 1.0.0
	 */
	public function __construct() {
		// Register shortcodes
		add_shortcode( 'aiopod_episode', array( $this, 'render_shortcode_episode' ) );
	}
	
	/**
	 * Render the shortcode [aiopod_episode].
	 *
	 * @since  1.0.0
	 * @param  array  $atts An associative array of attributes.
	 * @return string       Shortcode output.
	 */
	public function render_shortcode_episode( $atts ) {
		$attributes = shortcode_atts( $this->get_defaults(), $atts, 'aiopod_episode' );
		$attributes['shortcode'] = 'aiopod_episode';	

		$post_id = (int) $attributes['id'];

		if ( empty( $post_id ) ) {
			$is_singular   = is_singular( 'aiopod_episodes' );
			$in_the_loop   = apply_filters( 'aiopod_the_content_in_the_loop', in_the_loop() );
			$is_main_query = apply_filters( 'aiopod_the_content_is_main_query', is_main_query() );

			// Define the query
			$args = array(				
				'post_type'              => 'aiopod_episodes',			
				'post_status'            => 'publish',
				'posts_per_page'         => 1,
				'fields'                 => 'ids',
				'no_found_rows'          => true,
				'update_post_term_cache' => false,
				'update_post_meta_cache' => false
			);

			if ( ! empty( $attributes['podcast'] ) ) { // Podcast ID	
				$args['post_parent'] = (int) $attributes['podcast'];	
				$is_singular = false;
			}

			// Taxonomy Parameters
			$tax_queries = array();		

			if ( ! empty( $attributes['tags'] ) ) { // Tags
				$tags = array_map( 'intval', ( is_array( $attributes['tags'] ) ? $attributes['tags'] : explode( ',', $attributes['tags'] ) ) );
				$tags = array_filter( $tags );

				if ( ! empty( $tags ) ) {
					$tax_queries[] = array(
						'taxonomy'         => 'aiopod_tags',
						'field'            => 'term_id',
						'terms'            => $tags,
						'include_children' => false
					);

					$is_singular = false;
				}
			}

			if ( ! empty( $attributes['participants'] ) ) { // Participants
				$participants = array_map( 'intval', ( is_array( $attributes['participants'] ) ? $attributes['participants'] : explode( ',', $attributes['participants'] ) ) );
				$participants = array_filter( $participants );

				if ( ! empty( $participants ) ) {
					$tax_queries[] = array(
						'taxonomy'         => 'aiopod_participants',
						'field'            => 'term_id',
						'terms'            => $participants,
						'include_children' => false
					);

					$is_singular = false;
				}
			}
			
			$count_tax_queries = count( $tax_queries );
			if ( $count_tax_queries ) {
				$args['tax_query'] = ( $count_tax_queries > 1 ) ? array_merge( array( 'relation' => 'AND' ), $tax_queries ) : $tax_queries;
			}

			// Custom Field (post meta) Parameters
			$meta_queries = array();

			if ( ! empty( $attributes['type'] ) ) { // Episode Type
				$allowed_types = aiopod_get_episode_types();
				$allowed_types = array_keys( $allowed_types );

				$types = is_array( $attributes['type'] ) ? $attributes['type'] : explode( ',', $attributes['type'] );
				$types = array_map( 'sanitize_key', array_map( 'trim', $types ) );
				$types = array_intersect( $types, $allowed_types );

				if ( ! empty( $types ) && count( $types ) !== count( $allowed_types ) ) {
					$meta_queries[] = array(
						'key'     => 'episode_type',
						'value'   => $types,
						'compare' => 'IN'
					);

					$is_singular = false;
				}
			}

			if ( ! empty( $attributes['featured'] ) ) { // Featured			
				$meta_queries[] = array(
					'key'     => 'is_featured',
					'value'   => 1,
					'compare' => '='
				);	
				
				$is_singular = false;
			}

			if ( ! empty( $attributes['season'] ) ) { // Season Number
				$season = absint( $attributes['season'] );
				
				if ( $season > 0 ) {
					$meta_queries[] = array(
						'key'     => 'season_number',
						'value'   => $season,
						'compare' => '=',
						'type'    => 'NUMERIC'
					);

					$is_singular = false;
				}
			}
			
			$count_meta_queries = count( $meta_queries );
			if ( $count_meta_queries ) {
				$args['meta_query'] = ( $count_meta_queries > 1 ) ? array_merge( array( 'relation' => 'AND' ), $meta_queries ) : $meta_queries;
			}
			
			// Order & Orderby Parameters
			$orderby = sanitize_text_field( $attributes['orderby'] );
			$order   = sanitize_text_field( $attributes['order'] );			

			switch ( $orderby ) {
				case 'popularity':
					$args['orderby']  = 'meta_value_num';
					$args['meta_key'] = 'total_downloads_plays';
					$args['order']    = $order;
					break;

				case 'downloads':
					$args['orderby']  = 'meta_value_num';
					$args['meta_key'] = 'total_downloads';
					$args['order']    = $order;
					break;

				case 'plays':
					$args['orderby']  = 'meta_value_num';
					$args['meta_key'] = 'total_plays';
					$args['order']    = $order;
					break;

				case 'rand':
					$seed = aiopod_get_orderby_rand_seed();
					$args['orderby']  = 'RAND(' . $seed . ')';
					break;

				default:
					$args['orderby'] = $orderby;
					$args['order']   = $order;
			}

			if ( 'date' !== $orderby || 'desc' !== $order ) { // If overriding the default order
				$is_singular = false;
			}

			if ( $is_singular && $in_the_loop && $is_main_query ) {
				global $wp_the_query;
				$post_id = (int) $wp_the_query->get_queried_object_id();
			} else {			
				$args = apply_filters( 'aiopod_query_args', $args, $attributes );
				$aiopod_query = new WP_Query( $args );
				
				if ( $aiopod_query->have_posts() ) {
					$posts   = $aiopod_query->posts;
					$post_id = (int) $posts[0];
				}
			}
		}
		
		// Validate the post ID
		if ( empty( $post_id ) ) {
			return '';
		}

		// Check post status and permissions
		$post_status = get_post_status( $post_id );
		if ( 'publish' !== $post_status ) {
			return '';	
		}

		// Check for password protection
		if ( post_password_required( $post_id ) ) {
			return '';
		}

		// Check user permissions
		if ( ! aiopod_current_user_can( 'view_aiopod_podcast', $post_id ) ) {
			return aiopod_get_access_denied_message( $post_id, 'episode' );
		}
			
		// Enqueue dependencies
		wp_enqueue_style( AIOPOD_PLUGIN_SLUG . '-public' );
		wp_enqueue_script( AIOPOD_PLUGIN_SLUG . '-public' );

		// Generate the player card
		$post = get_post( $post_id );

		ob_start();
		echo '<div class="aiopod">';
		aiopod_the_player_card( $post, $attributes );
		echo '</div>';
		$content = ob_get_clean();

		return $content;
	}

	/**
	 * Filter the post content.
	 *
	 * @since  1.0.0
	 * @param  string $content Content of the current post.
	 * @return string $content Modified Content.
	 */
	public function the_content( $content ) {
		$in_the_loop   = apply_filters( 'aiopod_the_content_in_the_loop', in_the_loop() );
		$is_main_query = apply_filters( 'aiopod_the_content_is_main_query', is_main_query() );

		if ( is_singular( 'aiopod_episodes' ) && $in_the_loop && $is_main_query ) {		
			global $wp_the_query, $post;
			$post_id = $post->ID;

			if ( $wp_the_query->get_queried_object_id() !== $post_id ) {
				return $content;
			}

			if ( post_password_required( $post_id ) ) {
				return $content;
			}

			if ( ! aiopod_current_user_can( 'view_aiopod_podcast', $post_id ) ) {
				return aiopod_get_access_denied_message( $post_id, 'episode', $content );
			}
			
			// Vars
			$episode_settings = aiopod_get_option( 'aiopod_episode_settings' );		
			
			$attributes = array_merge( 
				$this->get_defaults(), 
				array(						
					'show_related_episodes'  => $episode_settings['show_related_episodes'],
					'related_episodes_title' => $episode_settings['related_episodes_title'],
					'show_participants'      => $episode_settings['show_participants'],
					'participants_title'     => $episode_settings['participants_title']
				) 
			);			
			
			// Enqueue dependencies
			wp_enqueue_style( AIOPOD_PLUGIN_SLUG . '-public' );
			wp_enqueue_script( AIOPOD_PLUGIN_SLUG . '-public' );
			
			// Process output
			ob_start();
			include apply_filters( 'aiopod_load_template', AIOPOD_PLUGIN_DIR . 'public/templates/single-episode.php' );
			$content = ob_get_clean();			
		}
		
		return $content;	
	}

	/**
	 * Filters timestamps in the episode description and wraps them with links.
	 *
	 * @since  1.0.0
	 * @access private
	 * @param  string  $content The original episode description.
	 * @return string           The modified description with timestamps wrapped in links.
	 */
	private function wrap_timestamps_with_links( $content ) {
		$player_settings = aiopod_get_option( 'aiopod_player_settings' );

		if ( isset( $player_settings['controls']['chapters'] ) ) {
			$pattern = '/(\d{1,2}:)?\d{1,2}:\d{2}/';

			// Replace timestamps with anchor tags
			$content = preg_replace_callback( $pattern, function( $matches ) {
				$timestamp = $matches[0];

				return sprintf(
					'<a href="javascript:void(0);" class="aiopod-chapter-timestamp" data-time="%s">%s</a>',
					absint( aiopod_convert_time_to_seconds( $timestamp ) ),
					esc_html( $timestamp )
				);
			}, $content );
		}

		return $content;
	}

	/**
     * Filters whether the current episode post is open for comments.
     *
     * @since  1.0.0
     * @param  bool  $open    Whether the current post is open for comments.
     * @param  int   $post_id The post ID.
	 * @return bool  $open    True if the comments are open, false if not.
     */
	public function comments_open( $open, $post_id ) {
		if ( $post_id > 0 ) {
			$post_type = get_post_type( $post_id );
				
			if ( 'aiopod_episodes' === $post_type ) {
				$episode_settings = aiopod_get_option( 'aiopod_episode_settings' );

				// Forcefully enable comments on all the episode pages
				if ( 'open' === $episode_settings['comments'] ) {
					$open = true;
				}

				// Forcefully disable comments on all the episode pages
				if ( 'closed' === $episode_settings['comments'] ) {
					$open = false;
				}
			}
		}

		return $open;
	}

	/**
	 * Get the default shortcode attribute values.
	 *
	 * @since  1.0.0
	 * @return array An associative array of attributes.
	 */
	public function get_defaults() {	
		if ( empty( $this->defaults ) ) {	
			$player_settings = aiopod_get_option( 'aiopod_player_settings' ); 

			$fields = aiopod_get_shortcode_fields();

			foreach ( $fields['episodes']['sections']['player']['fields'] as $field ) {
				$this->defaults[ $field['name'] ] = $field['value'];
			}
		
			$this->defaults['source']         = 'episode';
			$this->defaults['id']             = '';	
			$this->defaults['podcast']        = '';	
			$this->defaults['tags']           = '';	
			$this->defaults['participants']   = '';
			$this->defaults['type']           = '';
			$this->defaults['featured']       = 0;
			$this->defaults['season']         = '';	
			$this->defaults['orderby']        = 'date';	
			$this->defaults['order']          = 'desc';			
			$this->defaults['player_hotkeys'] = $player_settings['hotkeys'];
		}
		
		return $this->defaults;
	}
	
}