<?php
/**
 * DBA Startup Hub Deduplication Guard
 *
 * Prevents duplicate Startup Hub posts by tracking:
 *   - Categories used today (transient)
 *   - Cities used today (transient)
 *   - Category+city combos used recently (option-based history)
 *   - Startups mentioned recently (avoids repeating the same companies)
 *
 * All methods are static for easy cross-class access.
 *
 * @since 2.16.0
 */

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

class DBA_Startup_Hub_Dedupe {

    const HISTORY_OPTION     = 'dba_startup_hub_dedupe_history';
    const HISTORY_MAX        = 200;
    const TRANSIENT_CATS     = 'dba_startup_hub_today_categories';
    const TRANSIENT_CITIES   = 'dba_startup_hub_today_cities';
    const TRANSIENT_STARTUPS = 'dba_startup_hub_recent_startups';

    /* =================================================================
     *  TODAY TRACKERS (transients — reset daily)
     * ================================================================= */

    /**
     * Get category slugs already used today.
     *
     * @return array
     */
    public static function get_today_categories() {
        $cats = get_transient( self::TRANSIENT_CATS );
        return is_array( $cats ) ? $cats : array();
    }

    /**
     * Get city names already used today.
     *
     * @return array
     */
    public static function get_today_cities() {
        $cities = get_transient( self::TRANSIENT_CITIES );
        return is_array( $cities ) ? $cities : array();
    }

    /**
     * Mark a category as used today.
     *
     * @param string $slug Category slug.
     */
    public static function mark_category_used( $slug ) {
        $cats = self::get_today_categories();
        if ( ! in_array( $slug, $cats, true ) ) {
            $cats[] = $slug;
            set_transient( self::TRANSIENT_CATS, $cats, DAY_IN_SECONDS );
        }
    }

    /**
     * Mark a city as used today.
     *
     * @param string $city City name.
     */
    public static function mark_city_used( $city ) {
        $cities = self::get_today_cities();
        if ( ! in_array( $city, $cities, true ) ) {
            $cities[] = $city;
            set_transient( self::TRANSIENT_CITIES, $cities, DAY_IN_SECONDS );
        }
    }

    /* =================================================================
     *  COMBO HISTORY (option-based — persistent)
     * ================================================================= */

    /**
     * Check if a category+city combo was used recently.
     *
     * @param  string $cat_slug Category slug.
     * @param  string $city     City name.
     * @param  int    $days     How many days to look back.
     * @return bool
     */
    public static function combo_recently_used( $cat_slug, $city, $days = 3 ) {
        $history  = get_option( self::HISTORY_OPTION, array() );
        $cutoff   = strtotime( "-{$days} days" );
        $cat_slug = strtolower( $cat_slug );
        $city     = strtolower( $city );

        foreach ( $history as $entry ) {
            if ( ( $entry['timestamp'] ?? 0 ) < $cutoff ) continue;
            if ( strtolower( $entry['category'] ?? '' ) === $cat_slug && strtolower( $entry['city'] ?? '' ) === $city ) {
                return true;
            }
        }

        return false;
    }

    /**
     * Record a published post in the dedupe history.
     *
     * @param int    $post_id
     * @param string $cat_slug
     * @param string $city
     * @param array  $startups
     */
    public static function record_post( $post_id, $cat_slug, $city, array $startups = array() ) {
        $history = get_option( self::HISTORY_OPTION, array() );

        $history[] = array(
            'post_id'   => $post_id,
            'category'  => $cat_slug,
            'city'      => $city,
            'startups'  => $startups,
            'timestamp' => time(),
            'date'      => current_time( 'Y-m-d' ),
        );

        // Trim to max entries (keep newest)
        if ( count( $history ) > self::HISTORY_MAX ) {
            $history = array_slice( $history, -self::HISTORY_MAX );
        }

        update_option( self::HISTORY_OPTION, $history, false );

        // Also update the recent startups transient
        self::update_recent_startups( $startups );
    }

    /* =================================================================
     *  STARTUP NAME TRACKING
     * ================================================================= */

    /**
     * Get startup names mentioned in recent posts (last 14 days).
     *
     * @return array Flat array of company names.
     */
    public static function get_recent_startups() {
        $cached = get_transient( self::TRANSIENT_STARTUPS );
        if ( is_array( $cached ) ) {
            return $cached;
        }

        // Rebuild from history
        $history  = get_option( self::HISTORY_OPTION, array() );
        $cutoff   = strtotime( '-14 days' );
        $startups = array();

        foreach ( $history as $entry ) {
            if ( ( $entry['timestamp'] ?? 0 ) < $cutoff ) continue;
            if ( ! empty( $entry['startups'] ) && is_array( $entry['startups'] ) ) {
                $startups = array_merge( $startups, $entry['startups'] );
            }
        }

        $startups = array_unique( array_filter( $startups ) );
        set_transient( self::TRANSIENT_STARTUPS, $startups, DAY_IN_SECONDS );

        return $startups;
    }

    /**
     * Add newly mentioned startups to the recent list.
     *
     * @param array $startups
     */
    private static function update_recent_startups( array $startups ) {
        $existing = get_transient( self::TRANSIENT_STARTUPS );
        if ( ! is_array( $existing ) ) $existing = array();

        $merged = array_unique( array_merge( $existing, array_filter( $startups ) ) );
        set_transient( self::TRANSIENT_STARTUPS, $merged, DAY_IN_SECONDS );
    }

    /* =================================================================
     *  ROTATION RESET
     * ================================================================= */

    /**
     * Reset all daily rotation transients. Used by admin "Reset Rotation" button.
     */
    public static function reset_rotation() {
        delete_transient( self::TRANSIENT_CATS );
        delete_transient( self::TRANSIENT_CITIES );
        delete_transient( self::TRANSIENT_STARTUPS );
        error_log( 'DBA StartupHub Dedupe: Rotation reset — all daily transients cleared.' );
    }
}
