<?php
/**
 * DESCRIPTION: Registers the Nemtly Events query loop variation, handles custom query
 * modifications for meta sorting, event type filtering, and past events toggle.
 *
 * @package NemtlyBooking\Blocks
 */

namespace NemtlyBooking\Blocks;

use NemtlyBooking\Core\Event_Creator;

/**
 * Query Loop Variation Block class
 *
 * @since PBOOKING_SINCE
 */
class Query_Loop_Variation extends Abstract_Block {

	/**
	 * Block Name
	 *
	 * @var string
	 */
	protected $block_name = 'events-loop';

	/**
	 * Register the block
	 *
	 * @since PBOOKING_SINCE
	 */
	public function register() {
		$script_asset_path = NEMTLY_BOOKING_PATH . 'assets/js/blocks/events-loop.asset.php';
		$script_asset_file = file_exists( $script_asset_path ) ? require $script_asset_path : [
			'dependencies' => [],
			'version'      => '1.0.0',
		];

		wp_register_script(
			'nemtly-events-loop',
			NEMTLY_BOOKING_URL . 'assets/js/blocks/events-loop.js',
			$script_asset_file['dependencies'],
			$script_asset_file['version'],
			true
		);

		add_action(
			'enqueue_block_editor_assets',
			function () {
				wp_enqueue_script( 'nemtly-events-loop' );
			}
		);

		add_filter( 'query_loop_block_query_vars', [ $this, 'modify_query_vars' ], 10, 3 );
		add_filter( 'rest_nemtly_event_collection_params', [ $this, 'add_rest_orderby_params' ] );
		add_filter( 'rest_nemtly_event_query', [ $this, 'handle_rest_orderby' ], 10, 2 );
	}

	/**
	 * Modify query vars for the Nemtly Events variation on the frontend.
	 *
	 * Handles meta-based sorting by event date, event type filtering,
	 * and hiding past events.
	 *
	 * @since PBOOKING_SINCE
	 *
	 * @param array     $query   The query vars.
	 * @param \WP_Block $block   The block instance.
	 * @param int       $page    The current page.
	 *
	 * @return array Modified query vars.
	 */
	public function modify_query_vars( $query, $block, $page ) {
		$post_type = $block->context['query']['postType'] ?? '';

		if ( 'nemtly_event' !== $post_type ) {
			return $query;
		}

		// Sort by event date meta field.
		$query['orderby']  = 'meta_value';
		$query['meta_key'] = Event_Creator::META_EVENT_DATE; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key

		$block_query = $block->context['query'] ?? [];

		// Initialize meta_query if needed.
		if ( ! isset( $query['meta_query'] ) ) {
			$query['meta_query'] = []; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
		}

		// Filter by event type if specified.
		$event_type = $block_query['nemtlyEventType'] ?? '';

		if ( ! empty( $event_type ) ) {
			$query['meta_query'][] = [
				'key'     => Event_Creator::META_EVENT_TYPE,
				'value'   => sanitize_text_field( $event_type ),
				'compare' => '=',
			];
		}

		// Hide past events if toggled on.
		$hide_past = $block_query['nemtlyHidePastEvents'] ?? false;

		if ( $hide_past ) {
			$query['meta_query'][] = [
				'key'     => Event_Creator::META_EVENT_DATE,
				'value'   => current_time( 'Y-m-d' ),
				'compare' => '>=',
				'type'    => 'DATE',
			];
		}

		return $query;
	}

	/**
	 * Add custom orderby params to the REST API collection params.
	 *
	 * This allows the block editor preview to sort by meta_value.
	 *
	 * @since PBOOKING_SINCE
	 *
	 * @param array $params The collection params.
	 *
	 * @return array Modified params.
	 */
	public function add_rest_orderby_params( $params ) {
		if ( isset( $params['orderby']['enum'] ) ) {
			$params['orderby']['enum'][] = 'meta_value';
		}

		return $params;
	}

	/**
	 * Handle meta_value orderby in REST API queries for editor preview.
	 *
	 * @since PBOOKING_SINCE
	 *
	 * @param array            $args    The query args.
	 * @param \WP_REST_Request $request The REST request.
	 *
	 * @return array Modified query args.
	 */
	public function handle_rest_orderby( $args, $request ) {
		if ( 'meta_value' === $request->get_param( 'orderby' ) ) {
			$args['orderby']  = 'meta_value';
			$args['meta_key'] = Event_Creator::META_EVENT_DATE; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
		}

		return $args;
	}

	/**
	 * Render the block
	 *
	 * @since PBOOKING_SINCE
	 *
	 * @param array     $attributes Block attributes.
	 * @param string    $content    Block content.
	 * @param \WP_Block $block      Block instance.
	 *
	 * @return string
	 */
	public function render( $attributes, $content, $block ) {
		// This is a variation, no render callback needed.
		return '';
	}
}
