<?php
/**
 * Header Footer Builder Class
 * @package Softech_Addons_for_Elementor
 * @since   1.2.0
 * @updated 1.2.3
 */

namespace Softech_Addons_for_Elementor\Includes;

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

class SITS_Header_Footer_Builder {

	/* ------------------------------------------------------------------ */
	/* Constants                                                            */
	/* ------------------------------------------------------------------ */
	const POST_TYPE         = 'sits_hf_template';
	const META_TYPE         = '_sits_hf_type';
	const META_DISPLAY_ON   = '_sits_hf_display_on';
	const ALL_TYPES         = [ 'header', 'footer', 'archive', 'single_page', 'single_post', '404_page' ];
	const META_EXCLUDE_ON   = '_sits_hf_exclude_on';
	const META_SPECIFIC_IDS = '_sits_hf_specific_ids';
	const META_EXCLUDE_IDS  = '_sits_hf_exclude_ids';
	const OPTION_ACTIVE     = 'sits_hf_active_templates';
	const META_MIRROR_ID    = '_sits_hf_elementor_mirror_id';
	/** Archive-sub-type specific term IDs (categories, tags, authors). */
	const META_DISPLAY_ARCHIVE_TERMS = '_sits_hf_display_archive_terms';
	const META_EXCLUDE_ARCHIVE_TERMS = '_sits_hf_exclude_archive_terms';

	
	const PRIORITY_GLOBAL    = 10;
	const PRIORITY_PAGE_TYPE = 20;
	const PRIORITY_SPECIFIC  = 30;

	/* ------------------------------------------------------------------ */
	/* Singleton                                                            */
	/* ------------------------------------------------------------------ */
	private static $instance = null;
    /** @var int|null Buffer level for footer suppression */
    private $sits_footer_buf_level = null;

    /** @var int|null Buffer level for header suppression */
    private $sits_header_buf_level = null;
    
	public static function instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	private function __construct() {
		add_action( 'init',             [ $this, 'register_post_type' ] );
		add_action( 'add_meta_boxes',   [ $this, 'add_meta_boxes' ] );
		add_action( 'save_post_' . self::POST_TYPE, [ $this, 'save_meta' ], 10, 2 );

		add_filter( 'manage_' . self::POST_TYPE . '_posts_columns',       [ $this, 'set_custom_columns' ] );
		add_action( 'manage_' . self::POST_TYPE . '_posts_custom_column', [ $this, 'custom_column_content' ], 10, 2 );
		add_filter( 'post_row_actions',  [ $this, 'add_row_actions' ], 10, 2 );

		add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_assets' ] );
		add_action( 'admin_notices',         [ $this, 'activation_admin_notice' ] );

		// Type tabs on listing page — rendered via admin_notices so they sit
		// in their own block ABOVE WP's native Published/Trash views row.
		add_action( 'admin_footer',                          [ $this, 'render_type_tabs_block' ] );
		add_filter( 'views_edit-' . self::POST_TYPE,         [ $this, 'add_type_tab_views' ] );
		add_filter( 'parse_query',                           [ $this, 'apply_tab_filter' ] );

		// Restore Active/Inactive status filter dropdown (Issue 4).
		add_action( 'restrict_manage_posts', [ $this, 'add_status_filter_dropdown' ] );
		add_filter( 'parse_query',           [ $this, 'apply_status_filter' ] );

		// Bug #6 fix: auto-activate template when it transitions to published.
		add_action( 'transition_post_status', [ $this, 'auto_activate_on_publish' ], 10, 3 );

		add_action( 'wp_ajax_sits_activate_hf_template',   [ $this, 'ajax_activate_template' ] );
		add_action( 'wp_ajax_sits_deactivate_hf_template', [ $this, 'ajax_deactivate_template' ] );
		add_action( 'wp_ajax_sits_search_posts_pages',     [ $this, 'ajax_search_posts_pages' ] );
		add_action( 'wp_ajax_sits_search_archive_items',  [ $this, 'ajax_search_archive_items' ] );

		// New: redirect Add New → Elementor editor
		add_action( 'load-post-new.php', [ $this, 'redirect_add_new_to_elementor' ] );

		// New: Elementor editor panel script (intercepts publish button)
		add_action( 'elementor/editor/before_enqueue_scripts', [ $this, 'enqueue_elementor_panel_assets' ] );
		// Points 5 & 6: Hide title above canvas in Elementor editor for HF templates.
		add_action( 'elementor/editor/after_enqueue_scripts',  [ $this, 'maybe_enqueue_hf_title_hide_css' ] );

		// New: AJAX handlers for the popup
		add_action( 'wp_ajax_sits_save_hf_template_settings', [ $this, 'ajax_save_template_settings' ] );
		add_action( 'wp_ajax_sits_check_hf_conflict',         [ $this, 'ajax_check_conflict' ] );
		add_action( 'wp_ajax_sits_get_hf_settings',           [ $this, 'ajax_get_settings' ] );
		add_action( 'wp_ajax_sits_create_hf_draft',           [ $this, 'ajax_create_hf_draft' ] );

		// Fix 7: auto-deactivate on trash / delete
		add_action( 'wp_trash_post',      [ $this, 'maybe_deactivate_on_trash_delete' ] );
		add_action( 'before_delete_post', [ $this, 'maybe_deactivate_on_trash_delete' ] );

		add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_frontend_assets' ] );

		// Override the theme template for 404_page, single_post, archive, and
		// single_page types when an active template exists for the current request.
		add_filter( 'template_include', [ $this, 'maybe_override_page_template' ], 99 );
		
		// Issue 3: Suppress Elementor Pro ThemeBuilder header/footer when ours is active.
		add_action( 'elementor/theme/before_do_header', [ $this, 'maybe_suppress_pro_header' ], 1 );
		add_action( 'elementor/theme/before_do_footer', [ $this, 'maybe_suppress_pro_footer' ], 1 );

		// Frontend injection – hooked directly so they always fire at the right moment.
		// Conditional tag checks (is_singular etc.) are safe inside wp_body_open / wp_footer.
		add_action( 'wp_body_open', [ $this, 'inject_header_at_body_open' ], 1 );
		add_action( 'wp_footer',    [ $this, 'inject_footer_before_close' ], 1 );

		// Editor / preview mode extra hooks (canvas hooks etc.)
		add_action( 'template_redirect', [ $this, 'setup_editor_display' ] );

		add_action( 'elementor/documents/register', [ $this, 'register_elementor_document_type' ] );
		add_filter( 'body_class', [ $this, 'add_body_class' ] );
		add_filter( 'elementor/frontend/admin_bar/settings', [ $this, 'filter_elementor_admin_bar_settings' ], 900 );

		add_action( 'init', [ $this, 'sync_elementor_template_type' ], 25 );

		// Sync edits made in Elementor Pro's Theme Builder back to our source template
		add_action( 'save_post_elementor_library', [ $this, 'on_elementor_library_save' ], 99, 2 );

		// Points 5 & 6: Hide the site/post title for HF templates in editor, preview, and frontend.
		add_filter( 'pre_get_document_title', [ $this, 'filter_document_title_for_hf' ], 10, 1 );
		add_filter( 'the_title',              [ $this, 'filter_the_title_for_hf' ],       10, 2 );
		add_action( 'wp',                     [ $this, 'force_hide_title_meta' ] );
		add_action( 'template_redirect', [ $this, 'setup_theme_suppression' ], 1 );
	}

	

	public function register_post_type() {
		register_post_type( self::POST_TYPE, [
			'labels' => [
				'name'               => _x( 'Theme Builder', 'post type general name', 'softech-addons-for-elementor' ),
				'singular_name'      => _x( 'Template', 'post type singular name', 'softech-addons-for-elementor' ),
				'menu_name'          => __( 'Theme Builder', 'softech-addons-for-elementor' ),
				'add_new'            => __( 'Add New', 'softech-addons-for-elementor' ),
				'add_new_item'       => __( 'Add New Template', 'softech-addons-for-elementor' ),
				'edit_item'          => __( 'Edit Template', 'softech-addons-for-elementor' ),
				'not_found'          => __( 'No templates found', 'softech-addons-for-elementor' ),
				'not_found_in_trash' => __( 'No templates found in Trash', 'softech-addons-for-elementor' ),
			],
			'public'              => true,
            'show_ui'             => true,
            'show_in_menu'        => false,
            'show_in_nav_menus'   => false,
            'exclude_from_search' => true,
            'capability_type'     => 'page',
            'hierarchical'        => false,
            'rewrite'             => false,
            'query_var'           => false,
            'supports'            => [ 'title', 'editor', 'elementor' ],
            'show_in_rest'        => true,
		] );

		add_action( 'admin_menu', function () {
			add_submenu_page(
				'softech-addons-for-elementor',
				__( 'Theme Builder', 'softech-addons-for-elementor' ),
				__( 'Theme Builder', 'softech-addons-for-elementor' ),
				'manage_options',
				'edit.php?post_type=' . self::POST_TYPE
			);
		} );
	}

	

	public function add_meta_boxes() {
		add_meta_box( 'sits_hf_settings', __( 'Template Settings', 'softech-addons-for-elementor' ),
			[ $this, 'render_settings_metabox' ], self::POST_TYPE, 'side', 'high' );
		add_meta_box( 'sits_hf_display_rules', __( 'Display Rules', 'softech-addons-for-elementor' ),
			[ $this, 'render_display_rules_metabox' ], self::POST_TYPE, 'normal', 'default' );
	}

