<?php

/**
 * Helper functions for rendering HTML output across the plugin.
 *
 * @link    https://aiopodcasting.com
 * @since   1.0.0
 *
 * @package AiO_Podcast_Studio
 */

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

/**
 * Displays or retrieves the HTML dropdown list of terms.
 *
 * @since  1.0.0
 * @param  array  $args Array of arguments to generate a terms drop-down element.
 * @return string       HTML dropdown list of terms.
 */
function aiopod_dropdown_terms( $args ) {
	$multiple = isset( $args['multiple'] ) ? (bool) $args['multiple'] : true;
	$echo     = isset( $args['echo'] ) ? (bool) $args['echo'] : true;	

	if ( ! $multiple ) {
		if ( $echo ) {
			wp_dropdown_categories( $args );
			return false;
		} else {
			return wp_dropdown_categories( $args );
		}
	} 

	$input_placeholder     = isset( $args['show_option_none'] ) ? $args['show_option_none'] : '';
	$stay_open             = isset( $args['stay_open'] ) ? $args['stay_open'] : 0;
	$show_search_threshold = isset( $args['show_search_threshold'] ) ? $args['show_search_threshold'] : 20;
	
	unset( $args['show_option_none'], $args['option_none_value'] );

	$args['walker'] = new AIOPOD_Walker_Terms_MultiSelect();
	$args['echo']   = false;

	$dropdown_list = wp_dropdown_categories( $args );
	$dropdown_list = preg_replace( '/<select(.*?)>(.*?)<\/select>/s', '<div class="aiopod-dropdown__items">$2</div>', $dropdown_list );

	// Output
	$html  = '<div class="aiopod-dropdown">';
	$html .= sprintf( '<input type="text" class="aiopod-dropdown__input aiopod-form-control" placeholder="%s" readonly />', esc_attr( $input_placeholder )	);	
	$html .= '<div class="aiopod-dropdown__list" style="display: none;">';

	$html .= sprintf( '<div class="aiopod-dropdown__search" hidden data-stay_open="%d" data-show_search_threshold="%d">', $stay_open, $show_search_threshold );
	$html .= sprintf( '<input type="text" placeholder="%s..." />', esc_html__( 'Search', 'aio-podcast-studio' ) );
	$html .= '<button type="button" hidden>';
	$html .= '<svg xmlns="http://www.w3.org/2000/svg" fill="none" width="16" height="16" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">';
	$html .= '<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path>';
	$html .= '</svg>';
	$html .= '</button>';
	$html .= '</div>';

	$html .= $dropdown_list;

	$html .= '<div class="aiopod-dropdown__no-items" hidden>';
	$html .= sprintf( '<label class="aiopod-text-muted aiopod-text-small">%s</label>', esc_html__( 'No items found', 'aio-podcast-studio' ) );
	$html .= '</div>';

	$html .= '</div>';
	$html .= '</div>';

	if ( $echo ) {
		echo $html;
	} else {
		return $html;
	}
}

/**
 * Outputs a list of categories.
 *
 * @since  1.0.0
 * @param  array       $attributes Array of attributes to control the output.
 * @return string|null             The HTML string if 'echo' is false. Otherwise, echoes the output.
 */
function aiopod_the_categories( $attributes = array() ) {
	$echo = isset( $attributes['echo'] ) ? (bool) $attributes['echo'] : true;	

	$categories = AIOPOD_Public_Categories::get_instance();
	$html = $categories->render_shortcode_categories( $attributes );

	if ( $echo ) {
		echo $html;
	} else {
		return $html;
	}
}

/**
 * Outputs a category card layout with header, image, and metadata.
 *
 * @since 1.0.0
 * @param WP_Term $term       WP term object.
 * @param array   $attributes Array of attributes to control the output.
 */
function aiopod_the_category_card( $term, $attributes = array() ) {
	if ( empty( $term ) ) {
		return;
	}

	include apply_filters( 'aiopod_load_template', AIOPOD_PLUGIN_DIR . 'public/templates/categories/category-card.php', $attributes );
}

/**
 * Outputs an episode card layout with header, image, and metadata.
 *
 * @since 1.0.0
 * @param WP_Post $post       WP post object.
 * @param array   $attributes Array of attributes to control the output.
 */
function aiopod_the_episode_card( $post, $attributes = array() ) {
	if ( empty( $post ) ) {
		return;
	}

	include apply_filters( 'aiopod_load_template', AIOPOD_PLUGIN_DIR . 'public/templates/episodes/episode-card.php', $attributes );
}

/**
 * Outputs the <template> used to update the player when this episode is selected.
 *
 * @since 1.0.0
 * @param WP_Post $post       WP post object.
 * @param array   $attributes Array of attributes to control the output.
 */
