<?php
/**
 * Reading UI: guides list with search, tag filter, and source filter.
 */

defined( 'ABSPATH' ) || exit;

$bw_search = isset( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : '';
$bw_tag    = isset( $_GET['guide_tag'] ) ? sanitize_title( wp_unslash( $_GET['guide_tag'] ) ) : '';
$bw_source = isset( $_GET['source'] ) ? sanitize_key( wp_unslash( $_GET['source'] ) ) : '';
$bw_paged  = isset( $_GET['paged'] ) ? max( 1, absint( $_GET['paged'] ) ) : 1;

$bw_args = array(
	'post_type'      => BW_Guides_CPT::POST_TYPE,
	'post_status'    => 'publish',
	// Raised from 20 (0.2.0 and earlier): the browse grid is now grouped by
	// category (BW_Guides_Keywords::group_guides()), and a 20-per-page slice
	// tends to cut a category's cards in half across two pages. 60 keeps a
	// category intact at the library sizes seen so far. A library that
	// outgrows 60 will still see a group split across pages — an accepted
	// tradeoff, not solved here (see docs/PLATFORM-ROADMAP.md).
	'posts_per_page' => 60,
	'paged'          => $bw_paged,
	'orderby'        => 'title',
	'order'          => 'ASC',
);
if ( '' !== $bw_search ) {
	$bw_args['s'] = $bw_search;
}
if ( '' !== $bw_tag ) {
	$bw_args['tax_query'] = array(
		array(
			'taxonomy' => BW_Guides_CPT::TAXONOMY,
			'field'    => 'slug',
			'terms'    => $bw_tag,
		),
	);
}
if ( 'hub' === $bw_source ) {
	$bw_args['meta_query'] = array(
		array(
			'key'   => BW_Guides_CPT::SOURCE_META,
			'value' => 'hub',
		),
	);
} elseif ( 'local' === $bw_source ) {
	$bw_args['meta_query'] = array(
		'relation' => 'OR',
		array(
			'key'   => BW_Guides_CPT::SOURCE_META,
			'value' => 'local',
		),
		array(
			'key'     => BW_Guides_CPT::SOURCE_META,
			'compare' => 'NOT EXISTS',
		),
	);
}

$bw_query = new WP_Query( $bw_args );

// Section-level search. Clients arrive with a small specific question ("how do
// I change the page url") that lives inside a larger guide, so a search also
// matches headings — and a guide's hidden keywords, see BW_Guides_Keywords —
// and offers a ranked, direct link to the best-matching section. Searches
// every published guide rather than the current page of results — the point
// is to find the answer wherever it lives.
$bw_sections = array();
if ( '' !== $bw_search ) {
	$bw_sections = BW_Guides_Content::search_sections(
		get_posts(
			array(
				'post_type'   => BW_Guides_CPT::POST_TYPE,
				'post_status' => 'publish',
				'numberposts' => 100,
				'orderby'     => 'title',
				'order'       => 'ASC',
			)
		),
		$bw_search
	);
}

$bw_terms = get_terms(
	array(
		'taxonomy'   => BW_Guides_CPT::TAXONOMY,
		'hide_empty' => true,
	)
);
if ( is_wp_error( $bw_terms ) ) {
	$bw_terms = array();
}

// Grouped for the browse grid: hub guides by category (alphabetical),
// uncategorized under "More guides", local guides always last under
// "Your guides" — see BW_Guides_Keywords::group_guides().
$bw_groups = $bw_query->have_posts() ? BW_Guides_Keywords::group_guides( $bw_query->posts ) : array();
?>
<div class="wrap bw-guides-wrap">
	<h1 class="wp-heading-inline"><?php esc_html_e( 'Guides', 'bw-guides' ); ?></h1>
	<a href="<?php echo esc_url( admin_url( 'post-new.php?post_type=' . BW_Guides_CPT::POST_TYPE ) ); ?>" class="page-title-action"><?php esc_html_e( 'Add New Guide', 'bw-guides' ); ?></a>
	<hr class="wp-header-end">

	<form method="get" action="<?php echo esc_url( admin_url( 'admin.php' ) ); ?>" class="bw-guides-filters">
		<input type="hidden" name="page" value="<?php echo esc_attr( BW_Guides_Admin::MENU_SLUG ); ?>">
		<div class="bw-guides-search-row">
			<input type="search" name="s" value="<?php echo esc_attr( $bw_search ); ?>" placeholder="<?php esc_attr_e( 'What do you need help with?', 'bw-guides' ); ?>" class="bw-guides-search-input">
		</div>
		<div class="bw-guides-filter-row">
			<select name="guide_tag">
				<option value=""><?php esc_html_e( 'All tags', 'bw-guides' ); ?></option>
				<?php foreach ( $bw_terms as $bw_term ) : ?>
					<option value="<?php echo esc_attr( $bw_term->slug ); ?>" <?php selected( $bw_tag, $bw_term->slug ); ?>>
						<?php echo esc_html( $bw_term->name . ' (' . $bw_term->count . ')' ); ?>
					</option>
				<?php endforeach; ?>
			</select>
			<select name="source">
				<option value=""><?php esc_html_e( 'All sources', 'bw-guides' ); ?></option>
				<option value="hub" <?php selected( $bw_source, 'hub' ); ?>><?php esc_html_e( 'From Bowden Works', 'bw-guides' ); ?></option>
				<option value="local" <?php selected( $bw_source, 'local' ); ?>><?php esc_html_e( 'Created here', 'bw-guides' ); ?></option>
			</select>
			<button type="submit" class="button"><?php esc_html_e( 'Filter', 'bw-guides' ); ?></button>
			<?php if ( '' !== $bw_search || '' !== $bw_tag || '' !== $bw_source ) : ?>
				<a href="<?php echo esc_url( BW_Guides_Admin::list_url() ); ?>" class="button-link"><?php esc_html_e( 'Reset', 'bw-guides' ); ?></a>
			<?php endif; ?>
		</div>
	</form>

	<?php if ( ! empty( $bw_sections ) ) : ?>
		<div class="bw-guides-sections">
			<h2><?php esc_html_e( 'Jump straight to', 'bw-guides' ); ?></h2>
			<ul>
				<?php foreach ( $bw_sections as $bw_section ) : ?>
					<li>
						<a href="<?php echo esc_url( BW_Guides_Admin::guide_url( $bw_section['post']->ID ) . '#' . $bw_section['heading']['slug'] ); ?>">
							<?php echo esc_html( $bw_section['heading']['text'] ); ?>
						</a>
						<?php if ( 'keyword' === $bw_section['via'] ) : ?>
							<span class="bw-guides-section-hint">
								<?php
								printf(
									/* translators: %s: the search term the client typed, shown because it matched a hidden keyword rather than the visible heading text */
									esc_html__( '(matches: %s)', 'bw-guides' ),
									esc_html( $bw_search )
								);
								?>
							</span>
						<?php endif; ?>
						<span class="bw-guides-section-source"><?php echo esc_html( $bw_section['post']->post_title ); ?></span>
					</li>
				<?php endforeach; ?>
			</ul>
		</div>
	<?php endif; ?>

	<?php if ( ! $bw_query->have_posts() && ! empty( $bw_sections ) ) : ?>
		<?php // Sections matched but no whole guide did — an alarming "No guides
		// found." here reads as failure when the answer is sitting right above. ?>
		<div class="bw-guides-empty bw-guides-empty-soft">
			<p><?php esc_html_e( 'No guide matches this as a whole — the sections above are the closest answers.', 'bw-guides' ); ?></p>
		</div>
	<?php elseif ( ! $bw_query->have_posts() ) : ?>
		<div class="bw-guides-empty">
			<p><?php esc_html_e( 'No guides found.', 'bw-guides' ); ?></p>
			<?php if ( '' === $bw_search && '' === $bw_tag && '' === $bw_source && current_user_can( 'manage_options' ) && '' === BW_Guides_Settings::site_key() ) : ?>
				<p>
					<?php esc_html_e( 'This site is not connected to the guides hub yet.', 'bw-guides' ); ?>
					<a href="<?php echo esc_url( admin_url( 'admin.php?page=' . BW_Guides_Admin::SETTINGS_SLUG ) ); ?>"><?php esc_html_e( 'Enter your site key in Settings', 'bw-guides' ); ?></a>
				</p>
			<?php endif; ?>
		</div>
	<?php else : ?>
		<?php foreach ( $bw_groups as $bw_group ) : ?>
			<div class="bw-guides-group">
				<h2 class="bw-guides-group-title"><?php echo esc_html( $bw_group['label'] ); ?></h2>
				<div class="bw-guides-grid">
					<?php
					foreach ( $bw_group['posts'] as $bw_post ) :
						$bw_is_hub         = 'hub' === get_post_meta( $bw_post->ID, BW_Guides_CPT::SOURCE_META, true );
						$bw_post_tags      = get_the_terms( $bw_post, BW_Guides_CPT::TAXONOMY );
						$bw_excerpt        = $bw_post->post_excerpt ? $bw_post->post_excerpt : wp_trim_words( wp_strip_all_tags( $bw_post->post_content ), 24 );
						// Up to 3 quick section links per card — the guide's
						// first h2s, so a client can jump straight to a task
						// without opening the guide first.
						$bw_quick_headings = array_slice(
							array_values(
								array_filter(
									BW_Guides_Content::headings( $bw_post->post_content ),
									static function ( $bw_h ) {
										return 2 === $bw_h['level'];
									}
								)
							),
							0,
							3
						);
						?>
						<div class="bw-guides-card">
							<div class="bw-guides-card-badges">
								<?php if ( $bw_is_hub ) : ?>
									<span class="bw-guides-badge bw-guides-badge-hub"><?php esc_html_e( 'Bowden Works', 'bw-guides' ); ?></span>
								<?php else : ?>
									<span class="bw-guides-badge bw-guides-badge-local"><?php esc_html_e( 'Created here', 'bw-guides' ); ?></span>
								<?php endif; ?>
							</div>
							<h2><a href="<?php echo esc_url( BW_Guides_Admin::guide_url( $bw_post->ID ) ); ?>"><?php echo esc_html( $bw_post->post_title ); ?></a></h2>
							<p class="bw-guides-card-excerpt"><?php echo esc_html( $bw_excerpt ); ?></p>
							<?php if ( $bw_quick_headings ) : ?>
								<ul class="bw-guides-card-quicklinks">
									<?php foreach ( $bw_quick_headings as $bw_qh ) : ?>
										<li><a href="<?php echo esc_url( BW_Guides_Admin::guide_url( $bw_post->ID ) . '#' . $bw_qh['slug'] ); ?>"><?php echo esc_html( $bw_qh['text'] ); ?></a></li>
									<?php endforeach; ?>
								</ul>
							<?php endif; ?>
							<div class="bw-guides-card-footer">
								<span class="bw-guides-updated">
									<?php
									/* translators: %s: human-readable time difference */
									echo esc_html( sprintf( __( 'Updated %s ago', 'bw-guides' ), human_time_diff( get_post_modified_time( 'U', true, $bw_post ) ) ) );
									?>
								</span>
								<?php if ( $bw_post_tags && ! is_wp_error( $bw_post_tags ) ) : ?>
									<span class="bw-guides-card-tags">
										<?php foreach ( $bw_post_tags as $bw_post_tag ) : ?>
											<a class="bw-guides-tag" href="<?php echo esc_url( BW_Guides_Admin::list_url( array( 'guide_tag' => $bw_post_tag->slug ) ) ); ?>"><?php echo esc_html( $bw_post_tag->name ); ?></a>
										<?php endforeach; ?>
									</span>
								<?php endif; ?>
							</div>
						</div>
					<?php endforeach; ?>
				</div>
			</div>
		<?php endforeach; ?>

		<?php if ( $bw_query->max_num_pages > 1 ) : ?>
			<div class="tablenav bottom"><div class="tablenav-pages">
				<?php
				$bw_base_args = array_filter(
					array(
						's'         => $bw_search,
						'guide_tag' => $bw_tag,
						'source'    => $bw_source,
					)
				);
				if ( $bw_paged > 1 ) {
					echo '<a class="button" href="' . esc_url( BW_Guides_Admin::list_url( array_merge( $bw_base_args, array( 'paged' => $bw_paged - 1 ) ) ) ) . '">&lsaquo; ' . esc_html__( 'Previous', 'bw-guides' ) . '</a> ';
				}
				echo '<span class="paging-input">' . (int) $bw_paged . ' / ' . (int) $bw_query->max_num_pages . '</span>';
				if ( $bw_paged < $bw_query->max_num_pages ) {
					echo ' <a class="button" href="' . esc_url( BW_Guides_Admin::list_url( array_merge( $bw_base_args, array( 'paged' => $bw_paged + 1 ) ) ) ) . '">' . esc_html__( 'Next', 'bw-guides' ) . ' &rsaquo;</a>';
				}
				?>
			</div></div>
		<?php endif; ?>
	<?php endif; ?>
	<?php wp_reset_postdata(); ?>
</div>
