<?php

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

class AIEO_Effective_Eligibility {

    const TABLE_NAME      = 'aieo_effective_eligibility';
    const SCHEMA_OPTION   = 'aieo_effective_eligibility_schema_version';
    const SCHEMA_VERSION  = 1;

    const SURFACE_FREE_SHIPPING_BAR = 'free_shipping_bar';
    const SURFACE_BRAND_GIFT        = 'brand_gift';
    const SURFACE_COMPLEMENTARY     = 'complementary';
    const SURFACE_STICKY_ATC        = 'sticky_atc';
    const SURFACE_PRODUCT_LABEL     = 'product_label';
    const SURFACE_TRUST_BADGES      = 'trust_badges';
    const SURFACE_WAITLIST          = 'waitlist';
    const SURFACE_WEB_PUSH          = 'web_push_optin';

    const VALID_SURFACES = array(
        self::SURFACE_FREE_SHIPPING_BAR,
        self::SURFACE_BRAND_GIFT,
        self::SURFACE_COMPLEMENTARY,
        self::SURFACE_STICKY_ATC,
        self::SURFACE_PRODUCT_LABEL,
        self::SURFACE_TRUST_BADGES,
        self::SURFACE_WAITLIST,
        self::SURFACE_WEB_PUSH,
    );

    private static $hooks_registered = false;

    public static function bootstrap() {
        self::maybe_install();
        if (self::$hooks_registered) { return; }
        self::$hooks_registered = true;
        
        
        
        
    }

    public static function is_enabled() {
        return (bool) get_option('aieo_use_effective_eligibility', 0);
    }

    
    public static function is_eligible($surface, $audience_key, $product_id = 0) {
        global $wpdb;
        if (!in_array($surface, self::VALID_SURFACES, true)) { return false; }
        if (!self::table_exists()) { return false; }
        $product_id = (int) $product_id;

        $table = self::table_name();
        
        $eligible = $wpdb->get_var($wpdb->prepare(
            "SELECT eligible FROM {$table}
             WHERE surface = %s AND audience_key = %s AND product_id = %d
             LIMIT 1",
            $surface,
            $audience_key,
            $product_id
        ));
        return $eligible !== null ? (bool) $eligible : false;
    }

    
    public static function get_for($surface, $audience_key, $product_id = 0) {
        global $wpdb;
        if (!in_array($surface, self::VALID_SURFACES, true)) { return null; }
        if (!self::table_exists()) { return null; }
        $product_id = (int) $product_id;

        $table = self::table_name();
        
        $row = $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM {$table}
             WHERE surface = %s AND audience_key = %s AND product_id = %d
             LIMIT 1",
            $surface,
            $audience_key,
            $product_id
        ), ARRAY_A);
        if (!is_array($row)) { return null; }
        if (!empty($row['payload'])) {
            $decoded = json_decode((string) $row['payload'], true);
            $row['payload'] = is_array($decoded) ? $decoded : array();
        } else {
            $row['payload'] = array();
        }
        return $row;
    }

    
    public static function set($surface, $audience_key, $product_id, $eligible, $offer_id = null, ?array $payload = null) {
        global $wpdb;
        if (!in_array($surface, self::VALID_SURFACES, true)) { return false; }
        if (!self::table_exists()) { return false; }

        $row = array(
            'surface'      => (string) $surface,
            'audience_key' => (string) $audience_key,
            'product_id'   => (int) $product_id,
            'eligible'     => $eligible ? 1 : 0,
            'offer_id'     => $offer_id !== null ? (int) $offer_id : null,
            'payload'      => $payload !== null ? wp_json_encode($payload) : null,
            'computed_at'  => current_time('mysql', true),
        );
        $formats = array('%s', '%s', '%d', '%d', '%d', '%s', '%s');
        return false !== $wpdb->replace(self::table_name(), $row, $formats);
    }

    
    public static function recompute($product_id, $audience_key) {
        $product_id = (int) $product_id;
        $count = 0;

        
        if ($product_id === 0) {
            
            self::set(
                self::SURFACE_WEB_PUSH,
                $audience_key,
                0,
                $audience_key !== 'guest'
            );
            $count++;

            
            
            
            $rows = apply_filters('aieo_eligibility_compute', array(), 0, $audience_key);
            if (is_array($rows)) {
                foreach ($rows as $surface => $row) {
                    if (!in_array($surface, self::VALID_SURFACES, true)) { continue; }
                    $eligible = !empty($row['eligible']);
                    $offer_id = isset($row['offer_id']) ? (int) $row['offer_id'] : null;
                    $payload  = isset($row['payload']) && is_array($row['payload']) ? $row['payload'] : null;
                    self::set($surface, $audience_key, 0, $eligible, $offer_id, $payload);
                    $count++;
                }
            }
            return $count;
        }

        
        if (!function_exists('wc_get_product')) { return 0; }
        $product = wc_get_product($product_id);
        if (!$product) { return 0; }

        
        self::set(self::SURFACE_STICKY_ATC, $audience_key, $product_id, true);
        $count++;

        
        
        
        
        $rows = apply_filters('aieo_eligibility_compute', array(), $product_id, $audience_key);
        if (is_array($rows)) {
            foreach ($rows as $surface => $row) {
                if (!in_array($surface, self::VALID_SURFACES, true)) { continue; }
                $eligible = !empty($row['eligible']);
                $offer_id = isset($row['offer_id']) ? (int) $row['offer_id'] : null;
                $payload  = isset($row['payload']) && is_array($row['payload']) ? $row['payload'] : null;
                self::set($surface, $audience_key, $product_id, $eligible, $offer_id, $payload);
                $count++;
            }
        }

        return $count;
    }

    
    public static function recompute_all_audiences($product_id) {
        $total = 0;
        $audiences = class_exists('AIEO_Identity_Bridge')
            ? AIEO_Identity_Bridge::known_audience_keys()
            : array('guest');
        foreach ($audiences as $key) {
            $total += self::recompute($product_id, $key);
        }
        return $total;
    }

    
    
    

    public static function table_name() {
        global $wpdb;
        return $wpdb->prefix . self::TABLE_NAME;
    }

    public static function table_exists() {
        static $cached = null;
        if ($cached !== null) { return $cached; }
        global $wpdb;
        $found = (int) $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = %s",
            self::table_name()
        ));
        return $cached = ($found > 0);
    }

    public static function maybe_install() {
        $current = (int) get_option(self::SCHEMA_OPTION, 0);
        if ($current >= self::SCHEMA_VERSION) {
            
            
            
            
            
            
            if (!is_admin() && !wp_doing_cron()) {
                return;
            }
            if (self::table_exists()) {
                return;
            }
        }
        global $wpdb;
        $table = self::table_name();
        $charset = $wpdb->get_charset_collate();

        $sql = "CREATE TABLE {$table} (
            surface VARCHAR(32) NOT NULL,
            product_id BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
            audience_key VARCHAR(64) NOT NULL,
            eligible TINYINT(1) NOT NULL DEFAULT 0,
            offer_id BIGINT(20) UNSIGNED DEFAULT NULL,
            payload LONGTEXT DEFAULT NULL,
            computed_at DATETIME NOT NULL,
            PRIMARY KEY (surface, audience_key, product_id),
            KEY ix_audience (audience_key),
            KEY ix_offer (offer_id)
        ) {$charset};";

        require_once ABSPATH . 'wp-admin/includes/upgrade.php';
        dbDelta($sql);
        update_option(self::SCHEMA_OPTION, self::SCHEMA_VERSION, 'no');
    }
}
