<?php

namespace ElementPack\Includes\Builder;

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

/**
 * Archive/search preview query switching for Theme Builder templates.
 *
 * Aligns with Elementor Pro Theme Builder Preview_Manager so widgets using
 * "Current Query" (Post Grid, Loop Grid, Archive Posts, etc.) render archive
 * content inside archive templates.
 */
class Builder_Preview_Manager {

	/**
	 * @var self|null
	 */
	private static $instance = null;

	public static function instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	private function __construct() {
		add_filter( 'element_pack/query/get_query_args/current_query', [ $this, 'filter_current_query' ], 15 );
		add_filter( 'elementor/query/get_query_args/current_query', [ $this, 'filter_current_query' ], 15 );
		add_filter( 'elementor/theme/posts_archive/query_posts/query_vars', [ $this, 'filter_current_query' ], 15 );
		add_filter( 'elementor_pro/query_control/get_query_args/current_query', [ $this, 'filter_current_query' ], 15 );

		add_action( 'elementor/template-library/before_get_source_data', [ $this, 'switch_to_preview_query' ] );
		add_action( 'elementor/template-library/after_get_source_data', [ $this, 'restore_current_query' ] );
		add_action( 'elementor/dynamic_tags/before_render', [ $this, 'switch_to_preview_query' ] );
		add_action( 'elementor/dynamic_tags/after_render', [ $this, 'restore_current_query' ] );
	}

	/**
	 * @param array<string, mixed> $query_vars Query vars.
	 * @return array<string, mixed>
	 */
	public function filter_current_query( $query_vars ) {
		$template_id = $this->get_active_builder_template_id();
		if ( ! $template_id || ! self::is_archive_like_template( $template_id ) ) {
			return $query_vars;
		}

		if ( ! $this->should_apply_preview_query( $template_id ) ) {
			return $query_vars;
		}

		$preview_args = Template_Conditions::get_preview_query_args( $template_id );
		if ( empty( $preview_args ) || ! is_array( $preview_args ) ) {
			return $query_vars;
		}

		return array_merge( (array) $query_vars, $preview_args );
	}

	public function switch_to_preview_query() {
		if ( ! class_exists( '\Elementor\Plugin' ) ) {
			return;
		}

		$template_id = $this->get_active_builder_template_id();
		if ( ! $template_id || ! self::is_archive_like_template( $template_id ) ) {
			return;
		}

		if ( ! $this->should_apply_preview_query( $template_id ) ) {
			return;
		}

		$preview_args = Template_Conditions::get_preview_query_args( $template_id );
		if ( empty( $preview_args ) ) {
			return;
		}

		\Elementor\Plugin::instance()->db->switch_to_query( $preview_args, true );
	}

	public function restore_current_query() {
		if ( ! class_exists( '\Elementor\Plugin' ) ) {
			return;
		}

		\Elementor\Plugin::instance()->db->restore_current_query();
	}

	/**
	 * @param int $template_id Template post ID.
	 */
	private function should_apply_preview_query( $template_id ) {
		if ( ! class_exists( '\Elementor\Plugin' ) ) {
			return false;
		}

		$elementor = \Elementor\Plugin::instance();

		if ( $elementor->editor->is_edit_mode() || $elementor->preview->is_preview_mode() ) {
			return true;
		}

		if ( wp_doing_ajax() && Builder_Template_Helper::isTemplateEditMode() ) {
			return true;
		}

		// Frontend Theme Builder preview URL (category archive + bdt_template_id).
		if ( Builder_Integration::instance()->is_theme_builder_frontend_preview_request() ) {
			return (int) Builder_Integration::instance()->current_template_id === (int) $template_id;
		}

		return false;
	}

	/**
	 * @return int
	 */
	private function get_active_builder_template_id() {
		// phpcs:disable WordPress.Security.NonceVerification.Recommended
		if ( ! empty( $_GET['bdt_template_id'] ) ) {
			$from_url = absint( wp_unslash( $_GET['bdt_template_id'] ) );
			if ( $from_url > 0 && Meta::POST_TYPE === get_post_type( $from_url ) ) {
				return $from_url;
			}
		}

		if ( ! empty( $_REQUEST['post'] ) ) {
			$from_request = absint( wp_unslash( $_REQUEST['post'] ) );
			if ( $from_request > 0 && Meta::POST_TYPE === get_post_type( $from_request ) ) {
				return $from_request;
			}
		}
		// phpcs:enable WordPress.Security.NonceVerification.Recommended

		global $post;
		if ( isset( $post->ID ) && Meta::POST_TYPE === get_post_type( $post->ID ) ) {
			return (int) $post->ID;
		}

		if ( Builder_Integration::instance()->current_template_id ) {
			return (int) Builder_Integration::instance()->current_template_id;
		}

		return 0;
	}

	/**
	 * @param int $template_id bdt-template-builder post ID.
	 */
	public static function is_archive_like_template( $template_id ) {
		$type = (string) get_post_meta( $template_id, Meta::TEMPLATE_TYPE, true );
		if ( '' === $type ) {
			return false;
		}

		$sep  = Builder_Template_Helper::separator();
		$slug = explode( $sep, $type, 2 );
		$slug = isset( $slug[1] ) ? $slug[1] : '';

		return in_array( $slug, [ 'archive', 'shop', 'search', 'category', 'tag', 'author', 'date' ], true );
	}
}

Builder_Preview_Manager::instance();