function aiopod_the_episode_template( $post, $attributes = array() ) {
	if ( empty( $post ) ) {
		return;
	}

	include apply_filters( 'aiopod_load_template', AIOPOD_PLUGIN_DIR . 'public/templates/episodes/episode-template.php', $attributes );
}

/**
 * Outputs a list of episodes.
 *
 * @since  1.0.0
 * @param  array       $attributes Array of attributes to control the output.
 * @return string|null             The HTML string if 'echo' is false. Otherwise, echoes the output.
 */
function aiopod_the_episodes( $attributes = array() ) {
	$echo = isset( $attributes['echo'] ) ? (bool) $attributes['echo'] : true;

	$episodes = AIOPOD_Public_Episodes::get_instance();
	$html = $episodes->render_shortcode_episodes( $attributes );
	
	if ( $echo ) {
		echo $html;
	} else {
		return $html;
	}
}

/**
 * Outputs the episodes search and filter form.
 *
 * @since 1.0.0
 * @param array $attributes Array of attributes to control the output.
 */
function aiopod_the_filters_form( $attributes = array() ) {
	$layout = $attributes['filters_layout'];
	if ( ! in_array( $layout, array( 'compact', 'horizontal', 'vertical' ) ) ) {
		$layout = 'horizontal';
	}

	// Auto-switch to "compact" layout if only the keyword field is enabled
	if ( 
		empty( $attributes['filters_tags'] ) && 
		empty( $attributes['filters_season'] ) && 
		empty( $attributes['filters_sort'] ) 
	) {
		$layout = 'compact';
	}

	// Render the filter form
	include apply_filters( 'aiopod_load_template', AIOPOD_PLUGIN_DIR . 'public/templates/filters/form-' . sanitize_file_name( $layout ) . '.php', $attributes );
}

/**
 * Outputs or returns the <img> element.
 *
 * @since  1.0.0
 * @param  array       $args Array of image args.
 * @return string|null HTML if echo=false, otherwise null.
 */
function aiopod_the_image( $args = array() ) {
	$performance_settings = aiopod_get_option( 'aiopod_performance_settings' );

	$defaults = array(
		'echo'     => true,
		'class'    => '',
		'loading'  => ! empty( $performance_settings['lazyloading'] ) ? 'lazy' : '',
		'decoding' => 'async',
	);

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

	// Resolve image data only if src is not provided
	if ( ! isset( $args['src'] ) || '' === $args['src'] ) {
		$image = aiopod_get_image( $args );

		$args['src'] = $image['src'];
		$args['alt'] = $image['alt'];
	}

	// Bail if still no src
	if ( ! isset( $args['src'] ) || '' === $args['src'] ) {
		return null;
	}

	// Normalize alt
	if ( ! isset( $args['alt'] ) ) {
		$args['alt'] = '';
	}

	// Build <img> attributes
	$img_attrs = array(
		'src' => esc_url( $args['src'] ),
		'alt' => esc_attr( $args['alt'] )
	);

	$attributes = array(
		'class',
		'loading',
		'decoding',
		'width',
		'height',
		'sizes',
		'srcset',
		'fetchpriority'
	);

	foreach ( $attributes as $attr ) {
		if ( isset( $args[ $attr ] ) && $args[ $attr ] !== '' ) {
			$img_attrs[ $attr ] = esc_attr( $args[ $attr ] );
		}
	}

	// Build HTML
	$html = '<img';

	foreach ( $img_attrs as $name => $value ) {
		$html .= sprintf( ' %s="%s"', $name, $value );
	}

	if ( isset( $args['placeholder'] ) && ! empty( $args['placeholder'] ) ) {
		$html .= sprintf( ' onerror="this.onerror=null; this.src=\'%s\'"', esc_url( $args['placeholder'] ) );
	}

	$html .= ' />';

	$html = apply_filters( 'aiopod_the_image', $html, $args );

	if ( false === $args['echo'] ) {
		return $html;
	}

	echo $html;
	return null;
}

/**
 * Render the pagination on archive pages.
 *
 * @since 1.0.0
 * @param array $attributes Array of pagination attributes.
 */
function aiopod_the_pagination( $attributes = array() ) {
	if ( 'loadmore' === $attributes['pagination'] ) {
		include apply_filters( 'aiopod_load_template', AIOPOD_PLUGIN_DIR . 'public/templates/pagination/loadmore.php', $attributes );
	} else {
		include apply_filters( 'aiopod_load_template', AIOPOD_PLUGIN_DIR . 'public/templates/pagination/numeric.php', $attributes );
	}
}

