<?php
/**
 * DBA Startup Hub Homepage Filter
 *
 * ═══════════════════════════════════════════════════════════════════════
 *  BULLETPROOF homepage exclusion — ported from Live Sports AI v10.4.3
 *
 *  TWO LAYERS of protection:
 *    1. pre_get_posts  → category__not_in (fast, catches main + secondary queries)
 *    2. the_posts      → safety net (catches Divi modules that bypass pre_get_posts)
 *
 *  COVERS:
 *    - Main homepage (is_home / is_front_page)
 *    - WPML translated homepages (?lang=fr, ?lang=it, etc.)
 *    - Divi Blog modules, sidebar widgets, any secondary post queries on homepage
 *    - RSS feeds on homepage
 *
 *  Startup Hub posts use category "smb-growth-hub" and meta key
 *  "_dba_startup_hub_auto_created". Both are used for exclusion.
 * ═══════════════════════════════════════════════════════════════════════
 *
 * @since 2.16.0
 */

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

class DBA_Startup_Hub_Homepage_Filter {

    private static $instance = null;

    /** Category slug used by all Startup Hub posts */
    const CATEGORY_SLUG = 'smb-growth-hub';

    /** Meta key present on all auto-created Startup Hub posts */
    const META_KEY = '_dba_startup_hub_auto_created';

    /** Transient for caching homepage filter data */
    const CACHE_KEY = 'dba_startup_hub_homepage_filter';

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

    private function __construct() {
        if ( ! is_admin() ) {
            // LAYER 1: pre_get_posts — category exclusion (fast path)
            add_action( 'pre_get_posts', array( $this, 'exclude_from_homepage' ) );

            // LAYER 2: the_posts — safety net for Divi / widgets / anything that skips pre_get_posts
            add_filter( 'the_posts', array( $this, 'strip_from_homepage_results' ), 10, 2 );
        }
    }

    /* =================================================================
     *  LAYER 1: pre_get_posts — Category-based exclusion
     *
     *  Mirrors Live Sports AI v10.4.3 lsa_exclude_from_homepage()
     *  Catches main query + secondary queries (Divi blog modules, widgets)
     *  on homepage and ALL translated homepage versions.
     * ================================================================= */

    /**
     * Exclude Startup Hub posts from homepage queries.
     *
     * @param WP_Query $query
     */
    public function exclude_from_homepage( $query ) {
        if ( is_admin() ) return;

        $should_exclude = false;

        // ── Check: is this a homepage query? ──

        // Main query on homepage
        if ( $query->is_main_query() && ( is_home() || is_front_page() ) ) {
            $should_exclude = true;
        }
        // Secondary queries on homepage (Divi Blog modules, widgets, etc.)
        elseif ( ! $query->is_main_query() && ( is_home() || is_front_page() ) ) {
            $post_type = $query->get( 'post_type' );
            if ( empty( $post_type ) || $post_type === 'post' || ( is_array( $post_type ) && in_array( 'post', $post_type ) ) ) {
                $should_exclude = true;
            }
        }

        // ── Check: is this a WPML translated homepage? ──
        // Even if is_home()/is_front_page() returns false for translated versions,
        // catch them via the WPML front page detection.
        if ( ! $should_exclude && $this->is_wpml_translated_homepage() ) {
            $post_type = $query->get( 'post_type' );
            if ( empty( $post_type ) || $post_type === 'post' || ( is_array( $post_type ) && in_array( 'post', $post_type ) ) ) {
                $should_exclude = true;
            }
        }

        if ( ! $should_exclude ) return;

        // ── Exclude by category ──
        $cat = get_term_by( 'slug', self::CATEGORY_SLUG, 'category' );
        if ( $cat && ! is_wp_error( $cat ) ) {
            $existing = $query->get( 'category__not_in' );
            if ( ! is_array( $existing ) ) $existing = array();
            $cat_id = intval( $cat->term_id );
            if ( ! in_array( $cat_id, $existing, true ) ) {
                $existing[] = $cat_id;
                $query->set( 'category__not_in', $existing );
            }
        }

        // ── Also exclude the hub page itself via post__not_in ──
        $config = DBA_Startup_Hub_Registry::get_config();
        $hub_id = get_option( $config['hub_page_option'], 0 );
        if ( $hub_id ) {
            $current_not_in = $query->get( 'post__not_in' );
            if ( ! is_array( $current_not_in ) ) $current_not_in = array();
            $hub_id_int = intval( $hub_id );
            if ( ! in_array( $hub_id_int, $current_not_in, true ) ) {
                $current_not_in[] = $hub_id_int;
                $query->set( 'post__not_in', $current_not_in );
            }
        }
    }

