<?php
/**
 * Brentwood FAQ Accordion — front-end render.
 *
 * Two columns: a white text card (intro + a list of question triggers) beside a
 * large image. Clicking a question expands its answer in a panel BELOW the image
 * (in the media column), with a × to close. Single-open by default.
 *
 * The pieces come from the block's children:
 *   - one bw/faq-text  → the intro text (its own InnerBlocks)
 *   - many bw/faq-item → each carries a `question` attribute (the list link) and
 *     its answer as its own InnerBlocks (rendered into the panel)
 * Both children are static (save InnerBlocks.Content); this parent reads them via
 * $block->inner_blocks and lays everything out. view.js toggles the panels.
 *
 * Mirrors brentwood.ca/admissions/financial-information.
 *
 * @var array    $attributes Block attributes.
 * @var string   $content    Inner content (unused — we render children ourselves).
 * @var WP_Block $block      Block instance (its inner_blocks are text + items).
 */

defined( 'ABSPATH' ) || exit;

if ( ! function_exists( 'bw_faq_color' ) ) {
	function bw_faq_color( $value, $default = '' ) {
		$value = trim( (string) $value );
		if ( '' === $value ) {
			return $default;
		}
		if ( preg_match( '/^#([0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i', $value )
			|| preg_match( '/^rgba?\(\s*[0-9.,%\s\/]+\)$/i', $value )
			|| preg_match( '/^var\(\s*--[a-z0-9\-]+\s*\)$/i', $value ) ) {
			return $value;
		}
		return $default;
	}
}

if ( ! function_exists( 'bw_faq_unique_id' ) ) {
	/**
	 * Slug of a question, kept unique across every FAQ Accordion in the request so
	 * duplicate questions (or two blocks) still get distinct ids ("-2", "-3", …).
	 */
	function bw_faq_unique_id( $question ) {
		static $used = array();
		$base = sanitize_title( $question );
		if ( '' === $base ) {
			$base = 'faq';
		}
		$id = $base;
		$n  = 2;
		while ( isset( $used[ $id ] ) ) {
			$id = $base . '-' . $n;
			$n++;
		}
		$used[ $id ] = true;
		return $id;
	}
}

// ── sanitize attributes ──────────────────────────────────────────────────────
$image_url      = esc_url_raw( $attributes['imageUrl'] ?? '' );
$image_alt      = sanitize_text_field( $attributes['imageAlt'] ?? '' );
$layout         = ( 'revealed' === ( $attributes['layout'] ?? 'default' ) ) ? 'revealed' : 'default';
$image_position = ( 'left' === ( $attributes['imagePosition'] ?? 'right' ) ) ? 'left' : 'right';
$single_open    = ! isset( $attributes['singleOpen'] ) || ! empty( $attributes['singleOpen'] );
$primary        = bw_faq_color( $attributes['primaryColor'] ?? '', '#cc0000' );
$pad_top        = max( 0, min( 120, (int) ( $attributes['padTop']    ?? 28 ) ) );
$pad_right      = max( 0, min( 120, (int) ( $attributes['padRight']  ?? 28 ) ) );
$pad_bottom     = max( 0, min( 120, (int) ( $attributes['padBottom'] ?? 28 ) ) );
$pad_left       = max( 0, min( 120, (int) ( $attributes['padLeft']   ?? 28 ) ) );

// ── collect intro text + items from the children ─────────────────────────────
$intro_html = '';
$items      = array();
if ( isset( $block->inner_blocks ) ) {
	foreach ( $block->inner_blocks as $child ) {
		if ( 'bw/faq-text' === $child->name ) {
			if ( '' === $intro_html ) {
				$intro_html = $child->render(); // the intro InnerBlocks
			}
			continue;
		}
		if ( 'bw/faq-item' !== $child->name ) {
			continue;
		}
		$question = sanitize_text_field( $child->attributes['question'] ?? '' );
		if ( '' === $question ) {
			continue;
		}
		$behavior = ( 'link' === ( $child->attributes['behavior'] ?? 'accordion' ) ) ? 'link' : 'accordion';
		$item = array(
			'question' => $question,
			'behavior' => $behavior,
			'id'       => '',
			'answer'   => '',
			'url'      => '',
			'new_tab'  => false,
		);
		if ( 'link' === $behavior ) {
			$item['url']     = esc_url_raw( $child->attributes['url'] ?? '' );
			$item['new_tab'] = ! empty( $child->attributes['newTab'] );
		} else {
			$item['id']     = bw_faq_unique_id( $question );
			$item['answer'] = $child->render(); // the answer InnerBlocks
		}
		$items[] = $item;
	}
}