/**
 * Outputs a participant card layout with header, image, and metadata.
 *
 * @since 1.0.0
 * @param WP_Term $term       WP term object.
 * @param array   $attributes Array of attributes to control the output.
 */
function aiopod_the_participant_card( $term, $attributes = array() ) {
	if ( empty( $term ) ) {
		return;
	}

	include apply_filters( 'aiopod_load_template', AIOPOD_PLUGIN_DIR . 'public/templates/participants/participant-card.php', $attributes );
}

/**
 * Outputs or returns the player element.
 *
 * @since  1.0.0
 * @param  WP_Post     $post       WP post object.
 * @param  array       $attributes Array of attributes to control the output.
 * @return string|null             The HTML string if 'echo' is false. Otherwise, echoes the player.
 */
function aiopod_the_player( $post, $attributes = array() ) {
	if ( empty( $post ) ) {
		return;
	}

	$post_id = $post->ID;

	$src = get_post_meta( $post_id, 'episode_file', true );
	
	if ( empty( $src ) ) {
		return;
	}

	$is_video_supported = aiopod_is_video_supported( $post_id, $src );

	// Player configuration.
	$config = array();

	if ( ! empty( $attributes['player_autoplay'] ) ) {
		$config['autoplay'] = true;
	}

	if ( ! empty( $attributes['player_loop'] ) ) {
		$config['loop'] = array( 
			'active' => true 
		);
	}

	if ( ! empty( $attributes['player_muted'] ) ) {
		$config['muted'] = true;
	}

	if ( in_array( $attributes['player_preload'], array( 'auto', 'metadata', 'none' ) ) ) {
		$config['preload'] = $attributes['player_preload'];
	}

	if ( ! empty( $attributes['player_playsinline'] ) ) {
		$config['playsinline'] = true;
	} else {
		$config['playsinline'] = false;
	}

	if ( ! empty( $attributes['player_hotkeys'] ) ) {
		$config['keyboard'] = array(
			'focused' => true,
			'global'  => true
		);
	}

	// Player controls.
	$controls = array( 'play-large' );

	if ( ! empty( $attributes['player_control_rewind'] ) ) {
		$controls[] = 'rewind';
	}

	if ( ! empty( $attributes['player_control_play'] ) ) {
		$controls[] = 'play';
	}

	if ( ! empty( $attributes['player_control_fastforward'] ) ) {
		$controls[] = 'fast-forward';
	}

	if ( ! empty( $attributes['player_control_progress'] ) ) {
		$controls[] = 'progress';
	}

	if ( ! empty( $attributes['player_control_currenttime'] ) ) {
		$controls[] = 'current-time';
	}

	if ( ! empty( $attributes['player_control_duration'] ) ) {
		$controls[] = 'duration';
	}

	if ( ! empty( $attributes['player_control_volume'] ) ) {
		$controls[] = 'mute';

		if ( ! wp_is_mobile() ) {
			$controls[] = 'volume';
		}
	}	

	if ( ! empty( $attributes['player_control_speed'] ) ) {
		$config['speed'] = array(
			'selected' => 1,
			'options'  => array( 0.5, 0.75, 1, 1.5, 2 )
		);
	}

	if ( ! empty( $attributes['player_control_pip'] ) ) {
		$controls[] = 'pip';
	}

	if ( ! empty( $attributes['player_control_download'] ) ) {
		$controls[] = 'download';
	}

	if ( ! empty( $attributes['player_control_fullscreen'] ) ) {
		$controls[] = 'fullscreen';

		$config['fullscreen'] = array(
			'enabled'   => true,
			'iosNative' => true
		);
	}

	$config['controls'] = $controls;
	
	// Load chapters
	if ( ! empty( $attributes['player_control_chapters'] ) ) {		
		$chapters = aiopod_get_chapters( $post_id );

		if ( ! empty( $chapters ) ) {
			$config['markers'] = array(
				'enabled' => true, 
				'points'  => $chapters
			);
		}
	}

	// Build inline style only when video dimension settings are present.
	$style_parts = array();

	if ( ! empty( $attributes['player_width'] ) ) {
		$style_parts[] = '--plyr-video-width: ' . (int) $attributes['player_width'] . 'px';
	}

	if ( ! empty( $attributes['player_ratio'] ) ) {
		$style_parts[] = '--plyr-video-ratio: ' . (float) $attributes['player_ratio'] . '%';
	}

	$inline_style = ! empty( $style_parts ) ? ' style="' . implode( '; ', $style_parts ) . '"' : '';

	// The player markup.
	$player = sprintf(
		'<aiopod-media%s src="%s" data-download="%s" data-params="%s" stacked%s></aiopod-media>',
		$inline_style,
		esc_url( $src ),
		esc_url( aiopod_get_episode_file_url( $post ) ),
		esc_attr( wp_json_encode( $config ) ),
		( $is_video_supported ? ' is-video' : '' )
	);

	$player = apply_filters( 'aiopod_the_player', $player, $post, $attributes );

	// Return or echo the player.
	if ( isset( $attributes['echo'] ) && empty( $attributes['echo'] ) ) {
		return $player;
	}

	echo $player;
}

