<?php

/**
 * Theme Builder
 *
 * Package: ZyreAddons
 * @since 1.0.0
 */

namespace VertexMediaLLC\ZyreElementorAddons\Modules\ThemeBuilder;

use VertexMediaLLC\ZyreElementorAddons\Dashboard;
use Elementor\Core\Settings\Manager;

defined( 'ABSPATH' ) || die();

class Module {
	public static $instance = null;

	const POST_TYPE = 'zyreladdons_library';
	const TAB_BASE = 'edit.php?post_type=' . self::POST_TYPE;

	private $cache;

	protected $current_theme;
	protected $current_location;

	protected $templates;
	public $singular_template;
	public $single_template;
	public $header_template;
	public $footer_template;
	protected $current_template;

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

		return self::$instance;
	}

	public function __construct() {
		$this->include_files();

		add_action( 'wp', [ $this, 'hooks' ] );
		$this->cache = new Conditions_Cache();

		add_filter( 'query_vars', [ $this, 'add_query_vars' ] );
		add_filter( 'views_edit-' . self::POST_TYPE, [ $this, 'render_admin_tabs' ] );
		// This module may itself be instantiated during `init`, so register immediately in that case.
		if ( doing_action( 'init' ) || did_action( 'init' ) ) {
			$this->create_post_type();
		} else {
			add_action( 'init', [ $this, 'create_post_type' ], 9 );
		}
		register_activation_hook( ZYRELADDONS__FILE__, [ $this, 'on_plugin_activation' ] );
		add_action( 'admin_menu', [ $this, 'modify_menu' ], 90 );
		add_action( 'pre_get_posts', [ $this, 'set_meta_query_to_posts_query' ] );

		add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );

		add_action( 'elementor/editor/after_enqueue_scripts', [ $this, 'edit_template_condition_modal' ], 10, 2 );
		add_action( 'elementor/editor/after_enqueue_scripts', [ $this, 'template_element_scripts' ], 9 );

		add_filter( 'elementor/document/config', [ $this, 'document_config_title' ], 10, 2 );
		add_action( 'admin_action_zyreladdons_library_new_post', [ $this, 'admin_action_new_post' ] );

		add_action( 'current_screen', function () {
			$current_screen = get_current_screen();
			if ( ! $current_screen || ! strstr( $current_screen->post_type, self::POST_TYPE ) ) {
				return;
			}
			add_action( 'in_admin_header', function () {
				$this->render_admin_top_bar();
			} );
			add_action( 'in_admin_footer', [ $this, 'add_new_template' ], 10, 2 );
		} );

		add_action( 'manage_' . self::POST_TYPE . '_posts_columns', [ $this, 'admin_columns_headers' ] );
		add_action( 'manage_' . self::POST_TYPE . '_posts_custom_column', [ $this, 'admin_columns_content' ], 10, 2 );

		add_filter( 'zyreladdons/conditions/sub_name_key_pairs', [ $this, 'set_sub_name_key_pairs' ] );

		// Override Single Post Template
		add_filter( 'template_include', [ $this, 'template_include' ], 999 );
		add_action( 'zyreladdons_theme_builder_render', [ $this, 'single_blog_content_elementor' ], 999 );

		add_action( 'elementor/elements/categories_registered', [ $this, 'add_elementor_widget_categories' ] );
	}

	public function include_files() {
		include_once ZYRELADDONS_DIR_PATH . 'modules/theme-builder/conditions-cache.php';
		include_once ZYRELADDONS_DIR_PATH . 'modules/theme-builder/conditions-manager.php';
		include_once ZYRELADDONS_DIR_PATH . 'modules/theme-builder/theme-support.php';
		include_once ZYRELADDONS_DIR_PATH . 'modules/theme-builder/compatibility/astra.php';
		include_once ZYRELADDONS_DIR_PATH . 'modules/theme-builder/compatibility/bbtheme.php';
		include_once ZYRELADDONS_DIR_PATH . 'modules/theme-builder/compatibility/generatepress.php';
		include_once ZYRELADDONS_DIR_PATH . 'modules/theme-builder/compatibility/genesis.php';
		include_once ZYRELADDONS_DIR_PATH . 'modules/theme-builder/compatibility/oceanwp.php';
		include_once ZYRELADDONS_DIR_PATH . 'modules/theme-builder/compatibility/twenty-nineteen.php';
	}

	protected function get_full_data( $post ) {
		if ( null !== $post ) {
			$tmpl_type = get_post_meta( $post->ID, 'zyreladdons_library_type', true );
			$tpl_cond = get_post_meta( $post->ID, 'zyreladdons_display_cond', true );

			$parsed_cond = $this->parse_condition( $tpl_cond );
			$conditions = [];

			if ( is_array( $tpl_cond ) ) {
				foreach ( $tpl_cond as $condition ) {
					$conditions[] = $this->parse_condition( $condition );
				}
			}

			return array_merge( (array) $post, [
				'type' => $tmpl_type,
				'condition_a' => $parsed_cond['name'],
				'condition_singular' => $parsed_cond['sub_name'],
				'condition_singular_id' => $parsed_cond['sub_id'],
			]);
		}
	}

	protected function load_template_element( $filters ) {
		$template_id = [];

		if ( null !== $this->templates ) {
			foreach ( $this->templates as $template ) {
				$template = $this->get_full_data( $template );
				$match_found = true;

				// WPML Language Check
				if ( defined( 'ICL_LANGUAGE_CODE' ) ) :
					$current_lang = apply_filters( 'wpml_post_language_details', null, $template['ID'] );

					if ( ! empty( $current_lang ) && ! $current_lang['different_language'] && ( ICL_LANGUAGE_CODE === $current_lang['language_code'] ) ) :
						$template_id[ $template['type'] ] = $template['ID'];
					endif;
				endif;

				foreach ( $filters as $filter ) {
					if ( 'condition_singular_id' === $filter['key'] ) {
						$ids = explode( ',', $template[ $filter['key'] ] );
						if ( ! in_array( $filter['value'], $ids, true ) ) {
							$match_found = false;
						}
					} elseif ( $template[ $filter['key'] ] !== $filter['value'] ) {
						$match_found = false;
					}
					if ( 'condition_a' === $filter['key'] && 'singular' === $template[ $filter['key'] ] && count( $filters ) < 2 ) {
						$match_found = false;
					}
				}

				if ( true === $match_found ) {
					if ( 'header' === $template['type'] ) {
						$this->header_template = isset( $template_id['header'] ) ? $template_id['header'] : $template['ID'];
					}
					if ( 'footer' === $template['type'] ) {
						$this->footer_template = isset( $template_id['footer'] ) ? $template_id['footer'] : $template['ID'];
					}
					if ( 'single' === $template['type'] ) {
						$this->single_template = isset( $template_id['single'] ) ? $template_id['single'] : $template['ID'];
					}
				}
			}
		}
	}

	protected function the_filter() {
		$arg = [
			'posts_per_page'   => -1,
			'orderby'          => 'id',
			'order'            => 'DESC',
			'post_status'      => 'publish',
			'post_type'        => self::POST_TYPE,
		];

		$this->templates = get_posts( $arg );

		if ( empty( $this->templates ) ) {
			$this->templates = null;
		}

		// more conditions can be triggered at once
		// don't use switch case
		// may impliment and callable by dynamic class in future

		// entire site
		if ( ! is_admin() ) {
			$filters = [
				[
					'key'     => 'condition_a',
					'value'   => 'general',
				],
			];
			$this->load_template_element( $filters );
		}

		// all pages, all posts, 404 page
		if ( is_page() ) {
			$filters = [
				[
					'key'     => 'condition_a',
					'value'   => 'singular',
				],
				[
					'key'     => 'condition_singular',
					'value'   => 'all_pages',
				],
			];
			$this->load_template_element( $filters );
		} elseif ( is_single() ) {
			$filters = [
				[
					'key'     => 'condition_a',
					'value'   => 'posts',
				],
			];
			$this->load_template_element( $filters );
		} elseif ( is_404() ) {
			$filters = [
				[
					'key'     => 'condition_a',
					'value'   => 'singular',
				],
				[
					'key'     => 'condition_singular',
					'value'   => '404page',
				],
			];
			$this->load_template_element( $filters );
		}
	}

	public static function template_ids() {
		$cached = wp_cache_get( 'zyreladdons_template_ids' );
		if ( false !== $cached ) {
			return $cached;
		}

		$instance = self::instance();
		$instance->the_filter();

		$ids = [
			$instance->header_template,
			$instance->footer_template,
			$instance->singular_template,
		];

		if ( null !== $instance->header_template ) {
			if ( class_exists( '\Elementor\Core\Files\CSS\Post' ) ) {
				$css_file = new \Elementor\Core\Files\CSS\Post( $instance->header_template );
				$css_file->enqueue();
			}
		}

		if ( null !== $instance->footer_template ) {
			if ( class_exists( '\Elementor\Core\Files\CSS\Post' ) ) {
				$css_file = new \Elementor\Core\Files\CSS\Post( $instance->footer_template );
				$css_file->enqueue();
			}
		}

		wp_cache_set( 'zyreladdons_template_ids', $ids );
		return $ids;
	}

	public function hooks() {
		$this->current_template = basename( get_page_template_slug() );
		if ( 'elementor_canvas' === $this->current_template ) {
			return;
		}

		$this->current_theme = get_template();

		switch ( $this->current_theme ) {
			case 'astra':
				new Compatibility\Astra();
				break;

			case 'bb-theme':
			case 'bb-theme-child':
				new Compatibility\Bbtheme();
				break;

			case 'generatepress':
			case 'generatepress-child':
				new Compatibility\Generatepress();
				break;

			case 'genesis':
			case 'genesis-child':
				new Compatibility\Genesis();
				break;

			case 'oceanwp':
			case 'oceanwp-child':
				new Compatibility\Oceanwp();
				break;

			case 'twentynineteen':
				new Compatibility\TwentyNineteen();
				break;

			default:
				new Theme_Support();
				break;
		}
	}

	// Modify the existing admin menu
	public function modify_menu() {
		add_submenu_page(
			Dashboard::PAGE_SLUG, // Parent slug
			__( 'Theme Builder', 'zyre-elementor-addons' ), // Page title
			__( 'Theme Builder', 'zyre-elementor-addons' ), // Menu title
			'manage_options',
			'edit.php?post_type=' . self::POST_TYPE,
			false
		);
	}

	public function add_query_vars( $vars ) {
		$vars[] = 'zyreladdons_library_type';
		return $vars;
	}

	public function enqueue_assets() {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		wp_enqueue_style(
			'zyreladdons-admin',
			ZYRELADDONS_ASSETS . 'admin/css/admin.css',
			null,
			ZYRELADDONS_VERSION
		);

		wp_enqueue_script(
			'zyreladdons-micromodal',
			ZYRELADDONS_ASSETS . 'libs/micromodal/micromodal.min.js',
			[],
			ZYRELADDONS_VERSION,
			true
		);

		wp_enqueue_script(
			'zyreladdons-admin',
			ZYRELADDONS_ASSETS . 'admin/js/admin.js',
			[ 'jquery', 'zyreladdons-micromodal' ],
			ZYRELADDONS_VERSION,
			true
		);
	}

	public function edit_template_condition_modal() {
		if ( self::POST_TYPE === get_post_type() ) {
			ob_start();
			include ZYRELADDONS_DIR_PATH . 'modules/theme-builder/templates/template-conditions.php';
			echo ob_get_clean(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		}
	}

	public function template_element_scripts() {
		if ( self::POST_TYPE === get_post_type() ) {
			wp_enqueue_style(
				'zyreladdons-template-modal',
				ZYRELADDONS_DIR_URL . 'modules/theme-builder/assets/css/template-modal.css',
				[ 'elementor-editor' ],
				ZYRELADDONS_VERSION
			);

			$theme = Manager::get_settings_managers( 'editorPreferences' )->get_model()->get_settings( 'ui_theme' );

			if ( 'light' !== $theme ) {
				$media_queries = 'all';

				if ( 'auto' === $theme ) {
					$media_queries = '(prefers-color-scheme: dark)';
				}

				wp_enqueue_style(
					'zyreladdons-template-modal-dark',
					ZYRELADDONS_DIR_URL . 'modules/theme-builder/assets/css/template-modal-dark.css',
					[ 'zyreladdons-template-modal' ],
					ZYRELADDONS_VERSION,
					$media_queries
				);
			}

			wp_enqueue_script(
				'zyreladdons-template-modal',
				ZYRELADDONS_DIR_URL . 'modules/theme-builder/assets/js/template-modal.js',
				[ 'jquery', 'zyreladdons-editor' ],
				ZYRELADDONS_VERSION,
				true
			);

			wp_localize_script('zyreladdons-template-modal', 'zyreTemplateInfo', [
				'postType' => self::POST_TYPE,
				'templateType' => get_post_meta( get_the_ID(), 'zyreladdons_library_type', true ),
				'postId' => get_the_ID(),
			]);

			wp_enqueue_script(
				'zyreladdons-micromodal',
				ZYRELADDONS_ASSETS . 'libs/micromodal/micromodal.min.js',
				[],
				ZYRELADDONS_VERSION,
				true
			);

			$localize_data = [
				'conditionsSubNames' => apply_filters( 'zyreladdons/conditions/sub_name_key_pairs', [] ),
			];

			wp_localize_script(
				'zyreladdons-template-modal',
				'ZyreTemplate',
				$localize_data
			);
		}
	}

	// Register custom post type
	public function create_post_type() {
		$labels = [
			'name'                  => _x( 'Theme Builder', 'Post Type General Name', 'zyre-elementor-addons' ),
			'singular_name'         => _x( 'Theme Builder', 'Post Type Singular Name', 'zyre-elementor-addons' ),
			'menu_name'             => _x( 'Theme Builder', 'Admin Menu text', 'zyre-elementor-addons' ),
			'name_admin_bar'        => _x( 'Theme Builder', 'Add New on Toolbar', 'zyre-elementor-addons' ),
			'archives'              => __( 'Theme Builder Archives', 'zyre-elementor-addons' ),
			'attributes'            => __( 'Theme Builder Attributes', 'zyre-elementor-addons' ),
			'parent_item_colon'     => __( 'Parent Theme Builder:', 'zyre-elementor-addons' ),
			'all_items'             => __( 'All Theme Builder', 'zyre-elementor-addons' ),
			'add_new_item'          => __( 'Add New Theme Builder', 'zyre-elementor-addons' ),
			'add_new'               => __( 'Add New', 'zyre-elementor-addons' ),
			'new_item'              => __( 'New Theme Builder', 'zyre-elementor-addons' ),
			'edit_item'             => __( 'Edit Theme Builder', 'zyre-elementor-addons' ),
			'update_item'           => __( 'Update Theme Builder', 'zyre-elementor-addons' ),
			'view_item'             => __( 'View Theme Builder', 'zyre-elementor-addons' ),
			'view_items'            => __( 'View Theme Builder', 'zyre-elementor-addons' ),
			'search_items'          => __( 'Search Theme Builder', 'zyre-elementor-addons' ),
			'not_found'             => __( 'Not found', 'zyre-elementor-addons' ),
			'not_found_in_trash'    => __( 'Not found in Trash', 'zyre-elementor-addons' ),
			'featured_image'        => __( 'Featured Image', 'zyre-elementor-addons' ),
			'set_featured_image'    => __( 'Set featured image', 'zyre-elementor-addons' ),
			'remove_featured_image' => __( 'Remove featured image', 'zyre-elementor-addons' ),
			'use_featured_image'    => __( 'Use as featured image', 'zyre-elementor-addons' ),
			'insert_into_item'      => __( 'Insert into Theme Builder', 'zyre-elementor-addons' ),
			'uploaded_to_this_item' => __( 'Uploaded to this Theme Builder', 'zyre-elementor-addons' ),
			'items_list'            => __( 'Theme Builder list', 'zyre-elementor-addons' ),
			'items_list_navigation' => __( 'Theme Builder list navigation', 'zyre-elementor-addons' ),
			'filter_items_list'     => __( 'Filter Theme Builder list', 'zyre-elementor-addons' ),
		];

		$args = [
			'label'               => __( 'Theme Builder', 'zyre-elementor-addons' ),
			'description'         => __( 'Build your website header, footer, single page/post template and more.', 'zyre-elementor-addons' ),
			'labels'              => $labels,
			'supports'            => [ 'title', 'elementor' ],
			'taxonomies'          => [],
			'public'              => true,
			'show_ui'             => true,
			'show_in_menu'        => '',
			'show_in_admin_bar'   => false,
			'show_in_nav_menus'   => false,
			'can_export'          => true,
			'has_archive'         => false,
			'hierarchical'        => false,
			'exclude_from_search' => true,
			'capability_type'     => 'page',
			'map_meta_cap'        => true,
		];

		register_post_type( self::POST_TYPE, $args );
	}

	// Fire actions on plugin activation
	public function on_plugin_activation() {
		// Ensure post type is registered before flushing
		$this->create_post_type();

		// Then flush rewrite rules
		flush_rewrite_rules();
	}

	public function set_meta_query_to_posts_query( $query ) {
		/**
		 * No use on front
		 * pre get posts runs everywhere
		 * even if you test $pagenow after, bail as soon as possible
		 */
		if ( ! is_admin() ) {
			return;
		}

		global $pagenow;

		// use $query parameter instead of global $post_type
		if ( 'edit.php' === $pagenow && self::POST_TYPE === $query->query['post_type'] ) {

			if ( isset( $_GET['zyreladdons_library_type'] ) ) {
				$library_type = sanitize_text_field( wp_unslash( $_GET['zyreladdons_library_type'] ) );

				$meta_query = array(
					array(
						'key' => 'zyreladdons_library_type',
						'value' => $library_type,
						'compare' => '=',
					),
				);

				$query->set( 'meta_query', $meta_query );
				$query->set( 'meta_key', 'zyreladdons_library_type' );
			}
		}
	}

	// Render top bar
	private function render_admin_top_bar() {
		?>
		<div class="zyre-admin-top-bar-root">
			<div class="zyre-admin-top-bar">
				<div class="zyre-admin-top-bar-branding">
					<div class="zyre-admin-top-bar-branding-logo">
						<img src="<?php echo esc_attr( zyreladdons_get_b64_3dicon() ); ?>" alt="" width="46">
					</div>
					<h1 class="zyre-admin-top-bar-branding-title"><?php esc_html_e( 'Theme Builder', 'zyre-elementor-addons' ); ?></h1>
				</div>
				<div class="zyre-admin-top-bar-buttons">
					<a class="button-secondary button-large" id="zyre-template-library-add-new" href="<?php echo esc_url( admin_url( 'post-new.php?post_type=zyreladdons_library' ) ); ?>"><?php esc_html_e( 'Add New', 'zyre-elementor-addons' ); ?></a>
				</div>
			</div>
		</div>
		<?php
	}

	public static function get_template_types() {
		$template_types = [
			'header'  => esc_html__( 'Header', 'zyre-elementor-addons' ),
			'footer'  => esc_html__( 'Footer', 'zyre-elementor-addons' ),
			'single'  => esc_html__( 'Single', 'zyre-elementor-addons' ),
			'archive' => esc_html__( 'Archive', 'zyre-elementor-addons' ),
		];

		return apply_filters( 'zyreladdons/theme-builder/template-types', $template_types );
	}

	public function add_new_template() {
		ob_start();
		include ZYRELADDONS_DIR_PATH . 'modules/theme-builder/templates/new-template.php';
		echo ob_get_clean(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
	}

	// Render tabs in the edit page
	public function render_admin_tabs( $views ) {
		$get_active = get_query_var( 'zyreladdons_library_type' );
		?>
		<div id="zyre-template-library-tabs-wrapper" class="nav-tab-wrapper">
			<a class="nav-tab <?php echo ! $get_active ? 'nav-tab-active' : ''; ?>" href="<?php echo esc_url( admin_url( self::TAB_BASE ) ); ?>"><?php esc_html_e( 'All', 'zyre-elementor-addons' ); ?></a>
			<?php
			foreach ( self::get_template_types() as $key => $value ) {
				$active = ( $get_active === $key ) ? 'nav-tab-active' : '';
				$admin_filter_url = admin_url( self::TAB_BASE . '&zyreladdons_library_type=' . $key );
                $nav_tab_link = '<a class="nav-tab ' . $active . '" href="' . esc_url( $admin_filter_url ) . '">' . esc_html( $value ) . '</a>';
				echo wp_kses_post( $nav_tab_link );
			}
			?>
		</div>
		<br>
		<?php
		return $views;
	}

	protected function parse_condition( $condition ) {
		$condition = is_array( $condition ) ? $condition[0] : $condition;
		list( $type, $name, $sub_name, $sub_id ) = array_pad( explode( '/', $condition ), 4, '' );
		return compact( 'type', 'name', 'sub_name', 'sub_id' );
	}

	/**
	 * @param Theme_Document $document
	 *
	 * @return array
	 */
	public function get_document_conditions( $post_id ) {
		$saved_conditions = get_post_meta( $post_id, 'zyreladdons_display_cond', true );

		$conditions = [];

		if ( is_array( $saved_conditions ) ) {
			foreach ( $saved_conditions as $condition ) {
				$conditions[] = $this->parse_condition( $condition );
			}
		}

		return $conditions;
	}

	private function get_template_by_location( $location ) {
		$templates = $this->cache->get_by_location( $location );

		return $templates;
	}

	public static function admin_columns_headers( $posts_columns ) {
		$offset = 2;

		$posts_columns = array_slice( $posts_columns, 0, $offset, true ) + [
			'type' => __( 'Type', 'zyre-elementor-addons' ),
			'condition' => __( 'Conditions', 'zyre-elementor-addons' ),
		] + array_slice( $posts_columns, $offset, null, true );

		return $posts_columns;
	}

	public function admin_columns_content( $column_name, $post_id ) {

		if ( 'type' === $column_name ) {

			$type       = get_post_meta( $post_id, 'zyreladdons_library_type', true );
			$is_active   = get_post_meta( $post_id, 'zyreladdons_template_active', true );

            echo esc_html( ucwords( str_replace( '-', ' ', $type ) ) );

			echo "<span id='tmpl-", esc_attr( $post_id ), "'>";

			if ( $is_active ) {
				echo ' - <b>' . esc_html__( 'Active', 'zyre-elementor-addons' ) . '</b>';
			}

			echo '</span>';
		}

		if ( 'condition' === $column_name ) {

			$type = get_post_meta( $post_id, 'zyreladdons_library_type', true );

			if ( 'loop-template' != $type ) {
				// generate display condition from document conditions
				$include_conditions = [];
				$exclude_conditions = [];

				// get doc conditions
				$document_conditions    = $this->get_document_conditions( $post_id );

				if ( ! empty( $document_conditions ) ) {
					foreach ( $document_conditions as $key => $condition ) {
						if ( 'include' === $condition['type'] ) {
							$title = self::get_condition_title( $condition['sub_name'], $condition['sub_id'] );
							$sub_title = $title ? ' #' . $title : '';
							$con_label = ! empty( $condition['sub_name'] ) && 'all' !== $condition['sub_name'] ? Conditions_Manager::instance()->get_name( $condition['sub_name'] ) . $sub_title : Conditions_Manager::instance()->get_all_name( $condition['name'] );
							$include_conditions[] = $con_label;
						} elseif ( 'exclude' === $condition['type'] ) {
							$title = self::get_condition_title( $condition['sub_name'], $condition['sub_id'] );
							$sub_title = $title ? ' #' . $title : '';
							$con_label = ! empty( $condition['sub_name'] ) && 'all' !== $condition['sub_name'] ? Conditions_Manager::instance()->get_name( $condition['sub_name'] ) . $sub_title : Conditions_Manager::instance()->get_all_name( $condition['name'] );
							$exclude_conditions[] = $con_label;
						}
					}
				}

                printf(
                    wp_kses(
                        /* translators: 1: included conditions, 2: excluded conditions */
                        __( '<b>Include : </b> %1$s<br/><b>Exclude : </b> %2$s', 'zyre-elementor-addons' ),
                        [
                            'b'  => [],
                            'br' => [],
                        ]
                    ),
                    esc_html( implode( ', ', $include_conditions ) ),
                    esc_html( implode( ', ', $exclude_conditions ) )
                );
			} else {
				echo '<b>' . esc_html__( 'Not Applicable', 'zyre-elementor-addons' ) . '</b>';
			}
		}
	}

	public function set_sub_name_key_pairs( $key_pairs ) {
		$result = [];

		$sub_conditions = self::get_sub_conditions();
		if ( isset( $sub_conditions['taxonomies'] ) ) {
			unset( $sub_conditions['taxonomies'] );
		}

		foreach ($sub_conditions as $parentKey => $values) {
			foreach ($values as $value) {
				$result[$value] = $parentKey;
			}
		}

		return array_merge( $key_pairs, $result );
	}

	private static function get_sub_conditions() {
		$conditions = [
			'author'   => ['author', 'by_author'],
		];

		return apply_filters( 'zyreladdons/conditions/sub_conditions', $conditions );
	}

	public static function get_condition_title( $sub_name, $sub_id ) {
		if ( empty( $sub_id ) ) {
			return '';
		}

		$conditions = self::get_sub_conditions();

		// Category
		if ( isset( $conditions['category'] ) && in_array( $sub_name, $conditions['category'], true ) ) {
			$term = get_term( $sub_id, 'category' );
			return ( $term && ! is_wp_error( $term ) ) ? $term->name : '';
		}

		// Post Tag
		if ( isset( $conditions['post_tag'] ) && in_array( $sub_name, $conditions['post_tag'], true ) ) {
			$term = get_term( $sub_id, 'post_tag' );
			return ( $term && ! is_wp_error( $term ) ) ? $term->name : '';
		}

		// Taxonomy
		if ( isset( $conditions['taxonomies'] ) && isset( $conditions['taxonomies'][ $sub_name ] ) ) {
			$term = get_term( $sub_id, $conditions['taxonomies'][ $sub_name ] );
			return ( $term && ! is_wp_error( $term ) ) ? $term->name : '';
		}

		// Author
		if ( isset( $conditions['author'] ) && in_array( $sub_name, $conditions['author'], true ) ) {
			$user = get_userdata( $sub_id );
			return $user ? $user->display_name : '';
		}

		// Default → Post/Page
		$title = get_the_title( $sub_id );
		return $title ? $title : '';
	}

	protected function create_or_update_post( $type, $post_data, $meta ) {
		if ( empty( $post_data['post_title'] ) ) {
			$post_data['post_title'] = esc_html__( 'Elementor', 'zyre-elementor-addons' );
			$update_title = true;
		}

		$meta_data['_elementor_edit_mode'] = 'builder';

		$meta_data['zyreladdons_library_type']  = $type;
		$meta_data['zyreladdons_display_cond']  = $meta['display_conditions'];
		$meta_data['_wp_page_template'] = 'elementor_canvas';

		$post_data['meta_input'] = $meta_data;

		$post_id = wp_insert_post( $post_data );

		if ( ! empty( $update_title ) ) {
			$post_data['ID'] = $post_id;
			$post_data['post_title'] .= ' #' . $post_id;

			// The meta doesn't need update.
			unset( $post_data['meta_input'] );

			wp_update_post( $post_data );
		}

		return $post_id;
	}

	public function get_edit_url( $id ) {
		$url = add_query_arg(
			[
				'post' => $id,
				'action' => 'elementor',
			],
			admin_url( 'post.php' )
		);

		return $url;
	}

	public function document_config_title( $config, $post_id ) {
		$tmpl_type = get_post_meta( $post_id, 'zyreladdons_library_type', true );

		if ( self::POST_TYPE === get_post_type( $post_id ) ) {
			$title = '';
			switch ( $tmpl_type ) {
				case 'header':
					$title = esc_html__( 'Header Settings', 'zyre-elementor-addons' );
					break;

				case 'footer':
					$title = esc_html__( 'Footer Settings', 'zyre-elementor-addons' );
					break;

				case 'single':
					$title = esc_html__( 'Single Settings', 'zyre-elementor-addons' );
					break;

				case 'archive':
					$title = esc_html__( 'Archive Settings', 'zyre-elementor-addons' );
					break;

				case 'loop-template':
					$title = esc_html__( 'Loop Template', 'zyre-elementor-addons' );
					break;
			}
			$config['settings']['panelPage']['title'] = $title;
		}

		return $config;
	}

	/**
	 * Admin action new post.
	 *
	 * When a new post action is fired, the title is set to 'Elementor' followed by the post ID.
	 *
	 * Fired by `admin_action_zyreladdons_library_new_post` action.
	 *
	 * @since 1.0.0
	 * @access public
	 */
	public function admin_action_new_post() {

		check_admin_referer( 'zyreladdons_library_new_post_nonce' );

		$post_type = empty( $_GET['post_type'] ) ? 'post' : sanitize_text_field( wp_unslash( $_GET['post_type'] ) );

		$post_type_object = get_post_type_object( $post_type );

		if ( ! $post_type_object ) {
			wp_die( esc_html__( 'Invalid post type.', 'zyre-elementor-addons' ) );
		}

		if ( ! current_user_can( $post_type_object->cap->edit_posts ) ) {
			wp_die( esc_html__( 'Permission denied.', 'zyre-elementor-addons' ) );
		}

		$type = empty( $_GET['template_type'] ) ? 'post' : sanitize_text_field( wp_unslash( $_GET['template_type'] ) );

		$post_data = isset( $_GET['post_data'] ) ? zyreladdons_sanitize_array_recursively( wp_unslash( $_GET['post_data'] ) ) : [];

		$meta = [
			'display_conditions' => [],
		];
	
		$post_data['post_type'] = $post_type;

		$post_id = $this->create_or_update_post( $type, $post_data, $meta );

		if ( is_wp_error( $post_id ) ) {
			wp_die( esc_html( $post_id->get_error_message() ) );
		}

		wp_safe_redirect( $this->get_edit_url( $post_id ) );
    	exit;
	}

	private function check_elementor_content( $post_id ) {
		$el_content = get_post_meta( $post_id, '_elementor_data', true );

		if ( $el_content ) {
			return true;
		}

		return false;
	}

	public static function get_public_post_types( $args = [] ) {
		$post_type_args = [
			'show_in_nav_menus' => true,
		];

		// Keep for backwards compatibility
		if ( ! empty( $args['post_type'] ) ) {
			$post_type_args['name'] = $args['post_type'];
			unset( $args['post_type'] );
		}

		$post_type_args = wp_parse_args( $post_type_args, $args );

		$_post_types = get_post_types( $post_type_args, 'objects' );

		$post_types = [];

		foreach ( $_post_types as $post_type => $object ) {
			$post_types[ $post_type ] = $object->label;
		}

		// Product form WooCommerce are handled separately.
		if ( class_exists( 'woocommerce' ) ) {
			unset( $post_types['product'] );
		}

		return $post_types;
	}

	public function template_include( $template ) {
		$location = '';

		if ( is_singular( array_keys( self::get_public_post_types() ) ) || is_404() ) {
			$location = 'single';

			$is_built_with_elementor = $this->check_elementor_content( get_the_ID() );

			if ( $is_built_with_elementor ) {
				return $template;
			}
		} elseif ( function_exists( 'is_shop' ) && \is_shop() ) {
			$location = 'archive';
		} elseif ( is_archive() || is_tax() || is_home() || is_search() ) {
			$location = 'archive';
		}

		if ( class_exists( '\ElementorPro\Plugin' ) ) {
			$document = \ElementorPro\Plugin::elementor()->documents->get_doc_for_frontend( get_the_ID() );
			$page_templates_module = \ElementorPro\Plugin::elementor()->modules_manager->get_modules( 'page-templates' );

			if ( $document && $document instanceof \ElementorPro\Modules\ThemeBuilder\Documents\Theme_Document ) {
				// For editor preview iframe.
				$location = $document->get_location();

				if ( 'header' === $location || 'footer' === $location ) {
					$page_template = $page_templates_module::TEMPLATE_HEADER_FOOTER;
					$template_path = $page_templates_module->get_template_path( $page_template );

					if ( $template_path ) {
						$page_templates_module->set_print_callback( function () use ( $location ) {
							\ElementorPro\Modules\ThemeBuilder\Module::instance()->get_locations_manager()->do_location( $location );
						} );

						$template = $template_path;
					}

					return $template;
				}
			}
		}

		if ( $location ) {
			$location_documents = Conditions_Manager::instance()->get_documents_for_location( $location );

			if ( empty( $location_documents ) ) {
				return $template;
			}

			if ( 'single' === $location || 'archive' === $location ) {

				$first_key = key( $location_documents );
				$theme_document = $location_documents[ $first_key ];

				$template_type = get_post_meta( $theme_document, '_wp_page_template', true );

				$this->singular_template = $theme_document;

				if ( $theme_document ) {
					switch ( $template_type ) {
						case 'elementor_canvas':
							$template = ZYRELADDONS_DIR_PATH . 'modules/theme-builder/templates/singular/canvas.php';
							break;
						case 'elementor_header_footer':
							$template = ZYRELADDONS_DIR_PATH . 'modules/theme-builder/templates/singular/fullwidth.php';
							break;
						default:
							$template = ZYRELADDONS_DIR_PATH . 'modules/theme-builder/templates/singular/fullwidth.php';
							break;
					}
				}
			}
		}

		return $template;
	}

	public static function render_builder_data( $content_id ) {
		$_elementor = \Elementor\Plugin::instance();
		$has_css = false;

		if ( ( 'internal' === get_option( 'elementor_css_print_method' ) ) || \Elementor\Plugin::$instance->preview->is_preview_mode() ) {
			$has_css = true;
		}
		$content_id = apply_filters( 'wpml_object_id', $content_id, 'elementor_library' );
		return $_elementor->frontend->get_builder_content_for_display( $content_id, $has_css );
	}

	public function render_builder_data_location( $location ) {
		$templates = Conditions_Manager::instance()->get_documents_for_location( $location );
		$first_key = key( $templates );
		$valid_template = $templates[ $first_key ];

		return $this->render_builder_data( $valid_template );
	}

	public function single_blog_content_elementor( $post ) {
		$templates = $this->singular_template;
		if ( ! empty( $templates ) ) {
            echo self::render_builder_data( $templates ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		} else {
			the_content();
		}
	}

	public function add_elementor_widget_categories( $elements_manager ) {
		if ( self::POST_TYPE === get_post_type() ) {
			$elements_manager->add_category(
				'zyreladdons_theme_builder',
				[
					'title' => esc_html__( 'Zyre Theme Builder', 'zyre-elementor-addons' ),
					'icon' => 'fa fa-plug',
				]
			);
		}
	}
}
