<?php

namespace Aepro;

use Elementor;
use Elementor\Plugin;
use Elementor\Post_CSS_File;
use WP_Query;
use Elementor\Core\Settings\Manager as SettingsManager;
use Aepro\Classes\CacheManager;

class Frontend {

	private static $_instance = null;

	private $_hook_templates = [];

	private $_page_type = null;

	private $_page_info = [];

	public static $_ae_post_block = 0;

	public static $_in_repeater_block = false;

	public static $_in_flexible_block = false;

	public static function instance() {
		if ( is_null( self::$_instance ) ) {
			self::$_instance = new self();
		}
		return self::$_instance;
	}

	private function __construct() {

		add_shortcode( 'AE_SEARCH_KEY', [ $this, 'ae_search_key' ] );
		add_shortcode( 'AE_SEARCH_COUNT', [ $this, 'ae_search_count' ] );
		add_action( 'init', [ $this, 'init' ] );

		add_filter( 'aepro_single_data', [ $this, 'apply_ae_single_post_template' ], 10, 1 );
		add_action( 'aepro_archive_data', [ $this, 'apply_ae_archive_template' ], 10, 1 );
		add_action( 'aepro_404', [ $this, 'apply_404_template' ] );
		add_action( 'ae_pro_search', [ $this, 'apply_search_template' ] );

		// remove theme hooks and action for single page/post
		add_action( 'template_redirect', [ $this, 'ae_template_hook' ] );

		add_action( 'template_redirect', [ $this, 'set_page_type' ] );
		add_action( 'template_redirect', [ $this, 'bind_template_for_hooks' ] );

		add_filter( 'ae_template_filter', [ $this, 'term_based_post_template' ] );
		//phpcs:ignore Squiz.PHP.CommentedOutCode.Found
		//add_filter( 'acf/pre_load_post_id', [ $this, 'acf_post_block_loop' ] );
	}

	public function acf_post_block_loop( $post_id ) {
		//phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
		if ( Frontend::$_ae_post_block != 0 ) {
			$post_id = Frontend::$_ae_post_block;
		}

		return $post_id;
	}

	public function ae_search_key() {
		if ( is_search() ) {
			return esc_html( get_search_query( false ) );
		} else {
			return 'Search Key';
		}
	}
	public function ae_search_count() {
		if ( is_search() ) {
			global $wp_query;
			return $wp_query->found_posts;
		} else {
			return '0';
		}
	}
	public function set_page_type() {

		if ( is_front_page() && is_home() ) {
			// Default Home
			$this->_page_type = 'home';
		} elseif ( is_front_page() ) {
			// Static Home
			$this->_page_type = 'home';
		} elseif ( is_home() ) {
			//Blog Page
			$this->_page_type = 'blog';
		} else {

			if ( is_singular() ) {
				$this->_page_type = 'single';
				return;
			}

			if ( is_archive() || is_category() || is_tag() ) {
				$this->_page_type = 'archive';
				$this->_page_info = get_queried_object();
				return;
			}

			if ( is_search() ) {
				$this->_page_type = 'search';
				return;
			}

			if ( is_404() ) {
				$this->_page_type = '404';
				return;
			}

			if ( is_author() ) {
				$this->_page_type = 'author';
			}
		}
	}
	public function init() {
		//phpcs:ignore Squiz.PHP.CommentedOutCode.Found
		//$this->bind_template_for_hooks();
	}

	public function render_shortcode( $atts ) {
		if ( ! isset( $atts['id'] ) || empty( $atts['id'] ) ) {
			return '';
		}

		$template_id = $atts['id'];

		return $this->render_insert_elementor( $template_id );
	}

	public function run_elementor_builder( $template_id ) {
		if ( ! isset( $template_id ) || empty( $template_id ) ) {
			return '';
		}
		$post_id = $template_id;
		ob_start();
		if ( Plugin::$instance->documents->get( $post_id )->is_built_with_elementor() ) {
			?>
			<?php //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
			<div class="ae_data elementor elementor-<?php echo $post_id; ?>" data-aetid="<?php echo $post_id; ?>">
				<?php //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
				<?php echo Elementor\Plugin::instance()->frontend->get_builder_content_for_display( $post_id ); ?>
			</div>
			<?php
		} else {
			echo esc_html__( 'Not a valid elementor page', 'ae-pro' );
		}
		$response = ob_get_contents();
		ob_end_clean();
		return $response;
	}