// ── revealed-panel layout ────────────────────────────────────────────────────
// A single-column FAQ, hidden until a link to its anchor is clicked (view.js
// reveals + scrolls; the × hides it and clears the hash). No image; every
// question is shown as a heading with its answer below. Mirrors the live
// course-selection "Frequently Asked Questions" reveal panel.
if ( 'revealed' === $layout ) {
	$anchor     = sanitize_title( $attributes['revealAnchor'] ?? '' );
	$has_anchor = ( '' !== $anchor );

	$qa_html = '';
	foreach ( $items as $it ) {
		if ( 'accordion' !== $it['behavior'] ) {
			continue; // only items that carry an answer
		}
		$qa_html .= '<section class="bw-faq__qa">'
			. '<h3 class="bw-faq__q" id="' . esc_attr( $it['id'] ) . '">' . esc_html( $it['question'] ) . '</h3>'
			. '<div class="bw-faq__a">' . $it['answer'] . '</div>' // phpcs:ignore WordPress.Security.EscapeOutput -- answer is InnerBlocks (self-escaped)
			. '</section>';
	}

	if ( '' === $intro_html && '' === $qa_html ) {
		return;
	}

	$close_btn = '<button type="button" class="bw-faq__close bw-faq__reveal-close" data-bw-faq-reveal-close aria-label="Close">'
		. '<svg viewBox="0 0 24 24" role="img" aria-hidden="true" focusable="false">'
		. '<path fill="currentColor" d="M18.3 5.71a1 1 0 0 0-1.41 0L12 10.59 7.11 5.7A1 1 0 1 0 5.7 7.11L10.59 12 5.7 16.89a1 1 0 1 0 1.41 1.41L12 13.41l4.89 4.89a1 1 0 0 0 1.41-1.41L13.41 12l4.89-4.89a1 1 0 0 0 0-1.4z"></path>'
		. '</svg></button>';

	$head = '<div class="bw-faq__reveal-head">'
		. ( '' !== $intro_html ? '<div class="bw-faq__intro">' . $intro_html . '</div>' : '<span class="bw-faq__reveal-spacer"></span>' )
		. $close_btn
		. '</div>';

	$pad   = (int) $pad_top . 'px ' . (int) $pad_right . 'px ' . (int) $pad_bottom . 'px ' . (int) $pad_left . 'px';
	$style = '--bw-faq-primary:' . esc_attr( $primary ) . ';--bw-faq-pad:' . esc_attr( $pad ) . ';';

	$wrapper_args = array(
		'class' => 'bw-faq bw-faq--reveal' . ( $has_anchor ? ' is-hidden' : '' ),
		'style' => $style,
	);
	if ( $has_anchor ) {
		$wrapper_args['id'] = $anchor;
	}

	printf(
		'<div %s>%s<div class="bw-faq__reveal-body">%s</div></div>',
		get_block_wrapper_attributes( $wrapper_args ), // phpcs:ignore WordPress.Security.EscapeOutput
		$head,    // phpcs:ignore WordPress.Security.EscapeOutput -- assembled from escaped parts
		$qa_html  // phpcs:ignore WordPress.Security.EscapeOutput -- assembled from escaped parts
	);
	return;
}

// Nothing meaningful to show.
if ( '' === $intro_html && empty( $items ) && '' === $image_url ) {
	return;
}

// ── question list (left card) ────────────────────────────────────────────────
$list_html = '';
if ( $items ) {
	$list_html = '<ul class="bw-faq__list">';
	foreach ( $items as $it ) {
		if ( 'link' === $it['behavior'] ) {
			// Plain link — navigates instead of expanding a panel.
			$href   = ( '' !== $it['url'] ) ? ' href="' . esc_url( $it['url'] ) . '"' : '';
			$target = $it['new_tab'] ? ' target="_blank" rel="noopener noreferrer"' : '';
			$list_html .= '<li class="bw-faq__list-item">'
				. '<a class="bw-faq__link"' . $href . $target . '>'
				. esc_html( $it['question'] )
				. '</a></li>';
		} else {
			$list_html .= '<li class="bw-faq__list-item">'
				. '<a class="bw-faq__trigger scroll-ignore" href="#' . esc_attr( $it['id'] ) . '"'
				. ' aria-controls="' . esc_attr( $it['id'] ) . '" aria-expanded="false" data-bw-faq-trigger>'
				. esc_html( $it['question'] )
				. '</a></li>';
		}
	}
	$list_html .= '</ul>';
}

