<?php
/**
 * Query Loop hierarchy filter integration.
 *
 * @package AmbassadorHub\QueryLoop
 */

namespace AmbassadorHub\QueryLoop;

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

/**
 * Adds hierarchy controls to the Query Loop block and applies them to frontend queries.
 */
final class HierarchyFilter {
	/**
	 * Editor script handle.
	 *
	 * @var string
	 */
	private const SCRIPT_HANDLE = 'ambassadorhub-query-loop-hierarchy-filter';

	/**
	 * Initialize hooks.
	 *
	 * @return void
	 */
	public static function init(): void {
		add_action( 'enqueue_block_editor_assets', array( self::class, 'enqueue_block_editor_assets' ) );
		add_filter( 'query_loop_block_query_vars', array( self::class, 'filter_query_loop_block_query_vars' ), 10, 3 );
		add_filter( 'register_block_type_args', array( self::class, 'extend_block_type_args' ), 10, 2 );
	}

	/**
	 * Register and enqueue the editor script for the Query Loop extension.
	 *
	 * @return void
	 */
	public static function enqueue_block_editor_assets(): void {
		$asset_file  = AMBASSADOR_HUB_PATH . 'src/QueryLoop/build/editor.asset.php';
		$script_file = AMBASSADOR_HUB_PATH . 'src/QueryLoop/build/editor.js';

		if ( ! file_exists( $asset_file ) || ! file_exists( $script_file ) ) {
			return;
		}

		$asset = require $asset_file;

		wp_register_script(
			self::SCRIPT_HANDLE,
			AMBASSADOR_HUB_URL . 'src/QueryLoop/build/editor.js',
			$asset['dependencies'] ?? array(),
			$asset['version'] ?? AMBASSADOR_HUB_VERSION,
			true
		);

		wp_set_script_translations(
			self::SCRIPT_HANDLE,
			'ambassadorhub',
			AMBASSADOR_HUB_PATH . 'languages'
		);

		wp_enqueue_script( self::SCRIPT_HANDLE );
	}

	/**
	 * Extend core/query's providesContext to include hierarchyFilter and
	 * hierarchyParentId, and extend core/post-template's usesContext so
	 * those values are accessible in the query_loop_block_query_vars filter.
	 *
	 * @param array  $args Block type registration arguments.
	 * @param string $name Block type name.
	 *
	 * @return array
	 */
	public static function extend_block_type_args( array $args, string $name ): array {
		if ( 'core/query' === $name ) {
			$args['provides_context']['hierarchyFilter']   = 'hierarchyFilter';
			$args['provides_context']['hierarchyParentId'] = 'hierarchyParentId';
		}

		if ( 'core/post-template' === $name ) {
			$args['uses_context'][] = 'hierarchyFilter';
			$args['uses_context'][] = 'hierarchyParentId';
		}

		return $args;
	}

	/**
	 * Apply hierarchy settings from the Query Loop block to the query vars.
	 *
	 * hierarchyFilter and hierarchyParentId are stored as top-level attributes
	 * on core/query and flow to core/post-template via extends providesContext
	 * (registered above), where they are available as $block->context keys.
	 *
	 * @param array     $query  Query vars used for the current Query Loop request.
	 * @param \WP_Block $block  Parsed block instance (core/post-template).
	 * @param int       $_page  Current paged result (not used).
	 *
	 * @return array
	 */
	public static function filter_query_loop_block_query_vars( array $query, \WP_Block $block, int $_page ): array { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed -- required by query_loop_block_query_vars filter signature.
		$hierarchy_filter = isset( $block->context['hierarchyFilter'] ) ? (string) $block->context['hierarchyFilter'] : 'all';
		$parent_id        = isset( $block->context['hierarchyParentId'] ) ? absint( $block->context['hierarchyParentId'] ) : 0;

		switch ( $hierarchy_filter ) {
			case 'parents_only':
				$query['post_parent'] = 0;
				break;

			case 'children_only':
				$query['post_parent__not_in'] = array( 0 );
				break;

			case 'current':
				$current_id = is_singular() ? get_queried_object_id() : 0;
				if ( $current_id > 0 ) {
					$query['post_parent'] = $current_id;
				}
				break;

			case 'parent_of_current':
				$current_post = is_singular() ? get_queried_object() : null;
				if ( $current_post instanceof \WP_Post && $current_post->post_parent > 0 ) {
					$query['post__in']       = array( $current_post->post_parent );
					$query['posts_per_page'] = 1;
				} else {
					// No parent — return nothing.
					$query['post__in'] = array( 0 );
				}
				break;

			case 'specific':
				if ( $parent_id > 0 ) {
					$query['post_parent'] = $parent_id;
				}
				break;

			case 'all':
			default:
				break;
		}

		return $query;
	}
}