    /* =================================================================
     *  LAYER 2: the_posts — Safety net (post-query filter)
     *
     *  Mirrors Live Sports AI v10.4.3 lsa_strip_from_homepage_results()
     *  Catches anything that bypassed pre_get_posts:
     *    - Divi Blog modules with custom queries
     *    - Widget queries
     *    - Theme-specific featured post sections
     *    - Any plugin that builds its own WP_Query
     *
     *  Checks post meta (already in object cache = fast).
     * ================================================================= */

    /**
     * Strip Startup Hub posts from homepage query results.
     *
     * @param  array    $posts
     * @param  WP_Query $query
     * @return array
     */
    public function strip_from_homepage_results( $posts, $query ) {
        if ( is_admin() ) return $posts;

        // Must be on a homepage (including translated)
        if ( ! is_home() && ! is_front_page() && ! $this->is_wpml_translated_homepage() ) {
            return $posts;
        }

        // Filter out any Startup Hub auto-created posts
        $filtered = array_filter( $posts, function( $post ) {
            return empty( get_post_meta( $post->ID, self::META_KEY, true ) );
        } );

        return array_values( $filtered );
    }

    /* =================================================================
     *  WPML TRANSLATED HOMEPAGE DETECTION
     *
     *  WPML can serve translated front pages where is_home() / is_front_page()
     *  still return true, but also cases where they don't (static front page
     *  translations). This helper catches both cases.
     * ================================================================= */

    /**
     * Check if the current page is a WPML-translated version of the homepage.
     *
     * @return bool
     */
    private function is_wpml_translated_homepage() {
        // Method 1: WPML's own front page detection
        if ( function_exists( 'wpml_is_front_page' ) ) {
            return wpml_is_front_page();
        }

        // Method 2: Check if current page is a translation of the front page
        if ( function_exists( 'icl_object_id' ) ) {
            $front_page_id = get_option( 'page_on_front' );
            if ( $front_page_id && is_page() ) {
                global $sitepress;
                if ( $sitepress ) {
                    $default_lang = $sitepress->get_default_language();
                    $original_id  = icl_object_id( get_the_ID(), 'page', false, $default_lang );
                    if ( $original_id && intval( $original_id ) === intval( $front_page_id ) ) {
                        return true;
                    }
                }
            }
        }

        // Method 3: Check URL-based language parameter on site root
        // Covers ?lang=fr, ?lang=it, /fr/, /it/ etc. when visiting the root
        if ( isset( $_GET['lang'] ) || ( defined( 'ICL_LANGUAGE_CODE' ) && ICL_LANGUAGE_CODE !== 'en' ) ) {
            $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '';
            $path = trim( parse_url( $request_uri, PHP_URL_PATH ), '/' );

            // Root with just language code: "" or "fr" or "it" etc.
            if ( empty( $path ) || preg_match( '#^[a-z]{2}/?$#', $path ) ) {
                return true;
            }
        }

        return false;
    }

    /* =================================================================
     *  CACHE FLUSH
     *
     *  Called after a new Startup Hub post is published to ensure
     *  the homepage re-queries and gets the updated exclusion list.
     * ================================================================= */

    /**
     * Flush the homepage filter cache.
     */
    public static function flush_cache() {
        delete_transient( self::CACHE_KEY );

        // Also flush page caches so homepage gets regenerated
        if ( function_exists( 'rocket_clean_home' ) ) rocket_clean_home();
        if ( function_exists( 'rocket_clean_domain' ) ) rocket_clean_domain();
        if ( has_action( 'litespeed_purge_all' ) ) do_action( 'litespeed_purge_all' );
        if ( function_exists( 'wp_cache_clear_cache' ) ) wp_cache_clear_cache();
        if ( function_exists( 'w3tc_flush_all' ) ) w3tc_flush_all();
        if ( function_exists( 'sg_cachepress_purge_cache' ) ) sg_cachepress_purge_cache();
        if ( function_exists( 'et_core_clear_wp_cache' ) ) et_core_clear_wp_cache();
    }
}
