<?php

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

class AIEO_DMM_Cache {

    const GROUP        = 'aieo_dmm';
    const TTL_SHORT    = 600;   
    const TTL_MEDIUM   = 3600;  
    const VERSION_OPTION_PREFIX = 'aieo_dmm_cache_v_';

    
    private static $l1 = array();

    
    public static function remember($domain, $key, callable $loader, $ttl = self::TTL_MEDIUM) {
        $full = self::compose_key($domain, $key);

        if (array_key_exists($full, self::$l1)) {
            return self::$l1[$full];
        }

        $cached = wp_cache_get($full, self::GROUP, false, $found);
        if ($found) {
            self::$l1[$full] = $cached;
            return $cached;
        }

        $value = $loader();
        wp_cache_set($full, $value, self::GROUP, (int) $ttl);
        self::$l1[$full] = $value;
        return $value;
    }

    
    public static function put($domain, $key, $value, $ttl = self::TTL_MEDIUM) {
        $full = self::compose_key($domain, $key);
        self::$l1[$full] = $value;
        wp_cache_set($full, $value, self::GROUP, (int) $ttl);
    }

    
    public static function put_l1($domain, $key, $value) {
        $full = self::compose_key($domain, $key);
        self::$l1[$full] = $value;
    }

    
    public static function get_l1($domain, $key) {
        $full = self::compose_key($domain, $key);
        return array_key_exists($full, self::$l1) ? self::$l1[$full] : null;
    }

    public static function has_l1($domain, $key) {
        $full = self::compose_key($domain, $key);
        return array_key_exists($full, self::$l1);
    }

    
    public static function bump_version($domain = '*') {
        $domains = $domain === '*'
            ? array('prices', 'brands', 'gifts', 'loyalty', 'shipping', 'needs', 'feeds')
            : array($domain);

        foreach ($domains as $d) {
            $opt = self::VERSION_OPTION_PREFIX . $d;
            $v = (int) get_option($opt, 1);
            update_option($opt, $v + 1, false);
            
            
            
            do_action('aieo_dmm_cache_version_bumped', $d);
        }

        
        self::$l1 = array();
    }

    
    private static function get_version($domain) {
        $opt = self::VERSION_OPTION_PREFIX . $domain;
        $v   = (int) get_option($opt, 1);
        return $v > 0 ? $v : 1;
    }

    
    private static function compose_key($domain, $key) {
        return $domain . ':' . self::get_version($domain) . ':' . $key;
    }

    
    public static function user_context_key($user_id = null) {
        if ($user_id === null) {
            $user_id = get_current_user_id();
        }
        $user_id = (int) $user_id;

        
        if (isset(self::$l1['__uctx:' . $user_id])) {
            return self::$l1['__uctx:' . $user_id];
        }

        $roles = array();
        if ($user_id > 0) {
            $user = get_userdata($user_id);
            if ($user && !empty($user->roles) && is_array($user->roles)) {
                $roles = $user->roles;
            }
        } else {
            $roles = array('guest');
        }
        sort($roles);

        $loyalty = array();
        if ($user_id > 0 && class_exists('AIEO_DMM_Pricing_Engine')) {
            $loyalty = AIEO_DMM_Pricing_Engine::instance()->get_loyalty_class_ids_for_user($user_id);
            sort($loyalty);
        }

        $ctx = md5(implode(',', $roles) . '|' . implode(',', $loyalty));
        self::$l1['__uctx:' . $user_id] = $ctx;
        return $ctx;
    }
}
