<?php
/**
 * SSE Stream Handler for AI Auto Tool
 * 
 * @package AI_Auto_Tool
 */

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

/**
 * Class AIAutoTool_SSE_Stream
 * Handles Server-Sent Events streaming for article writing with analysis
 */
class AIAutoTool_SSE_Stream {
    
    private $started = false;
    private $message_id = null;
    
    /**
     * Start SSE stream
     */
    public function start() {
        if ($this->started) {
            return;
        }
        
        // Prevent any output buffering
        while (ob_get_level()) {
            ob_end_clean();
        }
        
        // Set headers for SSE
        header('Content-Type: text/event-stream');
        header('Cache-Control: no-cache');
        header('Connection: keep-alive');
        header('X-Accel-Buffering: no'); // Disable nginx buffering
        
        // Disable PHP output buffering
        if (function_exists('apache_setenv')) {
            @apache_setenv('no-gzip', '1');
        }
        
        @ini_set('zlib.output_compression', '0');
        @ini_set('implicit_flush', '1');
        
        $this->started = true;
        
        // Send initial connection message
        $this->send('connected', array(
            'message' => 'Connected to AI Article Writer',
            'timestamp' => current_time('mysql')
        ));
    }
    
    /**
     * Set message ID for this stream
     * 
     * @param string $message_id Message ID
     */
    public function set_message_id($message_id) {
        $this->message_id = $message_id;
    }
    
    /**
     * Get current message ID
     * 
     * @return string|null Message ID
     */
    public function get_message_id() {
        return $this->message_id;
    }
    
    /**
     * Send SSE event
     * 
     * @param string $event_type Event type
     * @param mixed $data Event data
     */
    public function send($event_type, $data) {
        if (!$this->started) {
            $this->start();
        }
        
        // Add message_id to data if available and not already set
        if ($this->message_id && !isset($data['message_id'])) {
            $data['message_id'] = $this->message_id;
        }
        
        // Format data
        $json_data = json_encode($data, JSON_UNESCAPED_UNICODE);
        
        // Send event
        echo "event: {$event_type}\n";
        echo "data: {$json_data}\n\n";
        
        // Flush output
        if (ob_get_level()) {
            ob_flush();
        }
        flush();
    }
    
    /**
     * Send status update
     * 
     * @param string $message Status message
     */
    public function send_status($message) {
        $this->send('status', array(
            'message' => $message,
            'timestamp' => current_time('mysql')
        ));
    }
    
    /**
     * Send step start event
     * 
     * @param int $step_number Step number
     * @param string $step_name Step name
     * @param string $description Step description
     */
    public function send_step_start($step_number, $step_name, $description) {
        $this->send('step_start', array(
            'step' => $step_number,
            'name' => $step_name,
            'description' => $description,
            'timestamp' => current_time('mysql')
        ));
    }
    
    /**
     * Send step output (analysis content)
     * 
     * @param int $step_number Step number
     * @param string $output Step output/analysis content
     */
    public function send_step_output($step_number, $output) {
        $this->send('step_output', array(
            'step' => $step_number,
            'output' => $output,
            'timestamp' => current_time('mysql')
        ));
    }
    
    /**
     * Send step completion
     * 
     * @param int $step_number Step number
     * @param string $status Status (success/error)
     * @param mixed $result Step result
     */
    public function send_step_complete($step_number, $status, $result = null) {
        $this->send('step_complete', array(
            'step' => $step_number,
            'status' => $status,
            'result' => $result,
            'timestamp' => current_time('mysql')
        ));
    }
    
    /**
     * Send progress update
     * 
     * @param int $current Current progress
     * @param int $total Total steps
     * @param string $message Progress message
     */
    public function send_progress($current, $total, $message = '') {
        $percentage = $total > 0 ? round(($current / $total) * 100) : 0;
        
        $this->send('progress', array(
            'current' => $current,
            'total' => $total,
            'percentage' => $percentage,
            'message' => $message,
            'timestamp' => current_time('mysql')
        ));
    }
    
    /**
     * Send error event
     * 
     * @param string $message Error message
     * @param mixed $details Error details
     * @param string|null $message_id Message ID (optional, will use stored if not provided)
     */
    public function send_error($message, $details = null, $message_id = null) {
        $data = array(
            'message' => $message,
            'details' => $details,
            'timestamp' => current_time('mysql')
        );
        
        // Use provided message_id or stored one
        if ($message_id !== null) {
            $data['message_id'] = $message_id;
        } elseif ($this->message_id) {
            $data['message_id'] = $this->message_id;
        }
        
        $this->send('error', $data);
    }
    
    /**
     * Send completion event with final article content
     * 
     * @param string $content Final article content
     * @param mixed $result Final result data
     * @param string|null $message_id Message ID (optional, will use stored if not provided)
     */
    public function send_complete($content, $result = null, $message_id = null) {
        $data = array(
            'content' => $content,
            'result' => $result,
            'timestamp' => current_time('mysql')
        );
        
        // Use provided message_id or stored one
        if ($message_id !== null) {
            $data['message_id'] = $message_id;
        } elseif ($this->message_id) {
            $data['message_id'] = $this->message_id;
        }
        
        $this->send('complete', $data);
    }
    
    /**
     * Close stream
     */
    public function close() {
        $this->send('done', array(
            'message' => 'Stream closed',
            'timestamp' => current_time('mysql')
        ));
        
        exit;
    }
}