/**
 * Outputs a player card layout with header, image, and metadata.
 *
 * @since 1.0.0
 * @param WP_Post $post       WP post object.
 * @param array   $attributes Array of attributes to control the output.
 */
function aiopod_the_player_card( $post, $attributes = array() ) {
	if ( empty( $post ) ) {
		return;
	}

	$post_id = $post->ID;

	// Render the player
	include apply_filters( 'aiopod_load_template', AIOPOD_PLUGIN_DIR . 'public/templates/player/player-card.php' );
}

/**
 * Outputs a list of podcasts.
 *
 * @since  1.0.0
 * @param  array $attributes Array of attributes to control the output.
 * @return string|null             The HTML string if 'echo' is false. Otherwise, echoes the output.
 */
function aiopod_the_podcasts( $attributes = array() ) {
	$echo = isset( $attributes['echo'] ) ? (bool) $attributes['echo'] : true;

	$participants = AIOPOD_Public_Podcasts::get_instance();
	$html = $participants->render_shortcode_podcasts( $attributes );

	if ( $echo ) {
		echo $html;
	} else {
		return $html;
	}
}

/**
 * Outputs a podcast card layout with header, image, and metadata.
 *
 * @since 1.0.0
 * @param WP_Post $post       WP post object.
 * @param array   $attributes Array of attributes to control the output.
 */
function aiopod_the_podcast_card( $post, $attributes = array() ) {
	if ( empty( $post ) ) {
		return;
	}

	include apply_filters( 'aiopod_load_template', AIOPOD_PLUGIN_DIR . 'public/templates/podcasts/podcast-card.php', $attributes );
}

/**
 * Generate breadcrumb navigation for taxonomy term pages.
 *
 * @since  1.0.0
 * @param  WP_Term|null $term    Current term object.
 * @param  string       $taxonomy Taxonomy slug.
 * @param  int|null     $page_id  Optional archive page ID (if you use a custom page).
 * @return string       Breadcrumb HTML.
 */
function aiopod_the_taxonomy_breadcrumbs( $term = null, $taxonomy = '', $page_id = null ) {
	if ( empty( $taxonomy ) || ! taxonomy_exists( $taxonomy ) ) {
		return '';
	}

	$crumbs = array();

	/**
	 * Home
	 */
	$crumbs[] = array(
		'text' => __( 'Home', 'aio-podcast-studio' ),
		'url'  => home_url()
	);

	/**
	 * Optional taxonomy archive page (custom page)
	 */
	if ( $page_id ) {
		$post = get_post( $page_id );

		if ( $post ) {
			$crumbs[] = array(
				'text' => $post->post_title,
				'url'  => get_permalink( $page_id )
			);
		}
	}

	/**
	 * Single term page
	 */
	if ( $term instanceof WP_Term ) {
		// Parent terms
		$ancestors = get_ancestors( $term->term_id, $taxonomy );

		if ( ! empty( $ancestors ) ) {
			$ancestors = array_reverse( $ancestors );

			foreach ( $ancestors as $ancestor_id ) {
				$parent = get_term( $ancestor_id, $taxonomy );

				if ( ! is_wp_error( $parent ) ) {
					$crumbs[] = array(
						'text' => $parent->name,
						'url'  => get_term_link( $parent )
					);
				}
			}
		}

		// Current term (no link)
		$crumbs[] = array(
			'text' => $term->name
		);
	}

	/**
	 * Filters
	 */
	$crumbs = apply_filters( 'aiopod_breadcrumb_links', $crumbs, $term, $taxonomy, $page_id );

	/**
	 * Output
	 */
	if ( empty( $crumbs ) ) {
		return '';
	}

	$links = array();

	foreach ( $crumbs as $crumb ) {
		if ( isset( $crumb['url'] ) ) {
			$links[] = sprintf(
				'<span><a href="%s">%s</a></span>',
				esc_url( $crumb['url'] ),
				wp_kses_post( $crumb['text'] )
			);
		} else {
			$links[] = sprintf(
				'<span>%s</span>',
				wp_kses_post( $crumb['text'] )
			);
		}
	}

	$separator = apply_filters( 'aiopod_breadcrumb_separator', ' » ' );

	echo '<div class="aiopod-breadcrumbs">' . implode( $separator, $links ) . '</div>';
}