	public function render_settings_metabox( $post ) {
		wp_nonce_field( 'sits_hf_save_meta', 'sits_hf_meta_nonce' );
		$type    = get_post_meta( $post->ID, self::META_TYPE, true );
		$active  = $this->get_active_option();
		$is_active = $this->is_active( $post->ID, $type, $active );
		?>
		<div class="sits-hf-settings">
			<p>
				<label for="sits_hf_type"><strong><?php esc_html_e( 'Template Type:', 'softech-addons-for-elementor' ); ?></strong></label><br>
				<select name="sits_hf_type" id="sits_hf_type" class="widefat">
					<option value=""><?php esc_html_e( 'Select Type', 'softech-addons-for-elementor' ); ?></option>
					<option value="header"      <?php selected( $type, 'header' ); ?>><?php esc_html_e( 'Header',         'softech-addons-for-elementor' ); ?></option>
					<option value="footer"      <?php selected( $type, 'footer' ); ?>><?php esc_html_e( 'Footer',         'softech-addons-for-elementor' ); ?></option>
					<option value="archive"     <?php selected( $type, 'archive' ); ?>><?php esc_html_e( 'Archive',        'softech-addons-for-elementor' ); ?></option>
					<option value="single_page" <?php selected( $type, 'single_page' ); ?>><?php esc_html_e( 'Single Page',   'softech-addons-for-elementor' ); ?></option>
					<option value="single_post" <?php selected( $type, 'single_post' ); ?>><?php esc_html_e( 'Single Post',   'softech-addons-for-elementor' ); ?></option>
					<option value="404_page"    <?php selected( $type, '404_page' ); ?>><?php esc_html_e( '404 Page',      'softech-addons-for-elementor' ); ?></option>
				</select>
			</p>

			<?php if ( 'publish' === $post->post_status && $type ) : ?>
				<p class="sits-hf-activation-status">
					<?php if ( $is_active ) : ?>
						<span class="sits-status-active"><span class="dashicons dashicons-yes-alt"></span> <?php esc_html_e( 'Active', 'softech-addons-for-elementor' ); ?></span><br><br>
						<?php $dnonce = wp_create_nonce( 'sits_deactivate_hf_' . $post->ID ); ?>
						<button type="button" class="button sits-deactivate-template"
								data-template-id="<?php echo esc_attr( $post->ID ); ?>"
								data-template-type="<?php echo esc_attr( $type ); ?>"
								data-deactivate-url="<?php echo esc_url( admin_url( 'admin-ajax.php?action=sits_deactivate_hf_template&template_id=' . $post->ID . '&type=' . $type . '&_wpnonce=' . $dnonce ) ); ?>"
								style="color:#dc2626; border-color:#dc2626;">
							<?php esc_html_e( 'Deactivate This Template', 'softech-addons-for-elementor' ); ?>
						</button>
					<?php else : ?>
						<span class="sits-status-inactive"><span class="dashicons dashicons-minus"></span> <?php esc_html_e( 'Inactive', 'softech-addons-for-elementor' ); ?></span><br><br>
						<button type="button" class="button button-primary sits-activate-template"
								data-template-id="<?php echo esc_attr( $post->ID ); ?>"
								data-template-type="<?php echo esc_attr( $type ); ?>">
							<?php esc_html_e( 'Activate This Template', 'softech-addons-for-elementor' ); ?>
						</button>
					<?php endif; ?>
				</p>
			<?php endif; ?>

			<p class="description"><?php esc_html_e( 'Multiple templates can be active with different (non-overlapping) Display Rules.', 'softech-addons-for-elementor' ); ?></p>
		</div>
		<style>
		.sits-status-active  { color:#46b450; font-weight:600; }
		.sits-status-inactive{ color:#999; }
		.sits-status-active .dashicons, .sits-status-inactive .dashicons { vertical-align:middle; }
		</style>
		<?php
	}
    public function setup_theme_suppression() {
     if ( is_admin() || \Elementor\Plugin::$instance->editor->is_edit_mode() || is_singular( self::POST_TYPE ) || is_404() ) {
	return;
}

    // Canvas-rendered requests already replace the theme shell entirely.
    // If we keep buffering them here, the wp_footer discard path can erase the
    // actual single-post / single-page / archive content and leave only the header.
    
	$canvas_type = null;
    if ( is_404() ) {
        $canvas_type = '404_page';
    } elseif ( is_singular( 'post' ) ) {
        $canvas_type = 'single_post';
    } elseif ( is_singular( 'page' ) ) {
        $canvas_type = 'single_page';
    } elseif ( is_archive() || is_home() ) {
        $canvas_type = 'archive';
    }

    if ( $canvas_type && $this->get_best( $canvas_type ) ) {
        return;
    }

    $has_header = (bool) $this->get_best( 'header' );
    $has_footer = (bool) $this->get_best( 'footer' );

    if ( ! $has_header && ! $has_footer ) {
        return;
    }

    // ------------------------------------------------------------------
    // FOOTER — theme outputs <footer> BEFORE wp_footer() fires.
    // Buffer from get_footer, discard at wp_footer priority 0
    // (before our inject_footer_before_close at priority 1).
    // ------------------------------------------------------------------
    if ( $has_footer ) {
        add_action( 'get_footer', function () {
            $this->sits_footer_buf_level = ob_get_level();
            ob_start();
        } );

        add_action( 'wp_footer', function () {
	if ( isset( $this->sits_footer_buf_level ) && ob_get_level() > $this->sits_footer_buf_level ) {
		ob_end_clean(); // discards theme <footer> entirely
	}
}, 0 ); // priority 0 → before our custom footer injects at priority 1
    }

    
    if ( $has_header ) {
        add_action( 'get_header', function () {
            $this->sits_header_buf_level = ob_get_level();
            ob_start();
        } );

        add_action( 'wp_body_open', function () {
            // Flush pre-body content (doctype, head, body tag, our custom header).
            $pre = ob_get_clean();
            echo $pre; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped

            // Fresh buffer — captures theme's <header> that header.php
            // outputs after wp_body_open() returns.
            $this->sits_header_buf_level = ob_get_level();
            ob_start();
        }, PHP_INT_MAX );

        // Discard theme header buffer — whichever fires first wins;
        // static flag prevents double-discard.
        $discard = function () {
	static $done = false;
	if ( $done ) {
		return;
	}
	if ( isset( $this->sits_header_buf_level ) && ob_get_level() > $this->sits_header_buf_level ) {
		ob_end_clean();
	}
	$done = true;
};

        add_action( 'loop_start',  $discard, -999 ); // posts/pages/archives
        add_action( 'get_sidebar', $discard, -999 ); // themes using sidebar
        add_action( 'wp_footer',   $discard, -999 ); // fallback (404, no-loop pages)
    }
}
	public function render_display_rules_metabox( $post ) {
		$display_on   = (array) get_post_meta( $post->ID, self::META_DISPLAY_ON, true );
		$exclude_on   = (array) get_post_meta( $post->ID, self::META_EXCLUDE_ON, true );
		$specific_ids = (array) get_post_meta( $post->ID, self::META_SPECIFIC_IDS, true );
		$exclude_ids  = (array) get_post_meta( $post->ID, self::META_EXCLUDE_IDS,  true );
		$template_type = get_post_meta( $post->ID, self::META_TYPE, true );
		$display_on   = $this->normalize_display_conditions_for_template( $template_type, $display_on );

		$selected_posts = $this->build_post_list( $specific_ids );
		$excluded_posts = $this->build_post_list( $exclude_ids );

		$conditions = $this->get_display_conditions_for_type( $template_type );
		$exc_conditions = array_diff_key( $conditions, [ 'all' => '' ] );
		?>
		<div class="sits-hf-display-rules">
			<div style="background:#f0f6ff; border-left:4px solid #007cba; padding:10px 14px; margin-bottom:16px; border-radius:0 4px 4px 0; font-size:13px;">
				<strong><?php esc_html_e( 'Priority:', 'softech-addons-for-elementor' ); ?></strong>
				<?php esc_html_e( 'Specific Post/Page (highest) › Page-Type › Entire Website (lowest fallback). When two active templates match the same page, the highest priority one is shown. You cannot activate two templates with overlapping conditions.', 'softech-addons-for-elementor' ); ?>
			</div>

			<!-- DISPLAY ON -->
			<div class="sits-rules-section" style="margin-bottom:20px;">
				<h4 style="margin:0 0 4px;"><?php esc_html_e( 'Display On', 'softech-addons-for-elementor' ); ?></h4>
				<p class="description" style="margin:0 0 10px;"><?php esc_html_e( 'Where should this template be displayed?', 'softech-addons-for-elementor' ); ?></p>

				<?php foreach ( $conditions as $val => $label ) : ?>
					<p style="margin:4px 0;">
						<label>
							<input type="checkbox"
								   name="sits_hf_display_on[]"
								   value="<?php echo esc_attr( $val ); ?>"
								   class="sits-display-cb"
								   data-condition="<?php echo esc_attr( $val ); ?>"
								   <?php checked( in_array( $val, $display_on, true ) ); ?>>
							<?php echo esc_html( $label ); ?>
						</label>
					</p>
					<?php if ( 'singular' === $val ) {
						$this->render_specific_ui( 'display', $specific_ids, $selected_posts, in_array( 'singular', $display_on, true ) );
					} ?>
				<?php endforeach; ?>
			</div>

			<hr>

			<!-- EXCLUDE FROM -->
			<div class="sits-rules-section">
				<h4 style="margin:0 0 4px;"><?php esc_html_e( 'Exclude From', 'softech-addons-for-elementor' ); ?></h4>
				<p class="description" style="margin:0 0 10px;"><?php esc_html_e( 'Where should this template NOT appear? (Conditions selected in Display On are disabled here.)', 'softech-addons-for-elementor' ); ?></p>

				<?php foreach ( $exc_conditions as $val => $label ) :
					$in_display = in_array( $val, $display_on, true );
				?>
					<p style="margin:4px 0;">
						<label<?php echo $in_display ? ' style="color:#bbb;"' : ''; ?>>
							<input type="checkbox"
								   name="sits_hf_exclude_on[]"
								   value="<?php echo esc_attr( $val ); ?>"
								   class="sits-exclude-cb"
								   data-condition="<?php echo esc_attr( $val ); ?>"
								   <?php checked( in_array( $val, $exclude_on, true ) ); ?>
								   <?php disabled( $in_display ); ?>>
							<?php echo esc_html( $label ); ?>
						</label>
					</p>
					<?php if ( 'singular' === $val ) {
						$this->render_specific_ui( 'exclude', $exclude_ids, $excluded_posts, in_array( 'singular', $exclude_on, true ) );
					} ?>
				<?php endforeach; ?>
			</div>
		</div>
		<?php
	}

	/**
	 * Return the display-condition labels allowed for a given template type.
	 *
	 * Single Post templates intentionally expose only the core page buckets the
	 * user asked for: entire site, singular, single post, all archives, and 404.
	 *
	 * @param string $template_type Template type meta value.
	 * @return array<string,string>
	 */
	private function get_display_conditions_for_type( $template_type ) {
		$conditions = [
			'all'              => __( 'Entire Website', 'softech-addons-for-elementor' ),
			'front_page'       => __( 'Front Page', 'softech-addons-for-elementor' ),
			'blog'             => __( 'Blog Index / Posts Listing Page', 'softech-addons-for-elementor' ),
			'singular'         => __( 'All Singular (Posts & Pages)', 'softech-addons-for-elementor' ),
			'singular_post'    => __( '↳ All Single Posts', 'softech-addons-for-elementor' ),
			'singular_page'    => __( '↳ All Single Pages', 'softech-addons-for-elementor' ),
			'archive'          => __( 'All Archives', 'softech-addons-for-elementor' ),
			'archive_post'     => __( '↳ Posts Archive', 'softech-addons-for-elementor' ),
			'archive_author'   => __( '↳ Author Archive', 'softech-addons-for-elementor' ),
			'archive_date'     => __( '↳ Date Archive', 'softech-addons-for-elementor' ),
			'archive_search'   => __( '↳ Search Results', 'softech-addons-for-elementor' ),
			'archive_category' => __( '↳ Post Categories', 'softech-addons-for-elementor' ),
			'archive_tag'      => __( '↳ Post Tags', 'softech-addons-for-elementor' ),
			'404'              => __( '404 Page', 'softech-addons-for-elementor' ),
		];

		if ( 'single_post' === $template_type ) {
			return [
				'all'           => $conditions['all'],
				'singular'      => $conditions['singular'],
				'singular_post' => $conditions['singular_post'],
				'archive'       => $conditions['archive'],
				'404'           => $conditions['404'],
			];
		}

		if ( '404_page' === $template_type ) {
			return [
				'404' => $conditions['404'],
			];
		}

		return $conditions;
	}

	/**
	 * Normalize saved Display On conditions for a template type.
	 *
	 * @param string $template_type Template type.
	 * @param array  $display_on    Raw display conditions.
	 * @return array
	 */
	private function normalize_display_conditions_for_template( $template_type, $display_on ) {
		$display_on = array_values(
			array_unique(
				array_filter(
					array_map( 'sanitize_text_field', (array) $display_on )
				)
			)
		);

		$allowed = array_keys( $this->get_display_conditions_for_type( $template_type ) );
		if ( ! empty( $allowed ) ) {
			$display_on = array_values( array_intersect( $display_on, $allowed ) );
		}

		if ( '404_page' === $template_type ) {
			return [ '404' ];
		}

		if ( empty( $display_on ) && in_array( 'all', $allowed, true ) ) {
			return [ 'all' ];
		}

		return $display_on;
	}

	private function render_specific_ui( $mode, $ids, $posts, $singular_checked ) {
		$d = ( 'display' === $mode );
		?>
		<div id="<?php echo $d ? 'sits-specific-selection' : 'sits-exclude-specific-selection'; ?>"
			 style="margin-left:25px;<?php echo $singular_checked ? '' : ' display:none;'; ?>">
			<p style="margin:4px 0;">
				<label>
					<input type="checkbox" id="<?php echo $d ? 'sits_use_specific' : 'sits_use_exclude_specific'; ?>"
						   <?php checked( ! empty( $ids ) ); ?>>
					<strong><?php echo $d
						? esc_html__( 'Select Specific Posts/Pages', 'softech-addons-for-elementor' )
						: esc_html__( 'Exclude Specific Posts/Pages Only', 'softech-addons-for-elementor' ); ?></strong>
				</label>
			</p>
			<div id="<?php echo $d ? 'sits-specific-posts-wrapper' : 'sits-exclude-specific-posts-wrapper'; ?>"
				 style="<?php echo ! empty( $ids ) ? '' : 'display:none;'; ?>">
				<input type="text" id="<?php echo $d ? 'sits-search-posts' : 'sits-exclude-search-posts'; ?>" class="widefat"
					   placeholder="<?php esc_attr_e( 'Search posts or pages…', 'softech-addons-for-elementor' ); ?>" autocomplete="off">
				<div id="<?php echo $d ? 'sits-search-results' : 'sits-exclude-search-results'; ?>"
					 style="display:none; max-height:200px; overflow-y:auto; border:1px solid #ddd; background:#fff; margin-top:5px;"></div>
				<div id="<?php echo $d ? 'sits-selected-posts' : 'sits-excluded-posts'; ?>" style="margin-top:10px;">
					<?php foreach ( $posts as $item ) :
						$bg   = $d ? '#f0f0f1' : '#fff0f0';
						$name = $d ? 'sits_hf_specific_ids[]' : 'sits_hf_exclude_ids[]';
						$cls  = $d ? 'sits-selected-post'    : 'sits-excluded-post';
						$rcls = $d ? 'sits-remove-post'      : 'sits-remove-excluded-post';
					?>
						<div class="<?php echo esc_attr( $cls ); ?>"
							 style="padding:8px; background:<?php echo esc_attr( $bg ); ?>; margin-bottom:5px; border-radius:3px; display:flex; justify-content:space-between; align-items:center;">
							<span><strong><?php echo esc_html( $item['title'] ); ?></strong> <em style="color:#666; font-size:12px;">(<?php echo esc_html( ucfirst( $item['type'] ) ); ?>)</em></span>
							<button type="button" class="button <?php echo esc_attr( $rcls ); ?>" data-id="<?php echo esc_attr( $item['id'] ); ?>" style="padding:0 8px; line-height:1.5;">×</button>
							<input type="hidden" name="<?php echo esc_attr( $name ); ?>" value="<?php echo esc_attr( $item['id'] ); ?>">
						</div>
					<?php endforeach; ?>
				</div>
			</div>
		</div>
		<?php
	}

	/* ================================================================== */
	/* Save Meta                                                            */
	/* ================================================================== */

	public function save_meta( $post_id, $post ) {
		if ( ! isset( $_POST['sits_hf_meta_nonce'] ) ||
			 ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['sits_hf_meta_nonce'] ) ), 'sits_hf_save_meta' ) ) {
			return;
		}
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return; }
		if ( ! current_user_can( 'edit_post', $post_id ) )    { return; }

		$old_type = get_post_meta( $post_id, self::META_TYPE, true );
		$type     = isset( $_POST['sits_hf_type'] ) ? sanitize_text_field( wp_unslash( $_POST['sits_hf_type'] ) ) : '';
		if ( in_array( $type, [ 'header', 'footer', 'archive', 'single_page', 'single_post', '404_page' ], true ) ) {
			update_post_meta( $post_id, self::META_TYPE, $type );
			// Fix: if type changed, remove from old type's active list so the template
			// does not appear as both header and footer simultaneously.
			if ( $old_type && $old_type !== $type ) {
				$opt = $this->get_active_option();
				if ( in_array( absint( $post_id ), $opt[ $old_type ] ?? [], true ) ) {
					$opt[ $old_type ] = array_values( array_diff( $opt[ $old_type ], [ absint( $post_id ) ] ) );
					update_option( self::OPTION_ACTIVE, $opt );
				}
			}
		} else {
			delete_post_meta( $post_id, self::META_TYPE );
			$type = '';
		}

		$display_on = [];
		$allowed_display_on = array_keys( $this->get_display_conditions_for_type( $type ) );
		if ( ! empty( $_POST['sits_hf_display_on'] ) && is_array( $_POST['sits_hf_display_on'] ) ) {
			foreach ( array_map( 'sanitize_text_field', wp_unslash( $_POST['sits_hf_display_on'] ) ) as $loc ) {
				if ( in_array( $loc, $allowed_display_on, true ) ) {
					$display_on[] = $loc;
				}
			}
		}
		$display_on = $this->normalize_display_conditions_for_template( $type, $display_on );
		update_post_meta( $post_id, self::META_DISPLAY_ON, $display_on );

		$exclude_on = [];
		if ( ! empty( $_POST['sits_hf_exclude_on'] ) && is_array( $_POST['sits_hf_exclude_on'] ) ) {
			foreach ( array_map( 'sanitize_text_field', wp_unslash( $_POST['sits_hf_exclude_on'] ) ) as $loc ) {
				if ( in_array( $loc, $allowed_display_on, true )
					 && ! in_array( $loc, $display_on, true ) ) {
					$exclude_on[] = $loc;
				}
			}
		}
		update_post_meta( $post_id, self::META_EXCLUDE_ON, $exclude_on );

		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		update_post_meta( $post_id, self::META_SPECIFIC_IDS, $this->sanitize_ids( isset( $_POST['sits_hf_specific_ids'] ) ? wp_unslash( $_POST['sits_hf_specific_ids'] ) : [] ) );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		update_post_meta( $post_id, self::META_EXCLUDE_IDS,  $this->sanitize_ids( isset( $_POST['sits_hf_exclude_ids'] ) ? wp_unslash( $_POST['sits_hf_exclude_ids'] ) : [] ) );

		$this->sync_single( $post_id );
	}

	/* ================================================================== */
	/* Admin Columns / Row Actions                                          */
	/* ================================================================== */

	public function set_custom_columns( $cols ) {
		$new = [];
		foreach ( $cols as $k => $v ) {
			if ( 'title' === $k ) {
				$new[$k]                = $v;
				$new['sits_hf_type']    = __( 'Type', 'softech-addons-for-elementor' );
				$new['sits_hf_status']  = __( 'Status', 'softech-addons-for-elementor' );
				$new['sits_hf_display'] = __( 'Display On', 'softech-addons-for-elementor' );
			} elseif ( 'date' !== $k ) {
				$new[$k] = $v;
			}
		}
		$new['date'] = $cols['date'];
		return $new;
	}

	public function custom_column_content( $col, $pid ) {
		switch ( $col ) {
			case 'sits_hf_type':
				$t = get_post_meta( $pid, self::META_TYPE, true );
				echo $t ? '<span class="sits-hf-type sits-hf-type-' . esc_attr($t) . '">' . esc_html(ucfirst($t)) . '</span>' : '—';
				break;
			case 'sits_hf_status':
				$t = get_post_meta( $pid, self::META_TYPE, true );
				$a = $this->get_active_option();
				echo $this->is_active($pid, $t, $a)
					? '<span class="sits-hf-status-badge sits-active">'   . esc_html__('Active',   'softech-addons-for-elementor') . '</span>'
					: '<span class="sits-hf-status-badge sits-inactive">' . esc_html__('Inactive', 'softech-addons-for-elementor') . '</span>';
				break;
			case 'sits_hf_display':
				$this->render_display_col($pid);
				break;
		}
	}

	private function render_display_col( $pid ) {
		$display_on   = (array) get_post_meta($pid, self::META_DISPLAY_ON,   true);
		$specific_ids = (array) get_post_meta($pid, self::META_SPECIFIC_IDS, true);
		$exclude_on   = (array) get_post_meta($pid, self::META_EXCLUDE_ON,   true);
		$exclude_ids  = (array) get_post_meta($pid, self::META_EXCLUDE_IDS,  true);
		$template_type = get_post_meta( $pid, self::META_TYPE, true );
		$display_on    = $this->normalize_display_conditions_for_template( $template_type, $display_on );
		$allowed_keys  = array_keys( $this->get_display_conditions_for_type( $template_type ) );
		$exclude_on    = array_values( array_diff( array_intersect( $exclude_on, $allowed_keys ), $display_on ) );

		if ( empty($display_on) ) { echo '—'; return; }

		$lbl = [
			'all'              => __( 'Entire Website', 'softech-addons-for-elementor' ),
			'singular'         => __( 'All Singular', 'softech-addons-for-elementor' ),
			'singular_post'    => __( 'All Single Posts', 'softech-addons-for-elementor' ),
			'singular_page'    => __( 'All Single Pages', 'softech-addons-for-elementor' ),
			'archive'          => __( 'All Archives', 'softech-addons-for-elementor' ),
			'archive_post'     => __( 'Posts Archive', 'softech-addons-for-elementor' ),
			'archive_author'   => __( 'Author Archive', 'softech-addons-for-elementor' ),
			'archive_date'     => __( 'Date Archive', 'softech-addons-for-elementor' ),
			'archive_search'   => __( 'Search Results', 'softech-addons-for-elementor' ),
			'archive_category' => __( 'Post Categories', 'softech-addons-for-elementor' ),
			'archive_tag'      => __( 'Post Tags', 'softech-addons-for-elementor' ),
			'front_page'       => __( 'Front Page', 'softech-addons-for-elementor' ),
			'blog'             => __( 'Blog', 'softech-addons-for-elementor' ),
			'404'              => __( '404 Page', 'softech-addons-for-elementor' ),
		];

		$parts = [];
		foreach ($display_on as $loc) {
			if ( ! in_array( $loc, $allowed_keys, true ) ) {
				continue;
			}
			if ( 'singular' === $loc && !empty($specific_ids) ) {
				$titles = array_filter(array_map(function($sid){ $p=get_post(absint($sid)); return $p?esc_html($p->post_title):''; }, $specific_ids));
				$parts[] = $titles ? implode(', ', $titles) : $lbl['singular'];
			} elseif (isset($lbl[$loc])) { $parts[] = $lbl[$loc]; }
		}
		if ( '404_page' === $template_type && empty( $parts ) ) {
			$parts[] = $lbl['404'];
		}
		$include_text = implode( ', ', $parts );
		if ( '' === $include_text ) {
			$include_text = 'N/A';
		}
		if ( '404_page' === $template_type ) {
			echo '<small>' . esc_html__( 'Incl:', 'softech-addons-for-elementor' ) . ' ' . esc_html( $include_text ) . '</small>';
		} else {
			echo esc_html( $include_text );
		}

		$exc = [];
		if (!empty($exclude_on)) {
			foreach ($exclude_on as $loc) {
				if ( ! in_array( $loc, $allowed_keys, true ) ) {
					continue;
				}
				if ( 'singular' === $loc && !empty($exclude_ids) ) {
					$titles = array_filter(array_map(function($eid){ $p=get_post(absint($eid)); return $p?esc_html($p->post_title):''; }, $exclude_ids));
					$exc[] = $titles ? implode(', ', $titles) : $lbl['singular'];
				} elseif (isset($lbl[$loc])) { $exc[] = $lbl[$loc]; }
			}
		}
		if ( '404_page' === $template_type ) {
			if ( $exc ) {
				echo '<br><small style="color:#c00;">' . esc_html__( 'Excl:', 'softech-addons-for-elementor' ) . ' ' . esc_html( implode( ', ', $exc ) ) . '</small>';
			}
		} elseif ($exc) {
			echo '<br><small style="color:#c00;">' . esc_html__('Excl:','softech-addons-for-elementor') . ' ' . esc_html(implode(', ', $exc)) . '</small>';
		}
	}

	public function add_row_actions( $actions, $post ) {
		if ( self::POST_TYPE !== $post->post_type ) { return $actions; }

		// Req #5: Remove regular "Edit" and "Quick Edit" — only "Edit with Elementor" remains
		unset( $actions['edit'] );
		unset( $actions['inline hide-if-no-js'] );

		if ( 'publish' !== $post->post_status ) { return $actions; }

		$type = get_post_meta( $post->ID, self::META_TYPE, true );

		// Settings action (always visible for published templates)
		$actions['sits_settings'] = '<a href="#" class="sits-open-settings" data-post-id="' . esc_attr( $post->ID ) . '">'
			. esc_html__( 'Settings', 'softech-addons-for-elementor' ) . '</a>';

		if ( ! $type ) { return $actions; }

		$active = $this->get_active_option();
		$is_act = $this->is_active( $post->ID, $type, $active );

		if ( $is_act ) {
			$n = wp_create_nonce( 'sits_deactivate_hf_' . $post->ID );
			$u = admin_url( 'admin-ajax.php?action=sits_deactivate_hf_template&template_id=' . $post->ID . '&type=' . $type . '&_wpnonce=' . $n );
			$actions['sits_deactivate'] = '<a href="' . esc_url( $u ) . '" class="sits-deactivate-hf-link" style="color:#dc2626;">'
				. esc_html__( 'Deactivate', 'softech-addons-for-elementor' ) . '</a>';
		}
		
		return $actions;
	}

	/* ================================================================== */
	/* Admin Assets                                                         */
	/* ================================================================== */

	public function enqueue_admin_assets() {
		global $post_type;
		if ( self::POST_TYPE !== $post_type ) { return; }
		wp_enqueue_style(  'sits-hf-admin', SITS_ELEMENTOR_ADDONS_PLUGIN_URL.'assets/css/hf-admin.css',  [], SITS_ELEMENTOR_ADDONS_VERSION);
		wp_enqueue_script( 'sits-hf-admin', SITS_ELEMENTOR_ADDONS_PLUGIN_URL.'assets/js/hf-admin.js',   ['jquery','wp-i18n'], SITS_ELEMENTOR_ADDONS_VERSION, true);
		wp_localize_script('sits-hf-admin', 'sitsHFAdmin', [
			'ajaxurl' => admin_url('admin-ajax.php'),
			'nonce'   => wp_create_nonce('sits_hf_admin_nonce'),
			'strings' => [
				'activating'         => __('Activating…',   'softech-addons-for-elementor'),
				'activated'          => __('Activated!',     'softech-addons-for-elementor'),
				'deactivating'       => __('Deactivating…', 'softech-addons-for-elementor'),
				'deactivated'        => __('Deactivated!',  'softech-addons-for-elementor'),
				'error'              => __('Request failed', 'softech-addons-for-elementor'),
				'confirm_deactivate' => __('Deactivate this template?', 'softech-addons-for-elementor'),
				'settingsSaved'      => __('Settings saved successfully!', 'softech-addons-for-elementor'),
				'entireSite'         => __('Entire Website', 'softech-addons-for-elementor'),
				'archive'            => __('All Archives', 'softech-addons-for-elementor'),
				'archivePost'        => __('Posts Archive', 'softech-addons-for-elementor'),
				'archiveAuthor'      => __('Author Archive', 'softech-addons-for-elementor'),
				'archiveDate'        => __('Date Archive', 'softech-addons-for-elementor'),
				'archiveSearch'      => __('Search Results', 'softech-addons-for-elementor'),
				'archiveCategory'    => __('Post Categories', 'softech-addons-for-elementor'),
				'archiveTag'         => __('Post Tags', 'softech-addons-for-elementor'),
				'createTemplate'     => __('CREATE TEMPLATE', 'softech-addons-for-elementor'),
				'createAndEdit'      => __('Create & Edit with Elementor', 'softech-addons-for-elementor'),
				'creating'           => __('Creating…', 'softech-addons-for-elementor'),
				'saving'              => __('Saving…', 'softech-addons-for-elementor'),
				'errorSelectType'     => __('Please select a template type.', 'softech-addons-for-elementor'),
				'archiveAll'          => __('All Archives', 'softech-addons-for-elementor'),
				'templateTitle'       => __('Template Title', 'softech-addons-for-elementor'),
				'templateTitlePlaceholder' => __('Enter template title…', 'softech-addons-for-elementor'),
				// Type labels
				'header'              => __('Header',      'softech-addons-for-elementor'),
				'footer'              => __('Footer',      'softech-addons-for-elementor'),
				'archiveType'         => __('Archive',     'softech-addons-for-elementor'),
				'singlePage'          => __('Single Page', 'softech-addons-for-elementor'),
				'singlePost'          => __('Single Post', 'softech-addons-for-elementor'),
				'page404'             => __('404 Page',    'softech-addons-for-elementor'),
				// Fix 3: new singular sub-type labels
				'singularPost'        => __('All Single Posts',  'softech-addons-for-elementor'),
				'singularPage'        => __('All Single Pages',  'softech-addons-for-elementor'),
				// Fix 4: archive term search
				'searchArchiveItems'  => __('Search…', 'softech-addons-for-elementor'),
				'noResults'           => __('No results found', 'softech-addons-for-elementor'),
				'blogIndexPage'       => __('Blog Index / Posts Listing Page', 'softech-addons-for-elementor'),
			]
		]);
	}

	
	public function redirect_add_new_to_elementor() {
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- standard WP admin page GET param, no nonce available here
		if ( ! isset( $_GET['post_type'] ) || self::POST_TYPE !== sanitize_key( wp_unslash( $_GET['post_type'] ) ) ) {
			return;
		}
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if ( isset( $_GET['sits_skip_redirect'] ) ) {
			return; // JS-initiated flow already handled via AJAX
		}
		if ( ! current_user_can( 'edit_posts' ) ) { return; }

		// Fallback: create a draft post and redirect straight to Elementor
		$post_id = wp_insert_post( [
			'post_title'  => __( 'New Template', 'softech-addons-for-elementor' ),
			'post_type'   => self::POST_TYPE,
			'post_status' => 'draft',
		] );

		if ( $post_id && ! is_wp_error( $post_id ) ) {
			wp_safe_redirect( admin_url( 'post.php?post=' . $post_id . '&action=elementor' ) );
			exit;
		}
	}

	
	public function ajax_create_hf_draft() {
		check_ajax_referer( 'sits_hf_admin_nonce', '_wpnonce' );
		if ( ! current_user_can( 'edit_posts' ) ) {
			wp_send_json_error( [ 'message' => __( 'Permission denied', 'softech-addons-for-elementor' ) ] );
		}

		$post_title = isset( $_POST['post_title'] ) ? sanitize_text_field( wp_unslash( $_POST['post_title'] ) ) : '';
		if ( empty( $post_title ) ) {
			$post_title = __( 'New Template', 'softech-addons-for-elementor' );
		}

		$post_id = wp_insert_post( [
			'post_title'  => $post_title,
			'post_type'   => self::POST_TYPE,
			'post_status' => 'draft',
		] );

		if ( ! $post_id || is_wp_error( $post_id ) ) {
			wp_send_json_error( [ 'message' => __( 'Could not create template draft.', 'softech-addons-for-elementor' ) ] );
		}

		wp_send_json_success( [
			'post_id'       => $post_id,
			'elementor_url' => admin_url( 'post.php?post=' . $post_id . '&action=elementor' ),
		] );
	}

	/* ================================================================== */
	/* Req #2: Enqueue panel JS inside Elementor editor for HF templates  */
	/* ================================================================== */

	public function enqueue_elementor_panel_assets() {
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- reading post ID from Elementor editor URL, no nonce available
		$post_id = isset( $_GET['post'] ) ? absint( wp_unslash( $_GET['post'] ) ) : 0;
		if ( ! $post_id || get_post_type( $post_id ) !== self::POST_TYPE ) {
			return;
		}

		wp_enqueue_script(
			'sits-hf-elementor-panel',
			SITS_ELEMENTOR_ADDONS_PLUGIN_URL . 'assets/js/hf-elementor-panel.js',
			[ 'jquery' ],
			SITS_ELEMENTOR_ADDONS_VERSION,
			true
		);
		wp_enqueue_style(
			'sits-hf-admin-panel',
			SITS_ELEMENTOR_ADDONS_PLUGIN_URL . 'assets/css/hf-admin.css',
			[],
			SITS_ELEMENTOR_ADDONS_VERSION
		);

		// Build current conditions data for popup pre-fill
		$type       = get_post_meta( $post_id, self::META_TYPE, true );
		$conditions = $this->build_conditions_for_js( $post_id );

		wp_localize_script( 'sits-hf-elementor-panel', 'sitsHFPanel', [
			'isHFTemplate'  => true,
			'postId'        => $post_id,
			'templateType'  => $type ?: '',
			'conditions'    => $conditions,
			'settingsSaved' => ( $type !== '' ),
			'ajaxurl'       => admin_url( 'admin-ajax.php' ),
			'nonce'         => wp_create_nonce( 'sits_hf_admin_nonce' ),
			'strings'       => [
				'publishSettings'      => __( 'PUBLISH SETTINGS', 'softech-addons-for-elementor' ),
				'templateType'         => __( 'Template Type', 'softech-addons-for-elementor' ),
				'selectType'           => __( '— Select Type —', 'softech-addons-for-elementor' ),
				'header'               => __( 'Header', 'softech-addons-for-elementor' ),
				'footer'               => __( 'Footer', 'softech-addons-for-elementor' ),
				'displayConditions'    => __( 'Display Conditions', 'softech-addons-for-elementor' ),
				'displayConditionsDesc'=> __( 'Set the conditions that determine where your template is displayed. For example, choose \'Entire Website\' to display everywhere.', 'softech-addons-for-elementor' ),
				'addCondition'         => __( 'Add condition', 'softech-addons-for-elementor' ),
				'include'              => __( 'Include', 'softech-addons-for-elementor' ),
				// phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude -- this is a UI label string, not a WP_Query parameter
				'exclude'              => __( 'Exclude', 'softech-addons-for-elementor' ),
				'entireSite'           => __( 'Entire Website', 'softech-addons-for-elementor' ),
				'frontPage'            => __( 'Front Page', 'softech-addons-for-elementor' ),
				'blog'                 => __( 'Blog / Posts Page', 'softech-addons-for-elementor' ),
				'singular'             => __( 'All Singular', 'softech-addons-for-elementor' ),
				'archive'              => __( 'All Archives', 'softech-addons-for-elementor' ),
				'archivePost'          => __( 'Posts Archive', 'softech-addons-for-elementor' ),
				'archiveAuthor'        => __( 'Author Archive', 'softech-addons-for-elementor' ),
				'archiveDate'          => __( 'Date Archive', 'softech-addons-for-elementor' ),
				'archiveSearch'        => __( 'Search Results', 'softech-addons-for-elementor' ),
				'archiveCategory'      => __( 'Post Categories', 'softech-addons-for-elementor' ),
				'archiveTag'           => __( 'Post Tags', 'softech-addons-for-elementor' ),
				'archiveAll'           => __( 'All Archives', 'softech-addons-for-elementor' ),
				'notFound'             => __( '404 Page', 'softech-addons-for-elementor' ),
				'cancel'               => __( 'Cancel', 'softech-addons-for-elementor' ),
				'savePublish'          => __( 'Save & Publish', 'softech-addons-for-elementor' ),
				'checking'             => __( 'Checking…', 'softech-addons-for-elementor' ),
				'saving'               => __( 'Saving…', 'softech-addons-for-elementor' ),
				'saveError'            => __( 'Save failed. Please try again.', 'softech-addons-for-elementor' ),
				'errorSelectType'      => __( 'Please select a template type.', 'softech-addons-for-elementor' ),
				'noResults'            => __( 'No results found', 'softech-addons-for-elementor' ),
				'searchPlaceholder'    => __( 'Search posts or pages…', 'softech-addons-for-elementor' ),
			],
		] );
	}

	/**
	 * Build conditions array for JavaScript popup pre-fill.
	 */
	private function build_conditions_for_js( $post_id ) {
		$template_type      = get_post_meta( $post_id, self::META_TYPE, true );
		$allowed_conditions = array_keys( $this->get_display_conditions_for_type( $template_type ) );
		$display_on          = (array) get_post_meta( $post_id, self::META_DISPLAY_ON,   true );
		$exclude_on          = (array) get_post_meta( $post_id, self::META_EXCLUDE_ON,   true );
		$specific_ids        = (array) get_post_meta( $post_id, self::META_SPECIFIC_IDS, true );
		$exclude_ids         = (array) get_post_meta( $post_id, self::META_EXCLUDE_IDS,  true );
		$display_arch_terms  = (array) get_post_meta( $post_id, self::META_DISPLAY_ARCHIVE_TERMS, true );
		$exclude_arch_terms  = (array) get_post_meta( $post_id, self::META_EXCLUDE_ARCHIVE_TERMS, true );
		$arch_term_types     = [ 'archive_category', 'archive_tag', 'archive_author' ];
		$display_on          = $this->normalize_display_conditions_for_template( $template_type, $display_on );
		$exclude_on          = array_values( array_diff( array_intersect( $exclude_on, $allowed_conditions ), $display_on ) );

		$rows = [];

		foreach ( $display_on as $cond ) {
			if ( ! in_array( $cond, $allowed_conditions, true ) ) {
				continue;
			}
			$specific = [];
			if ( 'singular' === $cond ) {
				foreach ( $specific_ids as $sid ) {
					$p = get_post( absint( $sid ) );
					if ( $p ) { $specific[] = [ 'id' => $p->ID, 'title' => $p->post_title, 'type' => $p->post_type ]; }
				}
			}
			// Fix 4: load archive-term-specific items
			$arch_specific = [];
			if ( in_array( $cond, $arch_term_types, true ) ) {
				$term_ids = $display_arch_terms[ $cond ] ?? [];
				foreach ( $term_ids as $tid_raw ) {
					$tid_raw = sanitize_text_field( $tid_raw );
					if ( 'archive_author' === $cond ) {
						$u = get_userdata( (int) $tid_raw );
						if ( $u ) { $arch_specific[] = [ 'id' => $tid_raw, 'title' => $u->display_name, 'type' => 'author' ]; }
					} else {
						$tax  = ( 'archive_category' === $cond ) ? 'category' : 'post_tag';
						$term = get_term( (int) $tid_raw, $tax );
						if ( $term && ! is_wp_error( $term ) ) {
							$type_label = ( 'archive_category' === $cond ) ? 'category' : 'tag';
							$arch_specific[] = [ 'id' => $tid_raw, 'title' => $term->name, 'type' => $type_label ];
						}
					}
				}
			}
			$rows[] = [ 'include' => 'include', 'condition' => $cond, 'specific' => $specific, 'archSpecific' => $arch_specific ];
		}

		foreach ( $exclude_on as $cond ) {
			if ( ! in_array( $cond, $allowed_conditions, true ) ) {
				continue;
			}
			$specific = [];
			if ( 'singular' === $cond ) {
				foreach ( $exclude_ids as $eid ) {
					$p = get_post( absint( $eid ) );
					if ( $p ) { $specific[] = [ 'id' => $p->ID, 'title' => $p->post_title, 'type' => $p->post_type ]; }
				}
			}
			$arch_specific = [];
			if ( in_array( $cond, $arch_term_types, true ) ) {
				$term_ids = $exclude_arch_terms[ $cond ] ?? [];
				foreach ( $term_ids as $tid_raw ) {
					$tid_raw = sanitize_text_field( $tid_raw );
					if ( 'archive_author' === $cond ) {
						$u = get_userdata( (int) $tid_raw );
						if ( $u ) { $arch_specific[] = [ 'id' => $tid_raw, 'title' => $u->display_name, 'type' => 'author' ]; }
					} else {
						$tax  = ( 'archive_category' === $cond ) ? 'category' : 'post_tag';
						$term = get_term( (int) $tid_raw, $tax );
						if ( $term && ! is_wp_error( $term ) ) {
							$type_label = ( 'archive_category' === $cond ) ? 'category' : 'tag';
							$arch_specific[] = [ 'id' => $tid_raw, 'title' => $term->name, 'type' => $type_label ];
						}
					}
				}
			}
			$rows[] = [ 'include' => 'exclude', 'condition' => $cond, 'specific' => $specific, 'archSpecific' => $arch_specific ];
		}

		return $rows;
	}

	/* ================================================================== */
	/* AJAX: Get template settings (for popup pre-fill on listing page)   */
	/* ================================================================== */

	public function ajax_get_settings() {
		check_ajax_referer( 'sits_hf_admin_nonce', '_wpnonce' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( [ 'message' => __( 'Permission denied', 'softech-addons-for-elementor' ) ] );
		}

		$post_id = isset( $_POST['post_id'] ) ? absint( wp_unslash( $_POST['post_id'] ) ) : 0;
		if ( ! $post_id || get_post_type( $post_id ) !== self::POST_TYPE ) {
			wp_send_json_error( [ 'message' => __( 'Invalid post', 'softech-addons-for-elementor' ) ] );
		}

		$type       = get_post_meta( $post_id, self::META_TYPE, true );
		$conditions = $this->build_conditions_for_js( $post_id );

		wp_send_json_success( [
			'template_type' => $type ?: '',
			'conditions'    => $conditions,
		] );
	}

	/* ================================================================== */
	/* AJAX: Save template settings from popup                            */
	/* ================================================================== */

	public function ajax_save_template_settings() {
		check_ajax_referer( 'sits_hf_admin_nonce', '_wpnonce' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( [ 'message' => __( 'Permission denied', 'softech-addons-for-elementor' ) ] );
		}

		$post_id = isset( $_POST['post_id'] ) ? absint( wp_unslash( $_POST['post_id'] ) ) : 0;
		if ( ! $post_id || get_post_type( $post_id ) !== self::POST_TYPE ) {
			wp_send_json_error( [ 'message' => __( 'Invalid post', 'softech-addons-for-elementor' ) ] );
		}

		$template_type = isset( $_POST['template_type'] ) ? sanitize_text_field( wp_unslash( $_POST['template_type'] ) ) : '';
		if ( ! in_array( $template_type, [ 'header', 'footer', 'archive', 'single_page', 'single_post', '404_page' ], true ) ) {
			wp_send_json_error( [ 'message' => __( 'Invalid template type', 'softech-addons-for-elementor' ) ] );
		}

		$raw_conditions = isset( $_POST['conditions'] ) ? sanitize_text_field( wp_unslash( $_POST['conditions'] ) ) : '{}';
		$conditions     = json_decode( $raw_conditions, true );
		if ( ! is_array( $conditions ) ) {
			wp_send_json_error( [ 'message' => __( 'Invalid conditions data', 'softech-addons-for-elementor' ) ] );
		}

		// force_save=1 means the user confirmed saving despite errors (e.g. conflict)
		$force_save = ! empty( $_POST['force_save'] );

		$valid_conds = [ 'all', 'singular', 'singular_post', 'singular_page', 'archive', 'archive_post', 'archive_author', 'archive_date', 'archive_search', 'archive_category', 'archive_tag', 'front_page', 'blog', '404' ];

		$display_on   = [];
		$exclude_on   = [];
		$specific_ids = [];
		$exclude_ids  = [];
		$display_archive_terms = [];
		$exclude_archive_terms = [];

		if ( ! empty( $conditions['display_on'] ) ) {
			foreach ( array_map( 'sanitize_text_field', $conditions['display_on'] ) as $c ) {
				if ( in_array( $c, $valid_conds, true ) ) { $display_on[] = $c; }
			}
		}
		if ( ! empty( $conditions['exclude_on'] ) ) {
			foreach ( array_map( 'sanitize_text_field', $conditions['exclude_on'] ) as $c ) {
				if ( in_array( $c, $valid_conds, true ) && ! in_array( $c, $display_on, true ) ) { $exclude_on[] = $c; }
			}
		}
		if ( ! empty( $conditions['specific_ids'] ) ) {
			$specific_ids = $this->sanitize_ids( $conditions['specific_ids'] );
		}
		if ( ! empty( $conditions['exclude_ids'] ) ) {
			$exclude_ids = $this->sanitize_ids( $conditions['exclude_ids'] );
		}

		$display_on = $this->normalize_display_conditions_for_template( $template_type, $display_on );
		$allowed_display_on = array_keys( $this->get_display_conditions_for_type( $template_type ) );
		$exclude_on = array_values(
			array_filter(
				$exclude_on,
				function ( $loc ) use ( $allowed_display_on, $display_on ) {
					return in_array( $loc, $allowed_display_on, true ) && ! in_array( $loc, $display_on, true );
				}
			)
		);

		// Fix 4: Save archive-sub-type term IDs (categories, tags, authors)
		$archive_term_types = [ 'archive_category', 'archive_tag', 'archive_author' ];
		if ( ! empty( $conditions['archive_terms_include'] ) && is_array( $conditions['archive_terms_include'] ) ) {
			foreach ( $archive_term_types as $at ) {
				if ( ! empty( $conditions['archive_terms_include'][ $at ] ) ) {
					$display_archive_terms[ $at ] = array_map( 'sanitize_text_field', (array) $conditions['archive_terms_include'][ $at ] );
				}
			}
		}
		if ( ! empty( $conditions['archive_terms_exclude'] ) && is_array( $conditions['archive_terms_exclude'] ) ) {
			foreach ( $archive_term_types as $at ) {
				if ( ! empty( $conditions['archive_terms_exclude'][ $at ] ) ) {
					$exclude_archive_terms[ $at ] = array_map( 'sanitize_text_field', (array) $conditions['archive_terms_exclude'][ $at ] );
				}
			}
		}

		// Save meta
		update_post_meta( $post_id, self::META_TYPE,                 $template_type );
		update_post_meta( $post_id, self::META_DISPLAY_ON,           $display_on );
		update_post_meta( $post_id, self::META_EXCLUDE_ON,           $exclude_on );
		update_post_meta( $post_id, self::META_SPECIFIC_IDS,         $specific_ids );
		update_post_meta( $post_id, self::META_EXCLUDE_IDS,          $exclude_ids );
		update_post_meta( $post_id, self::META_DISPLAY_ARCHIVE_TERMS, $display_archive_terms );
		update_post_meta( $post_id, self::META_EXCLUDE_ARCHIVE_TERMS, $exclude_archive_terms );

		// Bug #6 FIX: Only auto-publish when publish_now=1 (called from Elementor panel popup).
		// When called from the listing-page "Create Template" popup (no publish_now flag),
		// keep the post as draft so the user can design it in Elementor before publishing.
		$publish_now = ! empty( $_POST['publish_now'] );
		$post        = get_post( $post_id );

		if ( ! $post ) {
			wp_send_json_error( [ 'message' => __( 'Invalid post.', 'softech-addons-for-elementor' ) ] );
		}

		// ---------------------------------------------------------------
		// Run the conflict check BEFORE the draft early-exit for ALL template types.
		// Previously this only ran for header/footer, so 404_page / single_post /
		// archive / single_page never showed a conflict error when creating a second
		// template with the same display conditions — the draft early-exit fired first
		// and returned success without ever checking for conflicts.
		//
		// - force_save=0 → return conflict error with override checkbox
		// - force_save=1 → deactivate conflicting template now so that when this
		//   draft is published the activation succeeds cleanly
		// ---------------------------------------------------------------
		if ( ! $force_save ) {
			$conflict_id = $this->find_condition_conflict( $post_id, $template_type );
			if ( $conflict_id ) {
				$conflict_post  = get_post( $conflict_id );
				$conflict_title = $conflict_post ? $conflict_post->post_title : '#' . $conflict_id;
				wp_send_json_error( [
					'conflict' => true,
					'message'  => sprintf(
						/* translators: %s: conflicting template title */
						__( 'Conflict: "%s" is already active with the same conditions. Deactivate it first, or use different conditions. You can also check the box below to save anyway — the conflicting template will be set to Draft and deactivated automatically.', 'softech-addons-for-elementor' ),
						$conflict_title
					),
				] );
			}
		} else {
			// force_save=1: pre-emptively deactivate conflicting active templates
			// so that when this draft is later published, activation succeeds.
			$opt_pre      = $this->get_active_option();
			$existing_pre = array_diff( $opt_pre[ $template_type ] ?? [], [ absint( $post_id ) ] );
			$new_disp_pre = (array) get_post_meta( $post_id, self::META_DISPLAY_ON,   true );
			$new_spec_pre = array_map( 'absint', (array) get_post_meta( $post_id, self::META_SPECIFIC_IDS, true ) );

			foreach ( $existing_pre as $eid_pre ) {
				$eid_pre = absint( $eid_pre );
				if ( 'publish' !== get_post_status( $eid_pre ) ) {
					continue;
				}
				$ex_disp_pre = (array) get_post_meta( $eid_pre, self::META_DISPLAY_ON,   true );
				$ex_spec_pre = array_map( 'absint', (array) get_post_meta( $eid_pre, self::META_SPECIFIC_IDS, true ) );
				if ( $this->conditions_overlap( $new_disp_pre, $new_spec_pre, $ex_disp_pre, $ex_spec_pre ) ) {
					$opt_pre[ $template_type ] = array_values( array_diff( $opt_pre[ $template_type ], [ $eid_pre ] ) );
					wp_update_post( [ 'ID' => $eid_pre, 'post_status' => 'draft' ] );
				}
			}
			update_option( self::OPTION_ACTIVE, $opt_pre );
		}

		if ( 'publish' !== $post->post_status && ! $publish_now ) {
			// Draft + not requesting publish → just save meta and return.
			$this->sync_single( $post_id );
			wp_send_json_success( [
				'message' => __( 'Settings saved. Template will be activated when you publish in Elementor.', 'softech-addons-for-elementor' ),
			] );
		}

		// For publish_now=1 (Elementor panel): publish the draft now.
		if ( 'publish' !== $post->post_status && $publish_now ) {
			wp_update_post( [ 'ID' => $post_id, 'post_status' => 'publish' ] );
		}

		// ---------------------------------------------------------------
		// IMPORTANT: Do NOT remove the template from the old type's active
		// list yet. We must run the conflict check first. If a conflict is
		// found and force_save is not set, we return an error and the
		// template must remain active under its original type so the site
		// continues to work. Removing it here (before the conflict check)
		// was the root cause of templates disappearing from both header and
		// footer when a type-change was attempted but blocked by a conflict.
		// ---------------------------------------------------------------

		// AUTO-ACTIVATE: saving settings always activates this template.
		// If there is a conflict and force_save is NOT set, return a conflict error.
		// The meta has already been updated above (so conditions/type are stored),
		// but the active-option is NOT changed until after this check passes.
		// Note: For header/footer types, the conflict check already ran above
		// (before the draft early-exit). For published posts / publish_now we
		// still run it here to handle the full activation flow.
		if ( ! $force_save ) {
			$conflict_id = $this->find_condition_conflict( $post_id, $template_type );
			if ( $conflict_id ) {
				// Roll back the META_TYPE to what it was before so the template
				// stays correctly typed as its original type in the DB.
				$original_type = ( 'header' === $template_type ) ? 'footer' : 'header';
				$opt_check     = $this->get_active_option();
				if ( in_array( absint( $post_id ), $opt_check[ $original_type ] ?? [], true ) ) {
					// Template was originally the other type and is still active there – restore the meta type.
					update_post_meta( $post_id, self::META_TYPE, $original_type );
				}

				$conflict_post  = get_post( $conflict_id );
				$conflict_title = $conflict_post ? $conflict_post->post_title : '#' . $conflict_id;
				wp_send_json_error( [
					'conflict' => true,
					'message'  => sprintf(
						/* translators: %s: conflicting template title */
						__( 'Conflict: "%s" is already active with the same conditions. Deactivate it first, or use different conditions. You can also check the box below to save anyway — the conflicting template will be set to Draft and deactivated automatically.', 'softech-addons-for-elementor' ),
						$conflict_title
					),
				] );
			}
		}

		// No conflict (or user confirmed force_save). Now it is safe to:
		//   1. Remove template from the OLD type's active list (if the type changed).
		//   2. Deactivate conflicting templates of the new type (force_save only).
		//   3. Add template to the new type's active list.

		$opt           = $this->get_active_option();
		$opposite_type = ( 'header' === $template_type ) ? 'footer' : 'header';

		// Step 1 – remove from old type if the type actually changed.
		if ( in_array( absint( $post_id ), $opt[ $opposite_type ] ?? [], true ) ) {
			$opt[ $opposite_type ] = array_values( array_diff( $opt[ $opposite_type ], [ absint( $post_id ) ] ) );
			update_option( self::OPTION_ACTIVE, $opt );
		}

		// Step 2 – force_save: deactivate ALL conflicting active templates of same type and set them to draft.
		if ( $force_save ) {
			$opt          = $this->get_active_option(); // re-read after possible step-1 write
			$existing_ids = array_diff( $opt[ $template_type ] ?? [], [ absint( $post_id ) ] );
			$new_disp     = (array) get_post_meta( $post_id, self::META_DISPLAY_ON,   true );
			$new_spec     = array_map( 'absint', (array) get_post_meta( $post_id, self::META_SPECIFIC_IDS, true ) );

			foreach ( $existing_ids as $eid ) {
				$eid     = absint( $eid );
				$ex_disp = (array) get_post_meta( $eid, self::META_DISPLAY_ON,   true );
				$ex_spec = array_map( 'absint', (array) get_post_meta( $eid, self::META_SPECIFIC_IDS, true ) );

				if ( $this->conditions_overlap( $new_disp, $new_spec, $ex_disp, $ex_spec ) ) {
					$opt[ $template_type ] = array_values( array_diff( $opt[ $template_type ], [ $eid ] ) );
					wp_update_post( [ 'ID' => $eid, 'post_status' => 'draft' ] );
				}
			}
			update_option( self::OPTION_ACTIVE, $opt );
		}

		// Step 3 – activate this template under its (possibly new) type.
		$opt = $this->get_active_option();
		if ( ! in_array( $post_id, $opt[ $template_type ], true ) ) {
			$opt[ $template_type ][] = $post_id;
			update_option( self::OPTION_ACTIVE, $opt );
		}

		$this->sync_single( $post_id );

		wp_send_json_success( [
			'message' => __( 'Settings saved and template activated.', 'softech-addons-for-elementor' ),
		] );
	}

	/* ================================================================== */
	/* AJAX: Check conditions conflict (without saving)                   */
	/* ================================================================== */

	public function ajax_check_conflict() {
		check_ajax_referer( 'sits_hf_admin_nonce', '_wpnonce' );
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( [ 'message' => __( 'Permission denied', 'softech-addons-for-elementor' ) ] );
		}

		$post_id       = isset( $_POST['post_id'] )       ? absint( wp_unslash( $_POST['post_id'] ) ) : 0;
		$template_type = isset( $_POST['template_type'] ) ? sanitize_text_field( wp_unslash( $_POST['template_type'] ) ) : '';

		if ( ! in_array( $template_type, [ 'header', 'footer' ], true ) ) {
			wp_send_json_success( [ 'conflict' => false ] ); // Can't check without valid type
		}

		$raw_conditions = isset( $_POST['conditions'] ) ? sanitize_text_field( wp_unslash( $_POST['conditions'] ) ) : '{}';
		$conditions     = json_decode( $raw_conditions, true );
		if ( ! is_array( $conditions ) ) {
			wp_send_json_success( [ 'conflict' => false ] );
		}

		$display_on   = array_map( 'sanitize_text_field', (array) ( $conditions['display_on'] ?? [] ) );
		$specific_ids = $this->sanitize_ids( $conditions['specific_ids'] ?? [] );

		// Check against other ACTIVE templates of same type
		$opt          = $this->get_active_option();
		$existing_ids = array_diff( $opt[ $template_type ] ?? [], [ absint( $post_id ) ] );

		foreach ( $existing_ids as $eid ) {
			$eid     = absint( $eid );

			// Skip trashed / non-published templates (same guard as find_condition_conflict).
			if ( 'publish' !== get_post_status( $eid ) ) {
				continue;
			}

			$ex_disp = (array) get_post_meta( $eid, self::META_DISPLAY_ON,   true );
			$ex_spec = array_map( 'absint', (array) get_post_meta( $eid, self::META_SPECIFIC_IDS, true ) );

			if ( $this->conditions_overlap( $display_on, $specific_ids, $ex_disp, $ex_spec ) ) {
				$p = get_post( $eid );
				$title = $p ? $p->post_title : '#' . $eid;
				wp_send_json_error( [
					'conflict' => true,
					'message'  => sprintf(
						/* translators: %s: conflicting template title */
						__( 'Conflict: "%s" is already active with the same conditions. Deactivate it first, or use different conditions.', 'softech-addons-for-elementor' ),
						$title
					),
				] );
			}
		}

		wp_send_json_success( [ 'conflict' => false ] );
	}

	/* ================================================================== */
	/* AJAX – Activate (Fix 2: conflict check)                             */
	/* ================================================================== */

	public function ajax_activate_template() {
		$this->ajax_gate();
		$tid  = isset( $_REQUEST['template_id'] ) ? absint( wp_unslash( $_REQUEST['template_id'] ) ) : 0;
		$type = isset( $_REQUEST['type'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['type'] ) ) : '';

		if ( ! $tid ) {
			wp_send_json_error( [ 'message' => __( 'Invalid template ID', 'softech-addons-for-elementor' ) ] );
		}

		if ( ! isset( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'sits_activate_hf_' . $tid ) ) {
			wp_send_json_error(['message'=>__('Security check failed','softech-addons-for-elementor')]);
		}
		if (!in_array($type, self::ALL_TYPES, true)) {
			wp_send_json_error(['message'=>__('Invalid type','softech-addons-for-elementor')]);
		}

		// Fix 2: block if conditions conflict with an existing active template
		$conflict = $this->find_condition_conflict($tid, $type);
		if ($conflict) {
			$conflict_post = get_post($conflict);
			$conflict_title = $conflict_post ? $conflict_post->post_title : '#' . $conflict;
			wp_send_json_error([
				'message'  => sprintf(
					/* translators: %s: conflicting template title */
					__('Cannot activate: "%s" is already active with overlapping Display On conditions. Deactivate it first or use different conditions.', 'softech-addons-for-elementor'),
					$conflict_title
				),
				'conflict' => true,
			]);
		}

		$opt = $this->get_active_option();
		if (!in_array($tid, $opt[$type], true)) {
			$opt[$type][] = $tid;
		}
		update_option(self::OPTION_ACTIVE, $opt);
		$this->sync_single($tid);

		$redir = add_query_arg(['post_type'=>self::POST_TYPE,'sits_activated'=>$tid,'_sits_notice_nonce'=>wp_create_nonce('sits_activation_notice')], admin_url('edit.php'));
		if (wp_doing_ajax()) { wp_send_json_success(['message'=>'ok','redirect'=>$redir]); }
		wp_safe_redirect($redir); exit;
	}

	/* ================================================================== */
	/* AJAX – Deactivate                                                    */
	/* ================================================================== */

	public function ajax_deactivate_template() {
		$this->ajax_gate();
		$tid  = isset( $_REQUEST['template_id'] ) ? absint( wp_unslash( $_REQUEST['template_id'] ) ) : 0;
		$type = isset( $_REQUEST['type'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['type'] ) ) : '';

		if ( ! $tid ) {
			wp_send_json_error( [ 'message' => __( 'Invalid template ID', 'softech-addons-for-elementor' ) ] );
		}

		if ( ! isset( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'sits_deactivate_hf_' . $tid ) ) {
			wp_send_json_error(['message'=>__('Security check failed','softech-addons-for-elementor')]);
		}
		if (!in_array($type, self::ALL_TYPES, true)) {
			wp_send_json_error(['message'=>__('Invalid type','softech-addons-for-elementor')]);
		}

		$opt = $this->get_active_option();
		$opt[$type] = array_values(array_diff($opt[$type], [$tid]));
		update_option(self::OPTION_ACTIVE, $opt);

		$redir = add_query_arg(['post_type'=>self::POST_TYPE,'sits_deactivated'=>$tid,'_sits_notice_nonce'=>wp_create_nonce('sits_deactivation_notice')], admin_url('edit.php'));
		if (wp_doing_ajax()) { wp_send_json_success(['message'=>'ok','redirect'=>$redir]); }
		wp_safe_redirect($redir); exit;
	}

	/* ================================================================== */
	/* AJAX – Search Posts / Pages                                          */
	/* ================================================================== */

	public function ajax_search_posts_pages() {
		check_ajax_referer('sits_hf_admin_nonce','nonce');
		if (!current_user_can('edit_posts')) { wp_send_json_error(); }

		$s = isset($_POST['search']) ? sanitize_text_field(wp_unslash($_POST['search'])) : '';
		if (strlen($s) < 2) {
			wp_send_json_success(['results' => [], 'total' => 0, 'pages' => 0]);
			return;
		}

		// Support optional page offset so the JS can load further results if needed.
		$paged = isset($_POST['paged']) ? max(1, intval(wp_unslash($_POST['paged']))) : 1;

		$q = new \WP_Query([
			's'              => $s,
			'post_type'      => ['post', 'page'],
			'post_status'    => 'publish',
			'posts_per_page' => 20,
			'paged'          => $paged,
			'orderby'        => 'relevance',
			'no_found_rows'  => false, // required for $q->found_posts and $q->max_num_pages
		]);

		$r = [];
		foreach ($q->posts as $post) {
			$r[] = [
				'id'    => $post->ID,
				'title' => $post->post_title,
				'type'  => $post->post_type,
			];
		}
		wp_reset_postdata();

		wp_send_json_success([
			'results' => $r,
			'total'   => (int) $q->found_posts,   // total matching posts (for JS to decide whether to show "load more")
			'pages'   => (int) $q->max_num_pages,  // total pages available
		]);
	}

	/**
	 * Fix 4: Search categories, tags, or authors for archive-sub-type condition specific items.
	 */
	public function ajax_search_archive_items() {
		check_ajax_referer( 'sits_hf_admin_nonce', 'nonce' );
		if ( ! current_user_can( 'edit_posts' ) ) { wp_send_json_error(); }

		$type   = isset( $_POST['type'] )   ? sanitize_key( wp_unslash( $_POST['type'] ) ) : '';
		$search = isset( $_POST['search'] ) ? sanitize_text_field( wp_unslash( $_POST['search'] ) ) : '';
		$results = [];

		switch ( $type ) {
			case 'archive_category':
				$terms = get_terms( [ 'taxonomy' => 'category', 'search' => $search, 'number' => 20, 'hide_empty' => false ] );
				if ( ! is_wp_error( $terms ) ) {
					foreach ( $terms as $term ) {
						$results[] = [ 'id' => (string) $term->term_id, 'title' => $term->name . ' (' . $term->count . ')', 'type' => 'category' ];
					}
				}
				break;

			case 'archive_tag':
				$terms = get_terms( [ 'taxonomy' => 'post_tag', 'search' => $search, 'number' => 20, 'hide_empty' => false ] );
				if ( ! is_wp_error( $terms ) ) {
					foreach ( $terms as $term ) {
						$results[] = [ 'id' => (string) $term->term_id, 'title' => $term->name . ' (' . $term->count . ')', 'type' => 'tag' ];
					}
				}
				break;

			case 'archive_author':
				$users = get_users( [
					'search'         => '*' . $search . '*',
					'search_columns' => [ 'user_login', 'user_nicename', 'display_name', 'user_email' ],
					'number'         => 20,
				] );
				foreach ( $users as $user ) {
					$results[] = [ 'id' => (string) $user->ID, 'title' => $user->display_name . ' (' . $user->user_login . ')', 'type' => 'author' ];
				}
				break;
		}

		wp_send_json_success( [ 'results' => $results ] );
	}

	/* ================================================================== */
	/* Fix 7: Auto-deactivate on trash / delete                            */
	/* ================================================================== */

	public function maybe_deactivate_on_trash_delete( $post_id ) {
		if ( get_post_type($post_id) !== self::POST_TYPE ) { return; }

		$type = get_post_meta($post_id, self::META_TYPE, true);
		if (!$type) { return; }

		$opt = $this->get_active_option();
		if (in_array(absint($post_id), $opt[$type] ?? [], true)) {
			$opt[$type] = array_values(array_diff($opt[$type], [absint($post_id)]));
			update_option(self::OPTION_ACTIVE, $opt);
		}

		// Also delete the Pro mirror if it exists
		$mirror_id = get_post_meta($post_id, self::META_MIRROR_ID, true);
		if ($mirror_id && get_post($mirror_id)) {
			wp_delete_post($mirror_id, true); // force delete mirror
		}
	}

	/* ================================================================== */
	/* Admin Notices                                                        */
	/* ================================================================== */

	public function activation_admin_notice() {
		$scr = get_current_screen();
		if (!$scr || self::POST_TYPE !== $scr->post_type || 'edit' !== $scr->base) { return; }
		// phpcs:disable WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput
		if (isset($_GET['sits_activated'],$_GET['_sits_notice_nonce']) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_sits_notice_nonce'] ) ), 'sits_activation_notice')) {
			if ($tpl = get_post(absint($_GET['sits_activated']))) {
				// translators: %s: template post title
			echo '<div class="notice notice-success is-dismissible"><p>' . sprintf(esc_html__('Template "%s" activated!','softech-addons-for-elementor'),'<strong>'.esc_html($tpl->post_title).'</strong>') . '</p></div>';
			}
		}
		if (isset($_GET['sits_deactivated'],$_GET['_sits_notice_nonce']) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_sits_notice_nonce'] ) ), 'sits_deactivation_notice')) {
			if ($tpl = get_post(absint($_GET['sits_deactivated']))) {
				// translators: %s: template post title
			echo '<div class="notice notice-info is-dismissible"><p>' . sprintf(esc_html__('Template "%s" deactivated.','softech-addons-for-elementor'),'<strong>'.esc_html($tpl->post_title).'</strong>') . '</p></div>';
			}
		}
		// phpcs:enable
	}

	/* ================================================================== */
	/* Type Tabs — rendered via admin_notices (Issue 4 fix)               */
	/* ================================================================== */

	/**
	 * Output our custom type tabs via admin_notices so they appear in their
	 * own block ABOVE WP's native "Published | Trash" views row.
	 */
	public function render_type_tabs_block() {
		global $pagenow;
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if ( 'edit.php' !== $pagenow || ! isset( $_GET['post_type'] ) || self::POST_TYPE !== sanitize_key( wp_unslash( $_GET['post_type'] ) ) ) {
			return;
		}
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$current_tab = isset( $_GET['sits_tab'] ) ? sanitize_key( wp_unslash( $_GET['sits_tab'] ) ) : '';
		$base_url    = admin_url( 'edit.php?post_type=' . self::POST_TYPE );

		$tab_defs = [
			''            => __( 'All',         'softech-addons-for-elementor' ),
			'header'      => __( 'Header',       'softech-addons-for-elementor' ),
			'footer'      => __( 'Footer',       'softech-addons-for-elementor' ),
			'archive'     => __( 'Archive',      'softech-addons-for-elementor' ),
			'single_page' => __( 'Single Page',  'softech-addons-for-elementor' ),
			'single_post' => __( 'Single Post',  'softech-addons-for-elementor' ),
			'404_page'    => __( '404 Page',     'softech-addons-for-elementor' ),
		];

		// Output the tabs container.
		// Start hidden — JS removes the inline display:none after moving
		// it to its correct position after .wp-header-end.
		echo '<div id="sits-type-tabs-container" class="sits-type-tabs-wrap" style="display:none;">';
		foreach ( $tab_defs as $tab_val => $tab_label ) {
			$url       = $tab_val ? add_query_arg( 'sits_tab', $tab_val, $base_url ) : $base_url;
			$is_active = ( $tab_val === $current_tab );
			$class     = $is_active ? 'sits-type-tab sits-type-tab--active' : 'sits-type-tab';
			$dot_key   = $tab_val ?: 'all';
			$dot       = '<span class="sits-tab-dot sits-tab-dot-' . esc_attr( $dot_key ) . '"></span>';
            $dot_kses  = wp_kses( $dot, [ 'span' => [ 'class' => [] ] ] );
            echo '<a href="' . esc_url( $url ) . '" class="' . esc_attr( $class ) . '">' . $dot_kses . esc_html( $tab_label ) . '</a>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $dot_kses is sanitized via wp_kses().
		}
		echo '</div>';
	}

	/**
	 * Keep WP's native Published/Trash views row unchanged (Issue 4).
	 * Our type tabs are now rendered separately via render_type_tabs_block().
	 *
	 * @param array $views WP views array.
	 * @return array Unmodified $views.
	 */
	public function add_type_tab_views( $views ) {
		return $views;
	}

	/**
	 * Apply type tab filter to the list-table query.
	 *
	 * @param \WP_Query $query The current WP_Query object.
	 */
	public function apply_tab_filter( $query ) {
		global $pagenow;
		if ( ! is_admin() || 'edit.php' !== $pagenow || ! $query->is_main_query() ) {
			return;
		}
		// phpcs:disable WordPress.Security.NonceVerification.Recommended
		if ( ! isset( $_GET['post_type'] ) || self::POST_TYPE !== sanitize_key( wp_unslash( $_GET['post_type'] ) ) ) {
			return;
		}
		$tab = isset( $_GET['sits_tab'] ) ? sanitize_key( wp_unslash( $_GET['sits_tab'] ) ) : '';
		// phpcs:enable
		if ( ! $tab || ! in_array( $tab, self::ALL_TYPES, true ) ) {
			return;
		}
		$meta_query   = (array) $query->get( 'meta_query' );
		$meta_query[] = [
			'key'     => self::META_TYPE,
			'value'   => $tab,
			'compare' => '=',
		];
		$query->set( 'meta_query', $meta_query );
	}

	/* ================================================================== */
	/* Active / Inactive Status Filter (restored — Issue 4)               */
	/* ================================================================== */

	/**
	 * Output Active / Inactive status filter dropdown via restrict_manage_posts.
	 *
	 * @param string $post_type Current post type.
	 */
	public function add_status_filter_dropdown( $post_type ) {
		if ( self::POST_TYPE !== $post_type ) {
			return;
		}
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$selected = isset( $_GET['sits_hf_filter_status'] ) ? sanitize_key( wp_unslash( $_GET['sits_hf_filter_status'] ) ) : '';
		?>
		<select name="sits_hf_filter_status" id="sits-hf-filter-status">
			<option value=""><?php esc_html_e( 'Status', 'softech-addons-for-elementor' ); ?></option>
			<option value="active"   <?php selected( $selected, 'active' ); ?>><?php esc_html_e( 'Active',   'softech-addons-for-elementor' ); ?></option>
			<option value="inactive" <?php selected( $selected, 'inactive' ); ?>><?php esc_html_e( 'Inactive', 'softech-addons-for-elementor' ); ?></option>
		</select>
		<?php
	}

	/**
	 * Apply Active/Inactive status filter to the list query.
	 *
	 * @param \WP_Query $query The current WP_Query object.
	 */
	public function apply_status_filter( $query ) {
		global $pagenow;
		if ( ! is_admin() || 'edit.php' !== $pagenow || ! $query->is_main_query() ) {
			return;
		}
		// phpcs:disable WordPress.Security.NonceVerification.Recommended
		if ( ! isset( $_GET['post_type'] ) || self::POST_TYPE !== sanitize_key( wp_unslash( $_GET['post_type'] ) ) ) {
			return;
		}
		$filter_status = isset( $_GET['sits_hf_filter_status'] ) ? sanitize_key( wp_unslash( $_GET['sits_hf_filter_status'] ) ) : '';
		// phpcs:enable
		if ( ! in_array( $filter_status, [ 'active', 'inactive' ], true ) ) {
			return;
		}
		$active_opt = $this->get_active_option();
		$all_active = [];
		foreach ( self::ALL_TYPES as $t ) {
			foreach ( $active_opt[ $t ] ?? [] as $id ) {
				$all_active[] = absint( $id );
			}
		}
		$all_active = array_unique( $all_active );
		if ( 'active' === $filter_status ) {
			$query->set( 'post__in', ! empty( $all_active ) ? $all_active : [ 0 ] );
		} else {
			if ( ! empty( $all_active ) ) {
				$query->set( 'post__not_in', $all_active );
			}
		}
	}

	/* ================================================================== */
	/* Bug #6 fix: Auto-activate when published via Elementor             */
	/* ================================================================== */

	/**
	 * When a sits_hf_template transitions to "publish", auto-activate it.
	 * This fires when Elementor publishes the post (the panel JS will also
	 * call ajax_save_template_settings with publish_now=1, but this hook
	 * acts as a safety net for all cases).
	 *
	 * @param string   $new_status New post status.
	 * @param string   $old_status Previous post status.
	 * @param \WP_Post $post       Post object.
	 */
	public function auto_activate_on_publish( $new_status, $old_status, $post ) {
		if ( 'publish' !== $new_status || 'publish' === $old_status ) {
			return;
		}
		if ( self::POST_TYPE !== $post->post_type ) {
			return;
		}
		$type = get_post_meta( $post->ID, self::META_TYPE, true );
		if ( ! $type || ! in_array( $type, self::ALL_TYPES, true ) ) {
			return;
		}
		// For header/footer AND other template types: run conflict check before activating.
		if ( $this->find_condition_conflict( $post->ID, $type ) ) {
			return; // Skip activation silently if conflict exists.
		}
		// Mark this template as active in the option store.
		$opt = $this->get_active_option();
		if ( ! isset( $opt[ $type ] ) ) {
			$opt[ $type ] = [];
		}
		if ( ! in_array( $post->ID, $opt[ $type ], true ) ) {
			$opt[ $type ][] = $post->ID;
			update_option( self::OPTION_ACTIVE, $opt );
		}
		$this->sync_single( $post->ID );
	}

	/* ================================================================== */
	/* Frontend Display (Fix 6 – CRITICAL)                                 */
	/* ================================================================== */

	/* ================================================================== */
	/* Custom Page Type Rendering (404_page, single_post, archive, …)     */
	/* ================================================================== */

	/**
	 * Override the theme template for non-header/footer custom types.
	 *
	 * When an active template of type 404_page, single_post, archive, or
	 * single_page matches the current request, we swap the theme's template
	 * file for our lightweight canvas template (templates/sits-canvas.php).
	 * The canvas outputs a full HTML document and delegates content rendering
	 * to Elementor's frontend renderer.
	 *
	 * This filter runs at priority 99 so it fires after most other plugins.
	 * Header and footer templates are NOT handled here — they are injected
	 * via wp_body_open / wp_footer hooks regardless of which page template
	 * is served, so they continue to work normally inside the canvas.
	 *
	 * @param  string $template Absolute path to the template WordPress selected.
	 * @return string           Possibly overridden template path.
	 */
	public function maybe_override_page_template( $template ) {
		// Never override when viewing a sits_hf_template post directly.
		if ( is_singular( self::POST_TYPE ) ) {
			return $template;
		}

		// Skip in the Elementor editor — setup_editor_display() handles that context.
		if ( $this->is_editor() ) {
			return $template;
		}

		// Map the current WordPress conditional to our template type key.
		$type = null;

		if ( is_404() ) {
			$type = '404_page';
		} elseif ( is_singular( 'post' ) ) {
			$type = 'single_post';
		} elseif ( is_singular( 'page' ) ) {
			$type = 'single_page';
		} elseif ( is_archive() || is_home() ) {
			$type = 'archive';
		}

		if ( ! $type ) {
			return $template;
		}

		$tid = $this->get_best( $type );
		if ( ! $tid ) {
			return $template;
		}

		// Expose the template ID and type to the canvas template via globals.
		$GLOBALS['sits_hf_canvas_id']   = $tid;
		$GLOBALS['sits_hf_canvas_type'] = $type;

		$canvas = SITS_ELEMENTOR_ADDONS_PLUGIN_PATH . 'templates/sits-canvas.php';
		return file_exists( $canvas ) ? $canvas : $template;
	}

	public function setup_editor_display() {
		if ( ! $this->is_editor() ) { return; }

		$hid = $this->get_best( 'header' );
		$fid = $this->get_best( 'footer' );

		if ( ! $hid && ! $fid ) { return; }

		add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_editor_assets' ] );

		if ( $hid ) {
			// Standard themes — fires right after <body> in the preview iframe.
			add_action( 'wp_body_open', [ $this, 'render_header_in_editor' ], 1 );
			// Elementor canvas page template.
			add_action( 'elementor/page_templates/canvas/before_content', [ $this, 'render_header_in_editor' ], 1 );
		}
		if ( $fid ) {
			// Standard themes — fires before </body> in the preview iframe.
			add_action( 'wp_footer', [ $this, 'render_footer_in_editor' ], 1 );
			// Elementor canvas page template.
			add_action( 'elementor/page_templates/canvas/after_content', [ $this, 'render_footer_in_editor' ], 999 );
		}
	}

	/**
	 * Issue 3: When our custom header is active on this page, suppress Elementor
	 * Pro's ThemeBuilder header output so both don't show simultaneously.
	 * Works by removing the Pro action that renders the header inside the theme.
	 */
	public function maybe_suppress_pro_header() {
		if ( $this->get_best( 'header' ) && ! $this->is_editor() ) {
			// Remove Elementor Pro's header rendering callbacks.
			remove_all_actions( 'elementor/theme/header' );
			// Also remove from the Hello Elementor theme integration hook.
			add_filter( 'elementor/theme/do_location', [ $this, 'suppress_pro_location_header' ], 1, 2 );
		}
	}

	/**
	 * Issue 3: Same as above but for footer.
	 */
	public function maybe_suppress_pro_footer() {
		if ( $this->get_best( 'footer' ) && ! $this->is_editor() ) {
			remove_all_actions( 'elementor/theme/footer' );
			add_filter( 'elementor/theme/do_location', [ $this, 'suppress_pro_location_footer' ], 1, 2 );
		}
	}

	/**
	 * Filter callback: prevent Elementor Pro from rendering the header location
	 * by returning true (pretends it was already handled).
	 */
	public function suppress_pro_location_header( $did_location, $location ) {
		if ( 'header' === $location && $this->get_best( 'header' ) && ! $this->is_editor() ) {
			return true;
		}
		return $did_location;
	}

	/**
	 * Filter callback: prevent Elementor Pro from rendering the footer location.
	 */
	public function suppress_pro_location_footer( $did_location, $location ) {
		if ( 'footer' === $location && $this->get_best( 'footer' ) && ! $this->is_editor() ) {
			return true;
		}
		return $did_location;
	}

	
	//  Hooked to wp_body_open (priority 1) directly from constructor.
	
	public function inject_header_at_body_open() {
		static $done = false;
		if ( $done ) { return; }
		$done = true;

		if ( is_admin() || $this->is_editor() ) { return; }

		$id = $this->get_best('header');
		if ( ! $id ) { return; }

		// Register the content renderer just-in-time
		add_action('sits_hf_header', [ $this, 'render_header_controls' ]);
		?>
		<header id="sits-custom-header" class="sits-custom-header-wrap elementor-location-header">
			<?php do_action('sits_hf_header'); ?>
		</header>
		<?php
	}

	/**
	 * Inject custom footer just before wp_footer scripts close.
	 * Hooked to wp_footer (priority 1) directly from constructor.
	 */
	public function inject_footer_before_close() {
		static $done = false;
		if ( $done ) { return; }
		$done = true;

		if ( is_admin() || $this->is_editor() ) { return; }

		$id = $this->get_best('footer');
		if ( ! $id ) { return; }

		// Register the content renderer just-in-time
		add_action('sits_hf_footer', [ $this, 'render_footer_controls' ]);
		?>
		<footer id="sits-custom-footer" class="sits-custom-footer-wrap elementor-location-footer">
			<?php do_action('sits_hf_footer'); ?>
		</footer>
		<?php
	}

	/* ================================================================== */
	/* Template Rendering                                                   */
	/* ================================================================== */

	public function render_header_controls() {
		$id = $this->get_best('header');
		if ($id) { $this->render_with_controls($id, 'header'); }
	}

	public function render_footer_controls() {
		$id = $this->get_best('footer');
		if ($id) { $this->render_with_controls($id, 'footer'); }
	}

	private function render_with_controls( $tid, $type ) {
		$is_ed = $this->is_editor();

		if ( $is_ed ) {
			// Determine which post is being previewed/edited.
			// phpcs:ignore WordPress.Security.NonceVerification.Recommended
			$preview_id = isset( $_GET['elementor-preview'] ) ? absint( $_GET['elementor-preview'] ) : 0;
			// phpcs:ignore WordPress.Security.NonceVerification.Recommended
			$post_id    = isset( $_GET['post'] ) ? absint( $_GET['post'] ) : 0;
			$editing_id = $preview_id ?: $post_id;

			if ( $editing_id === $tid ) {
				// User is editing this template directly — render without overlay.
				$this->render_tpl( $tid );
				return;
			}

			// User is editing a different page — show template with overlay.
			// The label is dynamic: "Header" or "Footer".
			if ( 'header' === $type ) {
				/* translators: overlay label shown in Elementor editor for active header template */
				$label = esc_html__( 'Header', 'softech-addons-for-elementor' );
			} else {
				/* translators: overlay label shown in Elementor editor for active footer template */
				$label = esc_html__( 'Footer', 'softech-addons-for-elementor' );
			}
			?>
			<div class="sits-hf-editor-wrapper"
			 data-template-id="<?php echo esc_attr( $tid ); ?>"
			 data-template-type="<?php echo esc_attr( $type ); ?>"
			 data-edit-url="<?php echo esc_url( admin_url( 'post.php?post=' . $tid . '&action=elementor' ) ); ?>">
				<a class="sits-hf-editor-overlay" href="<?php echo esc_url( admin_url( 'post.php?post=' . $tid . '&action=elementor' ) ); ?>" target="_top">
					<div class="sits-hf-editor-controls">
					    
						<span class="sits-hf-overlay-label"><i class="eicon-edit"></i><?php echo esc_html( $label ); ?></span>
					</div>
				</a>
				<div class="sits-hf-template-content">
					<?php $this->render_tpl( $tid ); ?>
				</div>
			</div>
			<?php
			return;
		}

		// Frontend — render template content directly, no overlay.
		$this->render_tpl( $tid );
	}
	private function render_tpl( $tid ) {
		if (class_exists('\Elementor\Plugin')) {
			// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			echo \Elementor\Plugin::instance()->frontend->get_builder_content_for_display($tid, true);
		}
	}

	public function render_header_in_editor() {
		static $d = false; if ($d) { return; } $d = true;
		$id = $this->get_best('header'); if ($id) { $this->render_with_controls($id,'header'); }
	}

	public function render_footer_in_editor() {
		static $d = false; if ($d) { return; } $d = true;
		$id = $this->get_best('footer'); if ($id) { $this->render_with_controls($id,'footer'); }
	}

	/* ================================================================== */
	/* Priority-Based Template Resolver                                     */
	/* ================================================================== */

	/**
	 * From all active templates of $type, return the one with highest score.
	 * Priority: Specific ID (30) > Page Type (20) > Entire Website (10).
	 * "Entire Website" (10) is the universal fallback – it wins over nothing
	 * (-1) but loses to any more specific rule (20+).
	 */
	public function get_best( $type ) {
		if ( is_singular(self::POST_TYPE) ) { return false; }

		$opt = $this->get_active_option();
		$ids = $opt[$type] ?? [];
		if (empty($ids)) { return false; }

		$best_id    = false;
		$best_score = -1;

		foreach ($ids as $tid) {
			$tid = absint($tid);
			if (get_post_status($tid) !== 'publish') { continue; }
			$score = $this->display_score($tid);
			if ($score > $best_score) {
				$best_score = $score;
				$best_id    = $tid;
			}
		}
		return $best_id;
	}

	private function display_score( $tid ) {
		/**
		 * Static cache keyed by $tid — avoids repeating the same 6 get_post_meta()
		 * calls when display_score() is called multiple times for the same template
		 * within a single request (e.g. get_best('header') + get_best('footer') both
		 * iterating the same active-template list).
		 *
		 * Using `static` (not a property) keeps this entirely local to the method and
		 * requires zero cache-invalidation logic: the array is discarded at request end.
		 *
		 * @var array<int, array>
		 */
		static $meta_cache = [];

		if ( ! isset( $meta_cache[ $tid ] ) ) {
			$meta_cache[ $tid ] = [
				'display_on'         => (array) get_post_meta( $tid, self::META_DISPLAY_ON,             true ),
				'exclude_on'         => (array) get_post_meta( $tid, self::META_EXCLUDE_ON,             true ),
				'specific_ids'       => array_map( 'absint', (array) get_post_meta( $tid, self::META_SPECIFIC_IDS, true ) ),
				'exclude_ids'        => array_map( 'absint', (array) get_post_meta( $tid, self::META_EXCLUDE_IDS,  true ) ),
				'display_arch_terms' => (array) get_post_meta( $tid, self::META_DISPLAY_ARCHIVE_TERMS, true ),
				'exclude_arch_terms' => (array) get_post_meta( $tid, self::META_EXCLUDE_ARCHIVE_TERMS, true ),
			];
		}

		$display_on         = $meta_cache[ $tid ]['display_on'];
		$exclude_on         = $meta_cache[ $tid ]['exclude_on'];
		$specific_ids       = $meta_cache[ $tid ]['specific_ids'];
		$exclude_ids        = $meta_cache[ $tid ]['exclude_ids'];
		$display_arch_terms = $meta_cache[ $tid ]['display_arch_terms'];
		$exclude_arch_terms = $meta_cache[ $tid ]['exclude_arch_terms'];

		// ---- Exclusion checks ----
		if (is_front_page()           && in_array('front_page',       $exclude_on, true)) { return -1; }
		if (is_home()                 && in_array('blog',             $exclude_on, true)) { return -1; }
		if (is_404()                  && in_array('404',              $exclude_on, true)) { return -1; }
		if (is_author()               && in_array('archive_author',   $exclude_on, true)) {
			$exc_authors = $exclude_arch_terms['archive_author'] ?? [];
			if ( empty($exc_authors) || in_array( (string) get_queried_object_id(), $exc_authors, true ) ) { return -1; }
		}
		if (is_date()                 && in_array('archive_date',     $exclude_on, true)) { return -1; }
		if (is_search()               && in_array('archive_search',   $exclude_on, true)) { return -1; }
		if (is_category()             && in_array('archive_category', $exclude_on, true)) {
			$exc_cats = $exclude_arch_terms['archive_category'] ?? [];
			if ( empty($exc_cats) || in_array( (string) get_queried_object_id(), $exc_cats, true ) ) { return -1; }
		}
		if (is_tag()                  && in_array('archive_tag',      $exclude_on, true)) {
			$exc_tags = $exclude_arch_terms['archive_tag'] ?? [];
			if ( empty($exc_tags) || in_array( (string) get_queried_object_id(), $exc_tags, true ) ) { return -1; }
		}
		if ((is_post_type_archive() || (is_home() && !is_front_page())) && in_array('archive_post', $exclude_on, true)) { return -1; }
		if ((is_archive() || (is_home() && !is_front_page())) && in_array('archive', $exclude_on, true)) { return -1; }

		if (in_array('singular_post', $exclude_on, true) && is_singular('post')) { return -1; }
		if (in_array('singular_page', $exclude_on, true) && is_singular('page')) { return -1; }

		if (in_array('singular', $exclude_on, true) && is_singular()) {
			if (!empty($exclude_ids)) {
				if (in_array(get_the_ID(), $exclude_ids, true)) { return -1; }
			} else {
				return -1;
			}
		}

		// ---- Display checks ----
		if (in_array('all', $display_on, true)) { return self::PRIORITY_GLOBAL; }

		if (in_array('front_page',       $display_on, true) && is_front_page())    { return self::PRIORITY_PAGE_TYPE; }
		if (in_array('blog',             $display_on, true) && is_home())           { return self::PRIORITY_PAGE_TYPE; }
		if (in_array('404',              $display_on, true) && is_404())            { return self::PRIORITY_PAGE_TYPE; }

		// Fix 3: singular_post / singular_page conditions
		$singular_sub_score = self::PRIORITY_PAGE_TYPE + 5;
		if (in_array('singular_post', $display_on, true) && is_singular('post'))   { return $singular_sub_score; }
		if (in_array('singular_page', $display_on, true) && is_singular('page'))   { return $singular_sub_score; }

		// Archive sub-types score higher (25) than generic "All Archives" (20)
		$archive_sub_score = self::PRIORITY_PAGE_TYPE + 5; // 25
		$archive_spec_score = self::PRIORITY_PAGE_TYPE + 10; // 30 – specific term match

		// Fix 4: archive sub-type with optional specific-item matching
		if (in_array('archive_author',   $display_on, true) && is_author()) {
			$auth_ids = $display_arch_terms['archive_author'] ?? [];
			if (!empty($auth_ids)) {
				return in_array( (string) get_queried_object_id(), $auth_ids, true ) ? $archive_spec_score : -1;
			}
			return $archive_sub_score;
		}
		if (in_array('archive_date',     $display_on, true) && is_date())           { return $archive_sub_score; }
		if (in_array('archive_search',   $display_on, true) && is_search())         { return $archive_sub_score; }
		if (in_array('archive_category', $display_on, true) && is_category()) {
			$cat_ids = $display_arch_terms['archive_category'] ?? [];
			if (!empty($cat_ids)) {
				return in_array( (string) get_queried_object_id(), $cat_ids, true ) ? $archive_spec_score : -1;
			}
			return $archive_sub_score;
		}
		if (in_array('archive_tag',      $display_on, true) && is_tag()) {
			$tag_ids = $display_arch_terms['archive_tag'] ?? [];
			if (!empty($tag_ids)) {
				return in_array( (string) get_queried_object_id(), $tag_ids, true ) ? $archive_spec_score : -1;
			}
			return $archive_sub_score;
		}
		if (in_array('archive_post',     $display_on, true) && (is_post_type_archive() || (is_home() && !is_front_page()))) { return $archive_sub_score; }
		if (in_array('archive',          $display_on, true) && (is_archive() || (is_home() && !is_front_page()))) { return self::PRIORITY_PAGE_TYPE; }

		if (in_array('singular', $display_on, true) && is_singular()) {
			if (!empty($specific_ids)) {
				return in_array(get_the_ID(), $specific_ids, true) ? self::PRIORITY_SPECIFIC : -1;
			}
			return self::PRIORITY_PAGE_TYPE;
		}

		return -1;
	}

	/* ================================================================== */
	/* Fix 2: Conflict Detection                                            */
	/* ================================================================== */

	/**
	 * Returns the ID of the conflicting template, or false if no conflict.
	 * A conflict exists when activating $template_id would cause two active
	 * templates of the same $type to match the same page (overlapping conditions).
	 */
	private function find_condition_conflict( $template_id, $type ) {
		$opt          = $this->get_active_option();
		$existing_ids = array_diff( $opt[ $type ] ?? [], [ absint( $template_id ) ] );

		if ( empty( $existing_ids ) ) { return false; }

		$new_disp = (array) get_post_meta( $template_id, self::META_DISPLAY_ON,   true );
		$new_spec = array_map( 'absint', (array) get_post_meta( $template_id, self::META_SPECIFIC_IDS, true ) );

		$stale_ids = [];

		foreach ( $existing_ids as $eid ) {
			$eid = absint( $eid );

			// Fix 2: skip (and mark stale) any post that is NOT published —
			// this covers trashed, drafted, or permanently deleted templates
			// that were never removed from the active option (e.g. because the
			// trash action fired before the meta was saved with the correct type).
			$post_status = get_post_status( $eid );
			if ( ! $post_status || 'publish' !== $post_status ) {
				$stale_ids[] = $eid;
				continue;
			}

			$ex_disp = (array) get_post_meta( $eid, self::META_DISPLAY_ON,   true );
			$ex_spec = array_map( 'absint', (array) get_post_meta( $eid, self::META_SPECIFIC_IDS, true ) );

			if ( $this->conditions_overlap( $new_disp, $new_spec, $ex_disp, $ex_spec ) ) {
				// Purge any stale IDs we found along the way before returning.
				if ( ! empty( $stale_ids ) ) {
					$opt[ $type ] = array_values( array_diff( $opt[ $type ], $stale_ids ) );
					update_option( self::OPTION_ACTIVE, $opt );
				}
				return $eid;
			}
		}

		// Purge stale IDs discovered during the scan even when there is no conflict.
		if ( ! empty( $stale_ids ) ) {
			$opt[ $type ] = array_values( array_diff( $opt[ $type ], $stale_ids ) );
			update_option( self::OPTION_ACTIVE, $opt );
		}

		return false;
	}

	private function conditions_overlap( $disp_a, $spec_a, $disp_b, $spec_b ) {
		/*
		 * Priority-aware conflict detection:
		 *
		 *  - Two "Entire Website" templates of same type = TRUE conflict (same priority).
		 *  - "Entire Website" + specific/page-type = NOT a conflict; priority (10 vs 20/30) handles it.
		 *  - Two page-type conditions that intersect (e.g. both "front_page") = TRUE conflict.
		 *  - Two "singular" with overlapping specific IDs = TRUE conflict.
		 *  - "singular" all + "singular" specific = NOT a conflict; priority (20 vs 30) handles it.
		 *  - "archive" (all) + "archive_post" (sub-type) = NOT a conflict; priority handles it.
		 *  - Two different archive sub-types (e.g. archive_post + archive_author) = NOT a conflict.
		 */

		$a_is_global = in_array( 'all', $disp_a, true );
		$b_is_global = in_array( 'all', $disp_b, true );

		// Two globals = conflict
		if ( $a_is_global && $b_is_global ) { return true; }

		// One global + one more specific = allow (priority system resolves this)
		if ( $a_is_global || $b_is_global ) { return false; }

		// Neither is global – check for overlapping page-type conditions
		$common = array_intersect( $disp_a, $disp_b );
		if ( empty( $common ) ) { return false; }

		// Archive sub-types vs parent "archive": priority handles it (no conflict)
		$archive_sub_types = [ 'archive_post', 'archive_author', 'archive_date', 'archive_search', 'archive_category', 'archive_tag' ];
		$singular_sub_types = [ 'singular_post', 'singular_page' ];

		// Remove singular from common for separate handling
		$non_singular = array_diff( $common, [ 'singular' ] );

		foreach ( $non_singular as $cond ) {
			if ( 'archive' === $cond ) {
				// "archive" in both — only a conflict if the OTHER also has "archive" (not just sub-types)
				// Two templates both targeting ALL archives = conflict
				return true;
			}
			if ( in_array( $cond, $archive_sub_types, true ) ) {
				// Both target the same specific archive sub-type = conflict
				return true;
			}
			if ( in_array( $cond, $singular_sub_types, true ) ) {
				// Same specific singular subtype in both templates = conflict.
				return true;
			}
			// Any other overlapping page-type (front_page, blog, 404) = conflict
			return true;
		}

		// Check if one has "archive" (all) and other has a sub-type — NOT a conflict (priority resolves)
		$a_has_archive_all  = in_array( 'archive', $disp_a, true );
		$b_has_archive_all  = in_array( 'archive', $disp_b, true );
		$a_has_archive_sub  = ! empty( array_intersect( $disp_a, $archive_sub_types ) );
		$b_has_archive_sub  = ! empty( array_intersect( $disp_b, $archive_sub_types ) );

		if ( ( $a_has_archive_all && $b_has_archive_sub ) || ( $b_has_archive_all && $a_has_archive_sub ) ) {
			return false; // "All Archives" + specific sub-type = priority handles it
		}

		$a_has_singular_sub = ! empty( array_intersect( $disp_a, $singular_sub_types ) );
		$b_has_singular_sub = ! empty( array_intersect( $disp_b, $singular_sub_types ) );

		if ( ( in_array( 'singular', $disp_a, true ) && $b_has_singular_sub ) || ( in_array( 'singular', $disp_b, true ) && $a_has_singular_sub ) ) {
			return false; // generic singular + post/page subtype = priority handles it
		}

		// Both have 'singular' in common – check specificity
		if ( in_array( 'singular', $common, true ) ) {
			if ( empty( $spec_a ) && empty( $spec_b ) ) {
				// Both target ALL singulars at same priority = conflict
				return true;
			}
			// At least one has specific IDs: if one is general and other specific, priority handles it (no block)
			if ( empty( $spec_a ) || empty( $spec_b ) ) {
				return false; // One is "all singular" (20), other is specific (30) – coexist
			}
			// Both have specific IDs – conflict only if they share the same IDs
			return ! empty( array_intersect( $spec_a, $spec_b ) );
		}

		return false;
	}

	/* ================================================================== */
	/* Elementor Documents & Sync                                           */
	/* ================================================================== */

	public function register_elementor_document_type( $mgr ) {
		/*
		 * ALWAYS register our custom document type for sits_hf_template posts,
		 * regardless of whether Elementor Pro is active.
		 *
		 * When Pro IS active, Pro's Header/Footer document types are applied only
		 * to elementor_library mirror posts — never to sits_hf_template posts.
		 * Using Pro's document types on our post type caused the "content area
		 * not found" error because Pro's documents expect a different preview
		 * setup that conflicts with our elementor_canvas rendering.
		 */
		require_once SITS_ELEMENTOR_ADDONS_PLUGIN_PATH . 'includes/class-hf-elementor-document.php';
		$mgr->register_document_type( 'sits-hf-template', '\Softech_Addons_for_Elementor\Includes\SITS_HF_Elementor_Document' );
	}

	public function sync_elementor_template_type() {
    // Only run in wp-admin, never on frontend page loads
    if ( ! is_admin() ) {
        return;
    }
    $transient_key = 'sits_hf_synced_ids';
    if ( get_transient( $transient_key ) ) {
        return;
    }

    // Batch in pages of 50 to avoid memory/CPU spikes on large sites.
    $page = 1;
    do {
        $batch = get_posts( [
            'post_type'      => self::POST_TYPE,
            'post_status'    => 'any',
            'fields'         => 'ids',
            'posts_per_page' => 50,
            'paged'          => $page,
            'no_found_rows'  => false, // needed for paged queries to work correctly
        ] );

        foreach ( $batch as $pid ) {
            $this->sync_single( $pid );
        }

        $page++;
    } while ( count( $batch ) === 50 );

    // Cache for 12 hours — cleared automatically when a template is saved via sync_single().
    set_transient( $transient_key, 1, 12 * HOUR_IN_SECONDS );
}

	/**
	 * Sync a single template's Elementor meta.
	 *
	 * Fix 1: Sets _elementor_template_type correctly so admin bar doesn't
	 *        show "Post".
	 *
	 * Fix 5: When Pro is active, creates/updates a mirror elementor_library
	 *        post so the template appears in Theme Builder > Header/Footer.
	 */
	private function sync_single( $pid ) {
		$type = get_post_meta($pid, self::META_TYPE, true);
		delete_transient( 'sits_hf_synced_ids' );

		// Set canvas template and hide title for ALL template types.
		update_post_meta($pid, '_elementor_template_type', 'sits-hf-template');
		update_post_meta($pid, '_wp_page_template', 'elementor_canvas');

		$page_settings = get_post_meta( $pid, '_elementor_page_settings', true );
		if ( ! is_array( $page_settings ) ) { $page_settings = []; }
		$page_settings['hide_title'] = 'yes';
		update_post_meta( $pid, '_elementor_page_settings', $page_settings );

		// Elementor Pro syncing (mirror posts) only for header/footer types.
		if (!in_array($type, ['header','footer'], true)) { return; }

		$pro = class_exists('\\ElementorPro\\Modules\\ThemeBuilder\\Documents\\Header');
		if ($pro) {
			update_post_meta($pid, '_elementor_conditions', $this->build_pro_conditions($pid));
			$this->sync_elementor_library_mirror($pid, $type);
		}
	}

	/**
	 * Fix 5: Create/update a shadow elementor_library post.
	 * This mirror has the same Elementor data and conditions, so it appears
	 * in Elementor Pro's Theme Builder > Header / Footer listing.
	 * When the mirror is edited in Pro, its _elementor_data is used.
	 * When our template is saved, the mirror is kept in sync.
	 */
	private function sync_elementor_library_mirror( $source_id, $type ) {
		$source_post = get_post($source_id);
		if (!$source_post || $source_post->post_status !== 'publish') { return; }

		$mirror_id = (int) get_post_meta($source_id, self::META_MIRROR_ID, true);

		// Validate existing mirror
		if ($mirror_id && get_post_type($mirror_id) !== 'elementor_library') {
			$mirror_id = 0;
			delete_post_meta($source_id, self::META_MIRROR_ID);
		}

		$mirror_title = $source_post->post_title . ' [Softech HF]';

		if ($mirror_id && get_post($mirror_id)) {
			// Update existing mirror
			wp_update_post([
				'ID'          => $mirror_id,
				'post_title'  => $mirror_title,
				'post_status' => 'publish',
			]);
		} else {
			// Create new mirror — remove our hook temporarily to avoid loops
			remove_action('save_post_elementor_library', [$this, 'on_elementor_library_save'], 99);
			$mirror_id = wp_insert_post([
				'post_title'  => $mirror_title,
				'post_status' => 'publish',
				'post_type'   => 'elementor_library',
			]);
			add_action('save_post_elementor_library', [$this, 'on_elementor_library_save'], 99, 2);

			if (!$mirror_id || is_wp_error($mirror_id)) { return; }
			update_post_meta($source_id, self::META_MIRROR_ID, $mirror_id);
			update_post_meta($mirror_id, '_sits_hf_source_id', $source_id); // back-reference
		}

		// Copy Elementor content from source to mirror
		$el_data = get_post_meta($source_id, '_elementor_data', true);
		$el_css  = get_post_meta($source_id, '_elementor_css',  true);
		$el_ver  = get_post_meta($source_id, '_elementor_version', true);

		update_post_meta($mirror_id, '_elementor_data',     $el_data);
		update_post_meta($mirror_id, '_elementor_css',      $el_css);
		update_post_meta($mirror_id, '_elementor_version',  $el_ver ?: '3.0.0');
		update_post_meta($mirror_id, '_elementor_template_type', $type);
		update_post_meta($mirror_id, '_elementor_conditions',    $this->build_pro_conditions($source_id));
		update_post_meta($mirror_id, '_wp_page_template',        'elementor_canvas');
	}

	/**
	 * When a mirror elementor_library post is saved in Elementor Pro,
	 * sync _elementor_data back to our source template.
	 */
	public function on_elementor_library_save( $post_id, $post ) {
		$source_id = (int) get_post_meta($post_id, '_sits_hf_source_id', true);
		if (!$source_id) { return; }

		$el_data = get_post_meta($post_id, '_elementor_data', true);
		if ($el_data) {
			update_post_meta($source_id, '_elementor_data', $el_data);
		}
	}

	/**
	 * Convert our display/exclude meta into Elementor Pro's condition strings.
	 */
	private function build_pro_conditions( $pid ) {
		$display_on   = (array) get_post_meta($pid, self::META_DISPLAY_ON,   true);
		$exclude_on   = (array) get_post_meta($pid, self::META_EXCLUDE_ON,   true);
		$specific_ids = array_map('absint', (array) get_post_meta($pid, self::META_SPECIFIC_IDS, true));
		$exclude_ids  = array_map('absint', (array) get_post_meta($pid, self::META_EXCLUDE_IDS,  true));

		$map = [
			'all'              => '',
			'singular'         => 'singular',
			'singular_post'    => 'singular/post',
			'singular_page'    => 'singular/page',
			'archive'          => 'archive',
			'archive_post'     => 'archive/post',
			'archive_author'   => 'archive/author',
			'archive_date'     => 'archive/date',
			'archive_search'   => 'archive/search',
			'archive_category' => 'archive/category',
			'archive_tag'      => 'archive/post_tag',
			'front_page'       => 'front_page',
			'blog'             => 'posts_page',
			'404'              => 'not_found404',
		];

		$conds = [];

		foreach ($display_on as $loc) {
			if ('singular' === $loc && !empty($specific_ids)) {
				foreach ($specific_ids as $sid) {
					$p = get_post($sid);
					if ($p) { $conds[] = 'include|singular|' . $p->post_type . '/' . $sid; }
				}
			} elseif (isset($map[$loc])) {
				$conds[] = 'include|general|' . $map[$loc];
			}
		}

		foreach ($exclude_on as $loc) {
			if ('singular' === $loc && !empty($exclude_ids)) {
				foreach ($exclude_ids as $eid) {
					$p = get_post($eid);
					if ($p) { $conds[] = 'exclude|singular|' . $p->post_type . '/' . $eid; }
				}
			} elseif (isset($map[$loc]) && 'all' !== $loc) {
				$conds[] = 'exclude|general|' . $map[$loc];
			}
		}

		return $conds;
	}

	/* ================================================================== */
	/* Assets                                                               */
	/* ================================================================== */

	public function enqueue_frontend_assets() {
		$opt = $this->get_active_option();
		if (!empty($opt['header']) || !empty($opt['footer'])) {
			wp_enqueue_style('sits-hf-frontend', SITS_ELEMENTOR_ADDONS_PLUGIN_URL.'assets/css/hf-frontend.css', [], SITS_ELEMENTOR_ADDONS_VERSION);
		}
		// Points 5 & 6: suppress entry-title when viewing a sits_hf_template page.
		if ( is_singular( self::POST_TYPE ) ) {
			$inline = '.entry-title,.page-title,.entry-header,.page-header{display:none!important}';
			wp_add_inline_style( 'elementor-frontend', $inline );
		}
	}

	public function enqueue_editor_assets() {
		wp_enqueue_style( 'sits-hf-editor', SITS_ELEMENTOR_ADDONS_PLUGIN_URL . 'assets/css/hf-editor.css', [], SITS_ELEMENTOR_ADDONS_VERSION );
		wp_enqueue_script( 'sits-hf-editor', SITS_ELEMENTOR_ADDONS_PLUGIN_URL . 'assets/js/hf-editor.js', [], SITS_ELEMENTOR_ADDONS_VERSION, true );
	}

	/* ================================================================== */
	/* Body Class                                                           */
	/* ================================================================== */

	public function add_body_class( $cls ) {
		// Only hide the theme header/footer when our custom template *actually matches* the current page.
		// Using get_best() (page-aware) instead of get_active_option() (global) prevents the theme
		// footer from being hidden on pages where no custom footer condition matches.
		if (!is_singular(self::POST_TYPE)) {
			if ($this->get_best('header')) { $cls[] = 'sits-custom-header'; }
			if ($this->get_best('footer')) { $cls[] = 'sits-custom-footer'; }
		}
		// Points 5 & 6: add a specific body class when viewing an HF template post
		// so CSS can target and hide the entry-title.
		if ( is_singular( self::POST_TYPE ) ) {
			$cls[] = 'elementor-page-sits-hf-template';
		}
		return $cls;
	}

	/**
	 * Replace Elementor admin-bar "sub_title" labels with template-type labels
	 * for our Theme Builder documents.
	 *
	 * Elementor's admin-bar module uses static document titles for submenu
	 * entries, so this filter enforces the per-template type label.
	 */
	public function filter_elementor_admin_bar_settings( $settings ) {
		if ( empty( $settings['elementor_edit_page']['children'] ) || ! is_array( $settings['elementor_edit_page']['children'] ) ) {
			return $settings;
		}

		foreach ( $settings['elementor_edit_page']['children'] as $index => $child ) {
			$child_id = isset( $child['id'] ) ? (string) $child['id'] : '';
			if ( '' === $child_id || ! preg_match( '/^elementor_edit_doc_(\d+)$/', $child_id, $matches ) ) {
				continue;
			}

			$template_id = absint( $matches[1] );
			if ( ! $template_id || self::POST_TYPE !== get_post_type( $template_id ) ) {
				continue;
			}

			$template_type = sanitize_key( (string) get_post_meta( $template_id, self::META_TYPE, true ) );
			$label         = $this->get_template_type_label( $template_type );
			if ( '' === $label ) {
				continue;
			}

			$settings['elementor_edit_page']['children'][ $index ]['sub_title'] = $label;
		}

		return $settings;
	}

	/**
	 * Human-readable label for a template type key.
	 */
	private function get_template_type_label( string $type ): string {
		$labels = [
			'header'      => __( 'Header', 'softech-addons-for-elementor' ),
			'footer'      => __( 'Footer', 'softech-addons-for-elementor' ),
			'archive'     => __( 'Archive', 'softech-addons-for-elementor' ),
			'single_page' => __( 'Single Page', 'softech-addons-for-elementor' ),
			'single_post' => __( 'Single Post', 'softech-addons-for-elementor' ),
			'404_page'    => __( '404 Page', 'softech-addons-for-elementor' ),
		];

		return $labels[ $type ] ?? '';
	}

	/* ================================================================== */
	/* Helpers                                                              */
	/* ================================================================== */

	/** Get active templates option, normalising old single-ID format. */
	public function get_active_option() {
		$opt = get_option(self::OPTION_ACTIVE, []);
		if (!is_array($opt)) { $opt = []; }
		foreach ( self::ALL_TYPES as $t) {
			if (!isset($opt[$t])) {
				$opt[$t] = [];
			} elseif (!is_array($opt[$t])) {
				$opt[$t] = $opt[$t] ? [absint($opt[$t])] : [];
			}
		}
		return $opt;
	}

	private function is_active( $pid, $type, $active ) {
		if (!$type) { return false; }
		return in_array(absint($pid), $active[$type] ?? [], true);
	}

	private function is_editor() {
		if (!class_exists('\Elementor\Plugin')) { return false; }
		return \Elementor\Plugin::$instance->editor->is_edit_mode() ||
			   \Elementor\Plugin::$instance->preview->is_preview_mode();
	}

	private function build_post_list( $ids ) {
		$list = [];
		foreach ($ids as $id) {
			$p = get_post(absint($id));
			if ($p && $p->post_type !== self::POST_TYPE) {
				$list[] = ['id'=>$p->ID, 'title'=>$p->post_title, 'type'=>$p->post_type];
			}
		}
		return $list;
	}

	private function sanitize_ids( $raw ) {
		$ids = [];
		if (is_array($raw)) {
			foreach (array_map('absint', wp_unslash($raw)) as $id) {
				if ($id > 0) { $ids[] = $id; }
			}
		}
		return $ids;
	}

	/**
	 * Pre-flight permission check for AJAX handlers.
	 * Each individual AJAX handler verifies its own action-specific nonce
	 * (which incorporates the template_id) BEFORE reading template_id or type,
	 * so we intentionally do not access those parameters here.
	 */
	private function ajax_gate() {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( [ 'message' => __( 'Permission denied', 'softech-addons-for-elementor' ) ] );
		}
	}
	/**
	 * Enqueue inline CSS in the Elementor editor to suppress the post title
	 * above the canvas when editing an HF template (Points 5 & 6).
	 */
	public function maybe_enqueue_hf_title_hide_css() {
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$post_id = isset( $_GET['post'] ) ? absint( wp_unslash( $_GET['post'] ) ) : 0;
		if ( ! $post_id || get_post_type( $post_id ) !== self::POST_TYPE ) {
			return;
		}
		$css = '
		/* Softech HF — hide post/page title in the editor canvas for HF templates */
		.elementor-editor-preview .entry-title,
		.elementor-editor-preview .page-title,
		.elementor-editor-preview h1.entry-title,
		.elementor-editor-preview .site-title,
		body.elementor-page-template-canvas .entry-header,
		body.elementor-page-template-canvas .page-header { display: none !important; }
		';
		wp_add_inline_style( 'elementor-editor', $css );
	}

	/**
	 * Points 5 & 6: Force Elementor's "Hide Title" meta to true for all HF template
	 * posts. This runs on wp action so is safe for both frontend and preview.
	 * We write the value only when it is not already set to avoid resetting user
	 * preferences on non-HF posts.
	 */
	public function force_hide_title_meta() {
		if ( ! is_singular( self::POST_TYPE ) ) {
			return;
		}
		$pid = get_the_ID();
		if ( ! $pid ) {
			return;
		}
		// Set Elementor's hide_title document setting.
		$doc_settings = get_post_meta( $pid, '_elementor_page_settings', true );
		if ( ! is_array( $doc_settings ) ) {
			$doc_settings = [];
		}
		if ( empty( $doc_settings['hide_title'] ) || 'yes' !== $doc_settings['hide_title'] ) {
			$doc_settings['hide_title'] = 'yes';
			update_post_meta( $pid, '_elementor_page_settings', $doc_settings );
		}
	}

	/**
	 * Remove the post title from <title> tag for HF template posts.
	 *
	 * @param string $title Document title.
	 * @return string
	 */
	public function filter_document_title_for_hf( $title ) {
		if ( is_singular( self::POST_TYPE ) ) {
			return get_bloginfo( 'name', 'display' );
		}
		return $title;
	}

	/**
	 * Return an empty string for the_title() when called on HF template posts
	 * so no visible title renders above the canvas on frontend or in editor preview.
	 *
	 * @param string $title Post title.
	 * @param int    $id    Post ID.
	 * @return string
	 */
	public function filter_the_title_for_hf( $title, $id = 0 ) {
		
		if ( is_admin() ) {
			return $title;
		}
		if ( $id && get_post_type( $id ) === self::POST_TYPE ) {
			return '';
		}
		return $title;
	}

	/**
	 * Enqueue inline CSS that hides the Elementor editor panel title element
	 * (the duplicate title above the canvas) for HF template posts.
	 * This covers Points 5 & 6.
	 */
	private function enqueue_hf_editor_title_hide_css() {
		$css = '
		/* Softech HF: hide post title above Elementor canvas in editor and preview */
		.elementor-editor-active .page-title-bar,
		.elementor-editor-active .entry-title,
		.elementor-editor-active h1.entry-title,
		body.elementor-editor-active > h1,
		body.elementor-editor-active .site-title,
		body.elementor-page-template-canvas h1.entry-title,
		body.elementor-page-template-canvas .page-title,
		.sits-hf-template-title-hide { display: none !important; }
		';
		wp_add_inline_style( 'elementor-editor', $css );
	}

}

SITS_Header_Footer_Builder::instance();
