<?php

class TranslationWorker {
    private $workerId;
    private $pdo;
    private $translator;
    private $running = true;
    private $sleepTime = 2; // segundos entre iteraciones
    
    public function __construct($workerId, $pdo) {
        $this->workerId = "worker_" . $workerId . "_" . getmypid();
        $this->pdo = $pdo;
        $this->translator = new Translate();
        
        // Configurar sleep time desde environment
        if (isset($_ENV['TRANSLATION_WORKER_SLEEP'])) {
            $this->sleepTime = (int)$_ENV['TRANSLATION_WORKER_SLEEP'];
        }
        
        custom_log("[{$this->workerId}] Inicializado");
    }
    
    public function run() {
        // Configurar manejadores de señales
        pcntl_async_signals(true);
        pcntl_signal(SIGINT, [$this, 'handleShutdown']);
        pcntl_signal(SIGTERM, [$this, 'handleShutdown']);
        
        custom_log("[{$this->workerId}] Iniciando loop de procesamiento");
        
        while ($this->running) {
            $job = null;
            
            try {
                // Obtener trabajo de la cola
                $job = $this->getNextJob();
                
                if ($job) {
                    $this->processJob($job);
                } else {
                    // No hay trabajos, esperar
                    sleep($this->sleepTime);
                }
                
                // Procesar señales
                pcntl_signal_dispatch();
                
            } catch (Exception $e) {
                custom_log("[{$this->workerId}] Error: " . $e->getMessage());
                if ($job) {
                    $this->markJobAsFailed($job['id'], $e->getMessage());
                }
                sleep($this->sleepTime);
            }
        }
        
        custom_log("[{$this->workerId}] Detenido");
    }
    
    
    private function getNextJob() {
        try {
            // Verificar y reconectar si es necesario
            try {
                $this->pdo->query('SELECT 1');
            } catch (PDOException $e) {
                custom_log("[{$this->workerId}] Reconectando a BD...");
                // La conexión se perdió, será recreada por el pool
                throw $e;
            }
            
            // Iniciar transacción
            $this->pdo->beginTransaction();
            
            // Obtener trabajo con bloqueo (FOR UPDATE SKIP LOCKED)
            $stmt = $this->pdo->prepare("
                SELECT * FROM translation_queue 
                WHERE status = 'pending' 
                  AND attempts < 5 
                ORDER BY priority DESC, created_at ASC 
                LIMIT 1 
                FOR UPDATE SKIP LOCKED
            ");
            $stmt->execute();
            $job = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if ($job) {
                // Marcar como procesando
                $updateStmt = $this->pdo->prepare("
                    UPDATE translation_queue 
                    SET status = 'processing', 
                        attempts = attempts + 1,
                        worker_id = ?,
                        processing_started_at = NOW() 
                    WHERE id = ?
                ");
                $updateStmt->execute([$this->workerId, $job['id']]);
                
                custom_log("[{$this->workerId}] Job #{$job['id']} obtenido (intento #{$job['attempts']})");
            }
            
            // Confirmar transacción
            $this->pdo->commit();
            
            return $job;
            
        } catch (Exception $e) {
            if ($this->pdo->inTransaction()) {
                $this->pdo->rollBack();
            }
            throw $e;
        }
    }
    
    private function processJob($job) {
        custom_log("[{$this->workerId}] Procesando job #{$job['id']}: {$job['source_lang']}->{$job['target_lang']}");
        
        try {
            // Traducir texto
            $translatedText = $this->translator->translateHtml(
                $job['text_to_translate'],
                $job['source_lang'],
                $job['target_lang']
            );
            
            // Verificar que la traducción sea válida
            if ($translatedText && trim(strtolower($translatedText)) !== trim(strtolower($job['text_to_translate']))) {
                // Enviar traducción
                $success = $this->sendTranslation($job, $translatedText);
                
                if ($success) {
                    $this->markJobAsCompleted($job['id']);
                    custom_log("[{$this->workerId}] Job #{$job['id']} completado");
                } else {
                    throw new Exception("Fallo al enviar traducción");
                }
            } else {
                // Traducción vacía o idéntica
                $this->markJobAsCompleted($job['id'], 'Traducción vacía o idéntica al original');
                custom_log("[{$this->workerId}] Job #{$job['id']} completado (sin envío)");
            }
            
        } catch (Exception $e) {
            throw $e;
        }
    }
    
    private function sendTranslation($job, $translatedText) {
        if ($job['platform'] === 'discord') {
            return $this->sendToDiscord($job, $translatedText);
        } else {
            return $this->sendToTelegram($job, $translatedText);
        }
    }
    
    private function sendToDiscord($job, $translatedText) {
        require_once __DIR__ . '/DiscordSender.php';
        
        $discordSender = new DiscordSender($_ENV['DISCORD_BOT_TOKEN']);
        
        // Obtener bandera del idioma
        $flag = $this->getLanguageFlag($job['target_lang']);
        
        $replyContent = "*{$flag} Traducción:*\n> {$translatedText}";
        $response = $discordSender->sendRawMessage($job['chat_id'], $replyContent);
        
        return $response !== null;
    }
    
    private function sendToTelegram($job, $translatedText) {
        require_once __DIR__ . '/TelegramSender.php';
        
        $telegram = new TelegramSender($_ENV['TELEGRAM_BOT_TOKEN'], $this->pdo);
        
        $response = $telegram->sendMessage($job['chat_id'], $translatedText, [
            'parse_mode' => 'HTML',
            'reply_to_message_id' => $job['message_id']
        ], false, $job['target_lang']);
        
        return $response !== null;
    }
    
    private function getLanguageFlag($langCode) {
        try {
            $stmt = $this->pdo->prepare("
                SELECT flag_emoji 
                FROM supported_languages 
                WHERE language_code = ? AND is_active = 1
            ");
            $stmt->execute([$langCode]);
            $flag = $stmt->fetchColumn();
            
            if ($flag) {
                return $flag;
            }
        } catch (Exception $e) {
            // Ignorar error
        }
        
        // Fallback flags
        $fallbackFlags = [
            'es' => '🇲🇽', 'en' => '🇺🇸', 'pt' => '🇵🇹',
            'fr' => '🇫🇷', 'de' => '🇩🇪', 'it' => '🇮🇹'
        ];
        
        return $fallbackFlags[strtolower($langCode)] ?? '🏳️';
    }
    
    private function markJobAsCompleted($jobId, $message = null) {
        $stmt = $this->pdo->prepare("
            UPDATE translation_queue 
            SET status = 'completed',
                error_message = ?,
                processed_at = NOW()
            WHERE id = ?
        ");
        $stmt->execute([$message, $jobId]);
    }
    
    private function markJobAsFailed($jobId, $errorMessage) {
        $stmt = $this->pdo->prepare("
            UPDATE translation_queue 
            SET status = 'failed',
                error_message = ?
            WHERE id = ?
        ");
        $stmt->execute([$errorMessage, $jobId]);
        
        custom_log("[{$this->workerId}] Job #{$jobId} marcado como fallido: {$errorMessage}");
    }
    
    public function handleShutdown($signal) {
        custom_log("[{$this->workerId}] Señal {$signal} recibida, deteniendo...");
        $this->running = false;
    }
}