	public function render_insert_elementor( $template_id, $with_css = false ) {
		if ( ! isset( $template_id ) || empty( $template_id ) ) {
			return '';
		}

		$post_id = (int)$template_id;
		
		// check if page is elementor page

		$edit_mode = get_post_meta( $post_id, '_elementor_edit_mode', '' );

		$post_id = apply_filters( 'wpml_object_id', $post_id, 'ae_global_templates' );

		if(!is_numeric($post_id) || is_null(get_post($post_id))){
			return '';
		}

		ob_start();
		if ( Plugin::$instance->documents->get( $post_id )->is_built_with_elementor() ) {
			if ( !Plugin::$instance->preview->is_preview() && !Plugin::$instance->editor->is_edit_mode()) {
			?>
			<?php //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
			<div class="ae_data elementor elementor-<?php echo $post_id; ?>" data-aetid="<?php echo $post_id; ?>">
				<?php
			}
					//phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
					echo Elementor\Plugin::instance()->frontend->get_builder_content( $post_id, $with_css );

					add_action(
						'wp_footer',
						function() {

							if ( is_archive() ) {
								$elementor_frontend_config['settings'] = $this->get_init_settings();
								wp_localize_script( 'elementor-frontend', 'elementorFrontendConfig', $elementor_frontend_config['settings'] );
							}
						}
					);

			if ( !Plugin::$instance->preview->is_preview() && !Plugin::$instance->editor->is_edit_mode()) { ?>
			</div>
			<?php
			}
		} else {
			echo esc_html__( 'Not a valid elementor page', 'ae-pro' );
		}
		$response = ob_get_contents();
		ob_end_clean();
		return do_shortcode( $response );
	}

	private function print_ae_data( $sections ) {
		foreach ( $sections as $section_data ) {
			$section = new Elementor\Element_Section( $section_data );

			$section->print_element();
		}
	}

	public function bind_template_for_hooks() {
		$curr_post = $GLOBALS['post'];
		if ( is_admin() ) {
			return; }
		$hook_positions = Aepro::instance()->get_hook_positions();
		$hook_positions = apply_filters( 'ae_pro_filter_hook_positions', $hook_positions );

		$meta_query = [ 'relation' => 'OR' ];
		foreach ( $hook_positions as $key => $hook_position ) {
			if ( empty( $hook_position ) ) {
				continue;
			}
			$meta_query[] = [
				'key'     => 'ae_usage',
				'value'   => $key,
				'compare' => '=',
			];
		}

		$templates = CacheManager::instance()->get_templates_by_render_mode( 'normal' );

		if ( is_array( $templates ) && count( $templates ) ) {
			foreach ( $templates as $tid => $template ) {

				if ( ! $this->validate_hook( $tid, $curr_post ) ) {
					continue;
				}

				$hook_position = get_post_meta( $tid, 'ae_usage', true );
				if ( $hook_position === 'custom' ) {
					$hook_position = get_post_meta( $tid, 'ae_custom_usage_area', true );
				}
				if ( ! empty( $hook_position ) ) {
					$this->_hook_templates[ $hook_position ] = $tid;

					add_action(
						$hook_position,
						function() {
							$current_filter = current_filter();
							//phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
							echo $this->render_insert_elementor( $this->_hook_templates[ $current_filter ] );
						},
						10,
						1
					);
				}
			}
			wp_reset_postdata();
		}
	}

