<?php
/**
 * Fundraiser Breadcrumb Block
 *
 * Renders a semantic breadcrumb navigation trail for fundraiser pages.
 * The trail is built by walking up the post_parent chain, optionally prepending
 * a home link.
 *
 * Example trail:
 *   Individual: Home › Root Fundraiser › Team Name › This Fundraiser
 *   Root:       Home › Root Fundraiser
 *
 * The current item is rendered as plain text (not linked). All ancestor items
 * are linked. Returns an empty string on pages that are not an ambh_fundraiser.
 *
 * @package AmbassadorHub\Fundraisers\Blocks\FundraiserBreadcrumb
 */

namespace AmbassadorHub\Fundraisers\Blocks\FundraiserBreadcrumb;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use AmbassadorHub\Fundraisers\FundraisersModule;

/**
 * Fundraiser Breadcrumb block registration and server-side rendering.
 */
final class Block {

	// -------------------------------------------------------------------------
	// Boot
	// -------------------------------------------------------------------------

	/**
	 * Initialize the block.
	 *
	 * @return void
	 */
	public static function init(): void {
		add_action( 'init', array( self::class, 'register_block' ) );
	}

	// -------------------------------------------------------------------------
	// Registration
	// -------------------------------------------------------------------------

	/**
	 * Register block type, editor script, and styles.
	 *
	 * @return void
	 */
	public static function register_block(): void {
		$block_dir = AMBASSADOR_HUB_PATH . 'src/Fundraisers/Blocks/FundraiserBreadcrumb/';
		$block_url = AMBASSADOR_HUB_URL . 'src/Fundraisers/Blocks/FundraiserBreadcrumb/';

		$editor_handle = 'ambh-fundraiser-breadcrumb-editor';
		$editor_file   = $block_dir . 'index.js';
		if ( file_exists( $editor_file ) ) {
			wp_register_script(
				$editor_handle,
				$block_url . 'index.js',
				array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-block-editor', 'wp-components', 'wp-server-side-render' ),
				(string) filemtime( $editor_file ),
				true
			);
		}

		$style_file = $block_dir . 'style.css';
		wp_register_style(
			'ambh-fundraiser-breadcrumb',
			$block_url . 'style.css',
			array(),
			file_exists( $style_file ) ? (string) filemtime( $style_file ) : AMBASSADOR_HUB_VERSION
		);

		$block_args = array(
			'style'           => 'ambh-fundraiser-breadcrumb',
			'render_callback' => array( self::class, 'render_block' ),
		);

		if ( file_exists( $editor_file ) ) {
			$block_args['editor_script'] = $editor_handle;
		}

		register_block_type( $block_dir, $block_args );
	}

	// -------------------------------------------------------------------------
	// Rendering
	// -------------------------------------------------------------------------

	/**
	 * Server-side render callback.
	 *
	 * @param array $attributes Block attributes.
	 *
	 * @return string Rendered HTML or empty string.
	 */
	public static function render_block( array $attributes = array() ): string {

		if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
			return '<div class="ambh-breadcrumb-wrap ambh-block-preview">'
				. '<p class="ambh-block-preview__label">' . esc_html__( 'Breadcrumb', 'ambassadorhub' ) . '</p>'
				. '<p class="ambh-block-preview__meta">' . esc_html__( 'Trail renders on fundraiser pages.', 'ambassadorhub' ) . '</p>'
				. '</div>';
		}

		$current_id = (int) get_the_ID();
		$post_type  = get_post_type( $current_id );

		// Only render on fundraiser pages.
		if ( FundraisersModule::POST_TYPE !== $post_type ) {
			return '';
		}

		$show_home = $attributes['showHome'] ?? false;
		$separator = sanitize_text_field( $attributes['separator'] ?? '›' );

		$crumbs = self::build_fundraiser_crumbs( $current_id, (bool) $show_home );

		if ( count( $crumbs ) < 1 ) {
			return '';
		}

		ob_start();
		?>
		<nav class="ambh-breadcrumb-wrap" aria-label="<?php esc_attr_e( 'Breadcrumb', 'ambassadorhub' ); ?>">
			<ol class="ambh-breadcrumb" itemscope itemtype="https://schema.org/BreadcrumbList">
				<?php foreach ( $crumbs as $index => $crumb ) : ?>
					<?php $is_last = ( count( $crumbs ) - 1 === $index ); ?>
					<li class="ambh-breadcrumb__item<?php echo $is_last ? ' is-current' : ''; ?>"
						itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">

						<?php if ( ! $is_last && $crumb['url'] ) : ?>
							<a class="ambh-breadcrumb__link" href="<?php echo esc_url( $crumb['url'] ); ?>" itemprop="item">
								<span itemprop="name"><?php echo esc_html( $crumb['label'] ); ?></span>
							</a>
						<?php else : ?>
							<span class="ambh-breadcrumb__current" itemprop="name" aria-current="page">
								<?php echo esc_html( $crumb['label'] ); ?>
							</span>
						<?php endif; ?>

						<meta itemprop="position" content="<?php echo esc_attr( (string) ( $index + 1 ) ); ?>">

						<?php if ( ! $is_last ) : ?>
							<span class="ambh-breadcrumb__sep" aria-hidden="true"><?php echo esc_html( $separator ); ?></span>
						<?php endif; ?>

					</li>
				<?php endforeach; ?>
			</ol>
		</nav>
		<?php
		return ob_get_clean();
	}

	// -------------------------------------------------------------------------
	// Breadcrumb building
	// -------------------------------------------------------------------------

	/**
	 * Build crumbs for a fundraiser page.
	 *
	 * Trail: [Home ›] [Ancestor Fundraisers ›] Current Fundraiser
	 *
	 * @param int  $fundraiser_id Current fundraiser post ID.
	 * @param bool $show_home     Whether to prepend a Home crumb.
	 *
	 * @return array[] List of ['label' => string, 'url' => string|null] maps.
	 */
	private static function build_fundraiser_crumbs( int $fundraiser_id, bool $show_home ): array {
		$ancestry = self::get_ancestor_chain( $fundraiser_id );

		$crumbs = array();

		if ( $show_home ) {
			$crumbs[] = array(
				'label' => __( 'Home', 'ambassadorhub' ),
				'url'   => home_url( '/' ),
			);
		}

		// Ancestor fundraiser crumbs (root first, excludes current).
		foreach ( $ancestry as $ancestor_id ) {
			$crumbs[] = array(
				'label' => get_the_title( $ancestor_id ),
				'url'   => get_permalink( $ancestor_id ),
			);
		}

		// Current fundraiser (no link).
		$crumbs[] = array(
			'label' => get_the_title( $fundraiser_id ),
			'url'   => null,
		);

		return $crumbs;
	}

	/**
	 * Walk up the post_parent chain from $post_id and return ancestor IDs
	 * ordered from oldest (topmost) to newest (direct parent), excluding
	 * $post_id itself.
	 *
	 * @param int $post_id Starting post ID.
	 *
	 * @return int[] Ancestor IDs, oldest first.
	 */
	private static function get_ancestor_chain( int $post_id ): array {
		$ancestors = array();
		$current   = $post_id;
		$safety    = 0;

		while ( $safety++ < 20 ) {
			$parent_id = (int) wp_get_post_parent_id( $current );
			if ( ! $parent_id ) {
				break;
			}
			array_unshift( $ancestors, $parent_id );
			$current = $parent_id;
		}

		return $ancestors;
	}
}
