<?php
/**
 * Brentwood Team Modal — front-end render.
 *
 * A Staff directory in one of three layouts, each opening the SAME profile modal
 * on click (view.js clones each card's inert <template> into one shared dialog):
 *   - "thumbnails": a photo grid with a translucent name/role overlay
 *     (mirrors brentwood.ca/academics/faculty).
 *   - "list": single/few-column rows — a small portrait photo on the left, then
 *     name, role and credentials — mirrors the live staff-profile-list "list".
 *   - "grid": a compact grid of names only (no photos) — the live "grid" layout.
 * All three keep the identical .bw-tm__cell > .bw-tm__card + <template> structure
 * so the modal wiring (view.js) is layout-agnostic; the visual differences are
 * pure CSS keyed off the .bw-tm--{layout} wrapper class.
 *
 * Data source: the `staff` post type — title = name, post_content = bio,
 * featured image = photo, ACF `staff_position` = role, `staff_credentials` =
 * credentials. Optionally filtered by the `department` taxonomy. The query and
 * profile markup are shared with bw/instructor via inc/bw-staff-profile.php.
 *
 * Cards with neither a bio nor credentials have nothing to show in a modal, so
 * they render as a static (non-clickable) tile — like the live site's
 * photo-only entries.
 *
 * @var array    $attributes Block attributes.
 * @var string   $content    Inner content (unused — dynamic block).
 * @var WP_Block $block      Block instance.
 */

defined( 'ABSPATH' ) || exit;

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

$layout = $attributes['layout'] ?? 'thumbnails';
if ( ! in_array( $layout, array( 'thumbnails', 'list', 'grid' ), true ) ) {
	$layout = 'thumbnails';
}

// ── query ────────────────────────────────────────────────────────────────────
$posts = bw_staff_query( array(
	'deptTerms'    => $attributes['deptTerms']    ?? array(),
	'deptRelation' => $attributes['deptRelation'] ?? 'IN',
	'orderby'      => $attributes['orderby']      ?? 'name_last',
	'order'        => $attributes['order']        ?? 'asc',
	'limit'        => $attributes['limit']        ?? 0,
	'exclude'      => $attributes['exclude']       ?? array(),
) );
if ( empty( $posts ) ) {
	return;
}

$columns = max( 1, min( 6, (int) ( $attributes['columns'] ?? 3 ) ) );

// Photo-less staff fall back to the white Brentwood shield centred on the grey
// tile, exactly like the live faculty grid.
$shield_white_uri = get_stylesheet_directory_uri() . '/blocks/team-modal/images/icon_white.svg';

// Mortarboard glyph for the list layout's credentials line (same as the modal).
$cap_icon = '<svg class="bw-tm__cap" viewBox="0 0 24 24" role="img" aria-hidden="true" focusable="false">'
	. '<path d="M12 3 1 9l11 6 9-4.91V17h2V9L12 3zM5 13.18v3.82c0 .73 3.13 3 7 3s7-2.27 7-3v-3.82l-7 3.82-7-3.82z"/></svg>';

// ── cards ──────────────────────────────────────────────────────────────────
$cards_html = '';
foreach ( $posts as $p ) {
	$name = get_the_title( $p );
	$role = trim( (string) get_post_meta( $p->ID, 'staff_position', true ) );
	$cred = trim( (string) get_post_meta( $p->ID, 'staff_credentials', true ) );

	// 'large' (not 'medium'): the cards are ~220px CSS wide, but WordPress's
	// `medium` resolves to only 225x300 for a 3:4 portrait, which visibly
	// pixelates on any 2x/3x display. `large` gives 768x1024 for these
	// portraits — crisp at 2x-3x — and the images stay lazy-loaded. A `sizes`
	// hint is supplied so that when a srcset is available the browser can still
	// pick a smaller candidate on narrow screens.
	$photo = has_post_thumbnail( $p )
		? get_the_post_thumbnail(
			$p,
			'large',
			array(
				'class'   => 'bw-tm__img',
				'loading' => 'lazy',
				'sizes'   => '(max-width: 767px) 50vw, (max-width: 1024px) 33vw, 240px',
			)
		)
		: '<span class="bw-tm__placeholder"><img class="bw-tm__placeholder-icon" src="' . esc_url( $shield_white_uri ) . '" alt="" aria-hidden="true" /></span>';

	// The visible card face differs per layout; the modal <template> below is
	// identical for all three.
	if ( 'grid' === $layout ) {
		// Names only — no photo.
		$visible = '<span class="bw-tm__gridname">' . esc_html( $name ) . '</span>';
	} elseif ( 'list' === $layout ) {
		// Photo on the left, name/role/credentials stacked on the right.
		$text  = '<span class="bw-tm__rowtext">';
		$text .= '<span class="bw-tm__name">' . esc_html( $name ) . '</span>';
		if ( '' !== $role ) {
			$text .= '<span class="bw-tm__role">' . esc_html( $role ) . '</span>';
		}
		if ( '' !== $cred ) {
			$text .= '<span class="bw-tm__cred">' . $cap_icon . '<span>' . esc_html( $cred ) . '</span></span>';
		}
		$text .= '</span>';
		$visible = '<span class="bw-tm__photo">' . $photo . '</span>' . $text;
	} else {
		// thumbnails: photo with a translucent name/role overlay.
		$caption = '<span class="bw-tm__caption">'
			. '<span class="bw-tm__name">' . esc_html( $name ) . '</span>'
			. ( '' !== $role ? '<span class="bw-tm__role">' . esc_html( $role ) . '</span>' : '' )
			. '</span>';
		$visible = '<span class="bw-tm__photo">' . $photo . '</span>' . $caption;
	}

	if ( bw_staff_has_profile( $p ) ) {
		$cards_html .= '<div class="bw-tm__cell">'
			. '<button type="button" class="bw-tm__card" aria-haspopup="dialog">' . $visible . '</button>'
			. '<template class="bw-tm__full">' . bw_staff_profile_html( $p ) . '</template>' // phpcs:ignore WordPress.Security.EscapeOutput -- escaped in helper
			. '</div>';
	} else {
		// Nothing to show in a modal → static (non-clickable) tile.
		$cards_html .= '<div class="bw-tm__cell">'
			. '<div class="bw-tm__card bw-tm__card--static">' . $visible . '</div>'
			. '</div>';
	}
}

// ── wrapper ──────────────────────────────────────────────────────────────────
$style = '--bw-tm-cols:' . (int) $columns . ';';

printf(
	'<div %s><div class="bw-tm__grid">%s</div></div>',
	get_block_wrapper_attributes( array( 'class' => 'bw-tm bw-tm--' . $layout, 'style' => $style ) ), // phpcs:ignore WordPress.Security.EscapeOutput
	$cards_html // phpcs:ignore WordPress.Security.EscapeOutput -- assembled from escaped parts above
);