	/**
	 * Checks whether hook is valid for these page as per
	 * rules settings in AE Template
	 * @param $tid
	 * @param null $curr_post
	 * @return bool
	 */
	protected function validate_hook( $tid, $curr_post = null ) {
		$ae_apply_global = get_post_meta( $tid, 'ae_apply_global', true );
		if ( $ae_apply_global === 'true' ) {
			// applied globally without any restriction
			return true;
		}

		$ae_hook_apply_on = get_post_meta( $tid, 'ae_hook_apply_on' );

		switch ( $this->_page_type ) {
			case 'single':   // check if AE Template is allowed on current page type,
				if ( ! isset( $ae_hook_apply_on[0] ) || ! in_array( $this->_page_type, $ae_hook_apply_on[0], true ) ) {
					return false;
				}

								// check if post type allowed
								$ae_hook_post_types = get_post_meta( $tid, 'ae_hook_post_types' );

				if ( ! isset( $ae_hook_post_types[0] ) || ! in_array( $curr_post->post_type, $ae_hook_post_types[0], true ) ) {
					return false;
				}

								$ae_hook_posts_selected = get_post_meta( $tid, 'ae_hook_posts_selected', true );
								$ae_hook_posts_excluded = get_post_meta( $tid, 'ae_hook_posts_excluded', true );

				if ( ! empty( $ae_hook_posts_selected ) ) {
					$ae_hps = explode( ',', $ae_hook_posts_selected );
					if ( ! in_array( $curr_post->ID, $ae_hps, true ) ) {
						return false;
					}
				} elseif ( ! empty( $ae_hook_posts_excluded ) ) {
					$ae_hpe = explode( ',', $ae_hook_posts_excluded );
					if ( in_array( $curr_post->ID, $ae_hpe, true ) ) {
						return false;
					}
				}
				break;

			case 'archive':   // check if AE Template is allowed on current page type,
				if ( ! isset( $ae_hook_apply_on[0] ) || ! in_array( $this->_page_type, $ae_hook_apply_on[0], true ) ) {
					return false;
				}

								// check if taxonomy is allowed
								$ae_hook_taxonomies = get_post_meta( $tid, 'ae_hook_taxonomies' );
				if ( ! isset( $ae_hook_taxonomies[0] ) || ! in_array( $this->_page_info->taxonomy, $ae_hook_taxonomies[0], true ) ) {
					return false;
				}

								$ae_hook_terms_selected = get_post_meta( $tid, 'ae_hook_terms_selected', true );
								$ae_hook_terms_excluded = get_post_meta( $tid, 'ae_hook_terms_excluded', true );

				if ( ! empty( $ae_hook_terms_selected ) ) {
					$ae_hts = explode( ',', $ae_hook_terms_selected );
					if ( ! in_array( $this->_page_info->term_id, $ae_hts, true ) ) {
						return false;
					}
				}
				if ( ! empty( $ae_hook_terms_excluded ) ) {
					$ae_hte = explode( ',', $ae_hook_terms_excluded );
					if ( in_array( $this->_page_info->term_id, $ae_hte, true ) ) {
						return false;
					}
				}
				break;

			default:
				if ( ! isset( $ae_hook_apply_on[0] ) || ! in_array( $this->_page_type, $ae_hook_apply_on[0], true ) ) {
									return false;
				}
		}

		return true;
	}


	public function apply_ae_single_post_template( $content ) {
		global $post;
		if ( post_password_required( $post->ID ) ) {
			//phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			echo get_the_password_form( $post->ID );
			return $content;
		}
		$helper = new Helper();
		if ( ! is_single() && ! is_page() ) {
			return $content;
		}
		$post_id = $GLOBALS['post']->ID;

		if ( class_exists( 'WooCommerce' ) && $GLOBALS['post']->post_type === 'product' ) {
			$content  = '<div class="product">';
			$content .= $this->apply_ae_wc_single_template();
			$content .= '</div>';
			//phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			echo $content;
			return $content;
		}

		// check ae_post_template
		$ae_post_template = $helper->get_ae_active_post_template( $post_id, $GLOBALS['post']->post_type ); 
		if ( isset( $ae_post_template ) && is_numeric( $ae_post_template ) ) {
			$template_content = $this->render_insert_elementor( $ae_post_template );
			//phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			echo $template_content;
		}

		return $content;
	}

	public function apply_ae_archive_template( $content ) {
		$helper = new Helper();
		
		$ae_archive_template = $helper->get_ae_active_archive_template();
		
		if(is_null(get_post($ae_archive_template))){
			return $content;
		}
		
		if ( $ae_archive_template ) {
			$template_content = $this->render_insert_elementor( $ae_archive_template );
			//phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			echo $template_content;
		}

		return $content;
	}