$card_html = '<div class="bw-faq__card">'
	. ( '' !== $intro_html ? '<div class="bw-faq__intro">' . $intro_html . '</div>' : '' )
	. $list_html
	. '</div>';

// ── image + panels (media column) ────────────────────────────────────────────
$image_html = '';
if ( '' !== $image_url ) {
	// Curved white divider that bulges the card colour into the image, like the
	// bw/curve block. Side follows the image position (card is on the opposite
	// side). Self-contained here so the block needs no extra asset/handle.
	$curve = '<span class="bw-faq__curve bw-faq__curve--' . esc_attr( $image_position ) . '" aria-hidden="true">'
		. '<span class="bw-faq__curve-shape"></span></span>';
	$image_html = '<div class="bw-faq__image-wrap">'
		. '<img class="bw-faq__image" src="' . esc_url( $image_url ) . '" alt="' . esc_attr( $image_alt ) . '" loading="lazy" />'
		. $curve
		. '</div>';
}

$close = '<button type="button" class="bw-faq__close" aria-label="Close">'
	. '<svg viewBox="0 0 24 24" role="img" aria-hidden="true" focusable="false">'
	. '<path fill="currentColor" d="M18.3 5.71a1 1 0 0 0-1.41 0L12 10.59 7.11 5.7A1 1 0 1 0 5.7 7.11L10.59 12 5.7 16.89a1 1 0 1 0 1.41 1.41L12 13.41l4.89 4.89a1 1 0 0 0 1.41-1.41L13.41 12l4.89-4.89a1 1 0 0 0 0-1.4z"></path>'
	. '</svg></button>';

$panels_html = '';
if ( $items ) {
	$panels_html = '<div class="bw-faq__panels">';
	foreach ( $items as $it ) {
		if ( 'accordion' !== $it['behavior'] ) {
			continue; // link items have no panel
		}
		$panels_html .= '<div class="bw-faq__panel" id="' . esc_attr( $it['id'] ) . '" data-bw-faq-panel role="region"'
			. ' aria-label="' . esc_attr( $it['question'] ) . '">'
			. '<div class="bw-faq__panel-clip">'
			. '<div class="bw-faq__panel-inner">'
			. $close
			. '<div class="bw-faq__panel-body">' . $it['answer'] . '</div>'
			. '</div></div></div>';
	}
	$panels_html .= '</div>';
}

// The card+image form one equal-height row; the answer panels live OUTSIDE it as
// a separate unit below, so opening an answer never stretches the text card.
$media_html = '<div class="bw-faq__col bw-faq__col--media">' . $image_html . '</div>';
$text_col   = '<div class="bw-faq__col bw-faq__col--text">' . $card_html . '</div>';

// ── wrapper ──────────────────────────────────────────────────────────────────
$pad = (int) $pad_top . 'px ' . (int) $pad_right . 'px ' . (int) $pad_bottom . 'px ' . (int) $pad_left . 'px';
$style = '--bw-faq-primary:' . esc_attr( $primary ) . ';--bw-faq-pad:' . esc_attr( $pad ) . ';';

printf(
	'<div %s data-single-open="%s"><div class="bw-faq__row">%s%s</div>%s</div>',
	get_block_wrapper_attributes( array( 'class' => 'bw-faq bw-faq--img-' . $image_position, 'style' => $style ) ), // phpcs:ignore WordPress.Security.EscapeOutput
	$single_open ? '1' : '0', // phpcs:ignore WordPress.Security.EscapeOutput -- literal
	// Source order keeps the text card first (DOM/a11y); CSS order swaps columns
	// when the image is on the left.
	$text_col,    // phpcs:ignore WordPress.Security.EscapeOutput -- assembled from escaped parts
	$media_html,  // phpcs:ignore WordPress.Security.EscapeOutput -- image escaped
	$panels_html  // phpcs:ignore WordPress.Security.EscapeOutput -- answers are InnerBlocks (self-escaped)
);
