<?php
/**
 * Brentwood 100 Grid — front-end render.
 *
 * Emits every published `bw_hundred` item as a tile, plus the constraints the
 * client-side packer needs (which shapes the tile may take, which content
 * layouts it allows, whether it actually has text and media). The packer then
 * fits them into a 3-column grid of square slots — see packer.js.
 *
 * Nothing about the arrangement is decided here. The HTML is identical for every
 * visitor and cached in a transient; the shuffle happens in the browser, which is
 * what lets the page stay cacheable while still looking fresh on each visit.
 *
 * Every tile opens the pop-up. That is deliberate: making it conditional on
 * hidden content or overflowing text produces tiles that look identical where
 * some respond to a click and some don't, and no way for a visitor to tell which.
 *
 * @var array $attributes Block attributes.
 */

defined( 'ABSPATH' ) || exit;

require_once get_stylesheet_directory() . '/inc/bw-hundred.php';

$cache_key = 'bw_hundred_grid_v2';
$inner     = get_transient( $cache_key );

if ( false === $inner ) {
	$posts = bw_hundred_query();
	if ( empty( $posts ) ) {
		return;
	}

	$inner = '';
	$number = 0;
	foreach ( $posts as $p ) {
		$tile = bw_hundred_tile_data( $p );

		/* The badge number IS the position in the admin's drag order — there is no
		   number field to keep in step any more. bw_hundred_query() orders by
		   menu_order, which is what Post Types Order writes, so first in the list
		   is #1. The cache is flushed on reorder (see inc/bw-hundred.php). */
		$number++;

		$inner .= '<div class="bw100__cell bw-tl__cell"'
			. ' data-bw100-anchor="' . esc_attr( $p->post_name ) . '"'
			. ' data-combos="' . esc_attr( implode( ',', $tile['combos'] ) ) . '"'
			. ' data-has-text="' . ( $tile['has_text'] ? '1' : '0' ) . '"'
			. ' data-has-media="' . ( $tile['has_media'] ? '1' : '0' ) . '">'
			. '<button type="button" class="bw100__tile bw-tl__modal-trigger" aria-haspopup="dialog"'
			. ' aria-label="' . esc_attr( sprintf( '%d. %s', $number, get_the_title( $p ) ) ) . '">'
			. '<span class="bw100__num" aria-hidden="true">' . esc_html( $number ) . '</span>'
			. bw_hundred_tile_face( $p, $tile ) // phpcs:ignore WordPress.Security.EscapeOutput -- escaped in helper
			. '</button>'
			. '<template class="bw-tl__course">' . bw_hundred_modal_html( $p ) . '</template>' // phpcs:ignore WordPress.Security.EscapeOutput -- escaped in helper
			. '</div>';
	}

	set_transient( $cache_key, $inner, DAY_IN_SECONDS );
}

/* The grid is hidden until the packer has positioned everything — without this
   the tiles paint in document order and then jump, which on 89 tiles is a very
   visible reflow. visibility, not display, so images still start loading.
   <noscript> reveals it as a plain column list when JS never arrives. */
printf(
	'<div %s><noscript><style>.bw100__grid{visibility:visible !important}.bw100__cell{grid-column:auto !important;grid-row:auto !important}</style></noscript><div class="bw100__grid">%s</div></div>',
	get_block_wrapper_attributes( array( 'class' => 'bw100 bw-tl bw-tl--courses' ) ), // phpcs:ignore WordPress.Security.EscapeOutput
	$inner // phpcs:ignore WordPress.Security.EscapeOutput -- assembled from escaped parts above / cached
);