	/**
	 * Remove hooks for post single page
	 */
	public function ae_template_hook() {
		$helper  = new Helper();
		$is_blog = $helper->is_blog();

		$theme_obj = Aepro::$_theme;

		if ( is_single() || is_page() ) {
			$post                   = get_post();
			$tid_post               = $helper->get_ae_active_post_template( $post->ID, $post->post_type );
			$post_is_canvas_enabled = $helper->is_canvas_enabled( $tid_post );
			$is_hf_enabled          = $helper->is_heder_footer_enabled( $tid_post );

			if ( ! $tid_post ) {
				return false;
			}

			if ( class_exists( 'WooCommerce' ) && $post->post_type === 'product' ) {
				remove_action( 'woocommerce_before_main_content', 'hestia_woocommerce_before_main_content' );
				add_filter(
					'body_class',
					function( $classes ) {
						$classes[] = 'aep-product';
						return $classes;
					}
				);
			}

			// Todo:: Move remove actions to separate file. Run only after theme detect.

			if ( $post_is_canvas_enabled ) {
				$theme_obj->set_use_canvas( true );
			}

			if ( $is_hf_enabled ) {
				$theme_obj->set_use_header_footer( true );
			}

			$theme_obj->manage_actions();

			// handle canvas template
			add_filter( 'template_include', [ $this, 'handle_canvas_template' ] );

		} elseif ( is_search() ) {
			$tid_search = $helper->has_search_template();
			if ( $tid_search ) {

				if ( $helper->is_canvas_enabled( $tid_search ) ) {
					$theme_obj->set_use_canvas( true );
				}

				if ( $helper->is_heder_footer_enabled( $tid_search ) ) {
					$theme_obj->set_use_header_footer( true );
				}

				$theme_obj->manage_actions();

			}
		} elseif ( is_archive() ) {
			$tid = $helper->get_ae_active_archive_template();
			if ( ! $tid && ! $is_blog ) {
				return false;
			}

			// check if canvas enabled
			if ( $helper->is_full_override( $tid ) ) {
				$theme_obj->set_override( 'full' );
			}
			if ( $helper->is_canvas_enabled( $tid ) ) {
				$theme_obj->set_use_canvas( true );
			}
			if ( $helper->is_heder_footer_enabled( $tid ) ) {
				$theme_obj->set_use_header_footer( true );
			}

			$theme_obj->manage_actions();

		} elseif ( $is_blog ) {
			$template_id = $helper->get_ae_active_archive_template();
			if ( ! $template_id ) {
				return false;
			}
			// is blog - force load archive template

			$theme_obj = Aepro::$_theme;
			$theme_obj->set_page_type( 'blog' );

			if ( $helper->is_full_override( $template_id ) ) {
				$theme_obj->set_override( 'full' );

				if ( $helper->is_canvas_enabled( $template_id ) ) {
					$theme_obj->set_use_canvas( true );
				}

				if ( $helper->is_heder_footer_enabled( $template_id ) ) {
					$theme_obj->set_use_header_footer( true );
				}
			}
			$theme_obj->manage_actions();

		} elseif ( is_404() ) {
			$tid_404 = $helper->has_404_template();
			if ( $tid_404 ) {

				if ( $helper->is_canvas_enabled( $tid_404 ) ) {
					$theme_obj->set_use_canvas( true );
				}

				if ( $helper->is_heder_footer_enabled( $tid_404 ) ) {
					$theme_obj->set_use_header_footer( true );
				}
				$theme_obj->manage_actions();

			}
		}

		// load_template i
		do_action( 'ae_remove_theme_single_page_actions' );
		return true;
	}

	public function handle_canvas_template( $template_include ) {
		if ( is_single() && strpos( $template_include, 'canvas.php' ) ) {
			$template_include = AE_PRO_PATH . 'includes/themes/canvas.php';
		}
		return $template_include;
	}

	public function apply_ae_wc_single_template() {
		global $product;
		$helper              = new Helper();
		$ae_product_template = $helper->get_ae_active_post_template( $product->get_id(), 'product' );

		if ( $ae_product_template !== '' && is_numeric( $ae_product_template ) ) {
			$template_content = $this->render_insert_elementor( $ae_product_template );
			$wc_sd            = new \WC_Structured_Data();
			$wc_sd->generate_product_data();
			return $template_content;
		}
	}

