<?php
/**
 * Staff profile modal via anchor / shortcode — open any staff member's profile
 * pop-up from ANYWHERE, without placing a Team Modal / Instructor block.
 *
 * Convention: a link whose href ends with `#staff-<slug>` (the `staff` post
 * type slug, e.g. `#staff-megan-rea`) opens that person's profile in the shared
 * modal. Works in page content, menus, widgets, an existing hand-built list —
 * anywhere a link can live — and as a deep link (landing on a URL that already
 * carries `#staff-<slug>` opens it on load).
 *
 * How it fits together:
 *   - REST: GET /wp-json/bw/v1/staff-modal/<slug> returns the profile HTML
 *     (the wide "feature" layout — photo bleeding right, like the live instructor
 *     pop-up) built by the SAME renderer the blocks use (bw_staff_profile_html).
 *   - JS: blocks/team-modal/view.js (shared modal) intercepts `#staff-<slug>`
 *     clicks + the initial hash, fetches the HTML, and opens the modal. It is
 *     enqueued site-wide here so the anchor works with no block on the page; the
 *     modal CSS + fonts are lazy-injected by view.js only when a modal opens.
 *   - Shortcode: [bw_staff_modal slug="megan-rea"] outputs a ready-made link
 *     (label defaults to the staff member's name). Plain `<a href="#staff-…">`
 *     written by hand works too — the JS matches any such link.
 *
 * No plugin changes, no DB writes. Reuses the team-modal renderer + modal.
 *
 * @package Kadence-Child
 */

defined( 'ABSPATH' ) || exit;

if ( ! function_exists( 'bw_staff_by_slug' ) ) {
	/** Published `staff` post for a slug, or null. */
	function bw_staff_by_slug( $slug ) {
		$slug = sanitize_title( $slug );
		if ( '' === $slug || ! post_type_exists( 'staff' ) ) {
			return null;
		}
		$q = new WP_Query( array(
			'post_type'           => 'staff',
			'name'                => $slug,
			'post_status'         => 'publish',
			'posts_per_page'      => 1,
			'no_found_rows'       => true,
			'ignore_sticky_posts' => true,
		) );
		return $q->have_posts() ? $q->posts[0] : null;
	}
}

/**
 * REST: the profile HTML for one staff member, for the anchor/shortcode modal.
 * Public read — only ever exposes PUBLISHED staff, the same data the faculty
 * grid already shows on the front end.
 */
add_action( 'rest_api_init', function () {
	register_rest_route( 'bw/v1', '/staff-modal/(?P<slug>[a-z0-9-]+)', array(
		'methods'             => 'GET',
		'permission_callback' => '__return_true',
		'args'                => array(
			'slug' => array( 'sanitize_callback' => 'sanitize_title' ),
		),
		'callback'            => function ( $req ) {
			require_once get_stylesheet_directory() . '/inc/bw-staff-profile.php';
			$post = bw_staff_by_slug( $req['slug'] );
			if ( ! $post ) {
				return new WP_Error( 'bw_staff_not_found', 'Staff member not found.', array( 'status' => 404 ) );
			}
			return array(
				'slug' => $post->post_name,
				'name' => get_the_title( $post ),
				'html' => bw_staff_profile_html( $post, 'h2', 'feature' ),
			);
		},
	) );
} );

/**
 * Enqueue the shared modal script site-wide so `#staff-<slug>` links work on any
 * page (the block only enqueues it when present). The modal CSS + fonts are NOT
 * loaded globally — view.js injects them on first open, so pages that never open
 * a staff modal pay nothing but the small script.
 */
add_action( 'wp_enqueue_scripts', function () {
	if ( is_admin() || ! wp_script_is( 'bw-team-modal-view', 'registered' ) ) {
		return;
	}
	wp_enqueue_script( 'bw-team-modal-view' );

	$theme = get_stylesheet_directory();
	$css   = $theme . '/blocks/team-modal/style.css';
	wp_localize_script( 'bw-team-modal-view', 'BW_STAFF_MODAL', array(
		'rest'  => esc_url_raw( rest_url( 'bw/v1/staff-modal/' ) ),
		'css'   => get_stylesheet_directory_uri() . '/blocks/team-modal/style.css?ver=' . ( file_exists( $css ) ? filemtime( $css ) : '1' ),
		'fonts' => 'https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,400;0,600;0,700;1,400&family=Oswald:wght@300;400;500&display=swap',
	) );
}, 20 );

/**
 * [bw_staff_modal slug="megan-rea" text="Megan Rea" class=""] — a link that
 * opens the staff profile modal. `text` (or enclosed content) is the label;
 * it defaults to the staff member's name. Renders nothing for an unknown slug.
 */
add_shortcode( 'bw_staff_modal', function ( $atts, $content = '' ) {
	$a = shortcode_atts( array(
		'slug'  => '',
		'text'  => '',
		'class' => '',
	), $atts, 'bw_staff_modal' );

	$slug = sanitize_title( $a['slug'] );
	if ( '' === $slug ) {
		return '';
	}
	$post = bw_staff_by_slug( $slug );

	// Label: enclosed content wins, then the text attr, then the staff name.
	$has_text = ( '' !== trim( (string) $content ) ) || ( '' !== $a['text'] );
	if ( '' !== trim( (string) $content ) ) {
		$label = do_shortcode( $content ); // trusted editor content
	} elseif ( '' !== $a['text'] ) {
		$label = esc_html( $a['text'] );
	} else {
		$label = esc_html( $post ? get_the_title( $post ) : $slug );
	}

	// Unknown/unpublished staff → don't emit a dead modal trigger. Keep any
	// author-supplied label as plain text; render nothing if there was none.
	if ( ! $post ) {
		return $has_text ? '<span class="bw-staff-modal-link is-missing">' . $label . '</span>' : '';
	}

	$cls = trim( 'bw-staff-modal-link ' . $a['class'] );
	return sprintf(
		'<a class="%s" href="#staff-%s">%s</a>',
		esc_attr( $cls ),
		esc_attr( $slug ),
		$label // already escaped / trusted above
	);
} );
