<?php
if (!defined('ABSPATH')) exit;

class Botami_Session_Handler {
    private static $instance = null;
    private $session_id;
    private $cookie_name = 'botami_chat_session_id';
    private $cookie_expiry = 30 * DAY_IN_SECONDS; // 30 days
    private $session_initialized = false;
    
    private function __construct() {
        // Initialize session early and only once
        add_action('init', array($this, 'initialize_session'), 1);
    }
    
    public static function getInstance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    /**
     * Initialize session on WordPress init hook
     */
    public function initialize_session() {
        if (!$this->session_initialized) {
            $this->session_id = $this->get_or_create_session_id();
            $this->session_initialized = true;
        }
    }
    
    /**
     * Get existing session ID from cookie or create a new one
     * 
     * @return string Session ID
     */
    private function get_or_create_session_id() {
        // First check if we already have a session ID in this request
        if (!empty($this->session_id)) {
            return $this->session_id;
        }
        
        // Check if user has existing session cookie
        if (isset($_COOKIE[$this->cookie_name]) && !empty($_COOKIE[$this->cookie_name])) {
            $session_id = sanitize_text_field($_COOKIE[$this->cookie_name]);
            
            // Validate the session ID format
            if (strlen($session_id) > 10) {
                return $session_id;
            }
        }
        
        // Create new session ID
        $session_id = $this->generate_session_id();
        
        // Set cookie for future requests
        $this->set_session_cookie($session_id);
        
        return $session_id;
    }
    
    /**
     * Generate a unique session ID
     * 
     * @return string Generated session ID
     */
    private function generate_session_id() {
        return wp_hash(uniqid('botami_', true));
    }
    
    /**
     * Set the session cookie
     * 
     * @param string $session_id Session ID to store
     */
    private function set_session_cookie($session_id) {
        // Set in $_COOKIE immediately for current request
        $_COOKIE[$this->cookie_name] = $session_id;
        
        // Only set actual cookie if headers haven't been sent
        if (!headers_sent()) {
            setcookie(
                $this->cookie_name,
                $session_id,
                time() + $this->cookie_expiry,
                COOKIEPATH,
                COOKIE_DOMAIN,
                is_ssl(),
                true // HTTP only for security
            );
        }
    }
    
    /**
     * Get the current session ID
     * 
     * @return string Session ID
     */
    public function get_session_id() {
        // Ensure session is initialized
        if (!$this->session_initialized) {
            $this->initialize_session();
        }
        
        return $this->session_id;
    }
    
    /**
     * Store data in session using WordPress transients
     * 
     * @param string $key Data key
     * @param mixed $value Data value
     * @param int $expiration Expiration time (default: 30 days)
     * @return bool True on success, false on failure
     */
    public function set_session_data($key, $value, $expiration = null) {
        if ($expiration === null) {
            $expiration = $this->cookie_expiry;
        }
        
        $transient_key = 'botami_session_' . $this->session_id . '_' . $key;
        return set_transient($transient_key, $value, $expiration);
    }
    
    /**
     * Get data from session using WordPress transients
     * 
     * @param string $key Data key
     * @param mixed $default Default value if key doesn't exist
     * @return mixed Stored value or default
     */
    public function get_session_data($key, $default = null) {
        $transient_key = 'botami_session_' . $this->session_id . '_' . $key;
        $value = get_transient($transient_key);
        
        return ($value !== false) ? $value : $default;
    }
    
    /**
     * Delete data from session
     * 
     * @param string $key Data key to delete
     * @return bool True on success, false on failure
     */
    public function delete_session_data($key) {
        $transient_key = 'botami_session_' . $this->session_id . '_' . $key;
        return delete_transient($transient_key);
    }
    
    /**
     * Clear all session data for current session
     * 
     * @return bool True on success
     */
    public function clear_session() {
        global $wpdb;
        
        // Delete all transients for this session
        $transient_pattern = 'botami_session_' . $this->session_id . '_%';
        
        $wpdb->query(
            $wpdb->prepare(
                "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s OR option_name LIKE %s",
                '_transient_' . $transient_pattern,
                '_transient_timeout_' . $transient_pattern
            )
        );
        
        return true;
    }
    
    /**
     * Destroy the current session completely
     * 
     * @return bool True on success
     */
    public function destroy_session() {
        // Clear all session data
        $this->clear_session();
        
        // Delete the session cookie
        if (!headers_sent()) {
            setcookie(
                $this->cookie_name,
                '',
                time() - 3600,
                COOKIEPATH,
                COOKIE_DOMAIN,
                is_ssl(),
                true
            );
        }
        
        // Remove from $_COOKIE
        unset($_COOKIE[$this->cookie_name]);
        
        // Generate new session ID
        $this->session_id = $this->generate_session_id();
        $this->set_session_cookie($this->session_id);
        
        return true;
    }
    
    /**
     * Check if session is valid (has a valid session ID)
     * 
     * @return bool True if session is valid
     */
    public function is_valid_session() {
        return !empty($this->session_id);
    }
}