	public function apply_ae_wc_archive_template() {
		$helper              = new Helper();
		$ae_product_template = $helper->get_woo_archive_template();

		if ( $ae_product_template !== '' && is_numeric( $ae_product_template ) ) {
			$template_content = $this->render_insert_elementor( $ae_product_template );
			//phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			echo $template_content;
		}
	}

	public function apply_404_template() {
		$helper = new Helper();
		$tid    = $helper->has_404_template();
		if ( $tid ) {
			//phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			echo $this->render_insert_elementor( $tid );
		}
	}

	public function apply_search_template() {
		$helper = new Helper();
		$tid    = $helper->has_search_template();
		if ( $tid ) {
			//phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			echo $this->render_insert_elementor( $tid );
		}
	}

	public function term_based_post_template( $template_id ) {

		global $post;

		if ( is_singular() ) { // to make sure this code runs only for single posts

			$post_template = get_post_meta( $post->ID, 'ae_post_template', true );

			if ( $post_template === 'none' ) {
				return false;
			}

			if ( is_numeric( $post_template ) ) {
				return $template_id;
			}

			$tax_ob = get_object_taxonomies( $post );

			if ( ! count( $tax_ob ) ) {
				return $template_id;
			}

			$args = [
				'order'      => 'ASC',
				'hide_empty' => false,
				'fields'     => 'ids',
				'meta_query' => [
					[
						'key'     => 'ae_term_post_template',
						'compare' => '!=',
						'value'   => '',
					],
				],
			];

			$tax_list = [];
			foreach ( $tax_ob as $t_ob ) {
				$terms = wp_get_post_terms( $post->ID, $t_ob, $args );
				if ( count( $terms ) ) {
					foreach ( $terms as $term ) {
						$term_post_template = get_term_meta( $term, 'ae_term_post_template', true );
						if ( is_numeric( $term_post_template ) ) {
							$tax_list[] = $term_post_template;
						}
						if ( $term_post_template === 'none' ) {
							return false;
						}
					}
				}
			}
			if ( ! count( $tax_list ) ) {
				return $template_id;
			}
			rsort( $tax_list );
			$template_id_arr = apply_filters( 'ae_term_post_template', $tax_list );
			$template_id     = $template_id_arr[0];

		}
		return $template_id;
	}


	/**
	 * @return array
	 *
	 * Copied for Elementor Frontend as that was protected
	 */

	protected function get_init_settings() {
		$is_preview_mode = Plugin::$instance->preview->is_preview_mode( Plugin::$instance->preview->get_post_id() );

		$settings = [
			'environmentMode' => [
				'edit'      => $is_preview_mode,
				'wpPreview' => is_preview(),
			],
			'is_rtl'          => is_rtl(),
			'version'         => ELEMENTOR_VERSION,
			'urls'            => [
				'assets' => ELEMENTOR_ASSETS_URL,
			],
		];

		$settings['settings'] = SettingsManager::get_settings_frontend_config();

		if ( is_singular() ) {
			$post             = get_post();
			$settings['post'] = [
				'id'      => $post->ID,
				'title'   => $post->post_title,
				'excerpt' => $post->post_excerpt,
			];
		} else {
			$settings['post'] = [
				'id'      => 0,
				'title'   => wp_get_document_title(),
				'excerpt' => '',
			];
		}

		if ( $is_preview_mode ) {
			$elements_manager = Plugin::$instance->elements_manager;

			$elements_frontend_keys = [
				'section' => $elements_manager->get_element_types( 'section' )->get_frontend_settings_keys(),
				'column'  => $elements_manager->get_element_types( 'column' )->get_frontend_settings_keys(),
			];

			$elements_frontend_keys += Plugin::$instance->widgets_manager->get_widgets_frontend_settings_keys();

			$settings['elements'] = [
				'data'         => (object) [],
				'editSettings' => (object) [],
				'keys'         => $elements_frontend_keys,
			];
		}

		if ( is_user_logged_in() ) {
			$user = wp_get_current_user();

			if ( ! empty( $user->roles ) ) {
				$settings['user'] = [
					'roles' => $user->roles,
				];
			}
		}

		return $settings;
	}

}

Frontend::instance();
