<?php
// process_translation_queue.php

// Permitir que el script se ejecute indefinidamente
set_time_limit(0);

require_once __DIR__ . '/includes/logger.php';

custom_log("--- INICIANDO PROCESADOR DE COLA DE TRADUCCIÓN ---");

// Cargar configuración y dependencias
require_once __DIR__ . '/config/config.php';
require_once __DIR__ . '/vendor/autoload.php'; // Asegurarse de que el autoloader de Composer esté cargado
require_once __DIR__ . '/includes/db.php';
require_once __DIR__ . '/src/TelegramSender.php';
require_once __DIR__ . '/src/Translate.php';
require_once __DIR__ . '/src/DiscordSender.php';

// Usar la clase Embed de DiscordPHP
use Discord\Parts\Embed\Embed;

// Instanciar las clases necesarias
$translator = new Translate();

$running = true;

// Manejador de señales para una terminación controlada
pcntl_async_signals(true);
pcntl_signal(SIGINT, function($sig) use (&$running) {
    custom_log("Señal SIGINT recibida. Terminando el worker...");
    $running = false;
});
pcntl_signal(SIGTERM, function($sig) use (&$running) {
    custom_log("Señal SIGTERM recibida. Terminando el worker...");
    $running = false;
});

while ($running) {
    $job = null;
    try {
        // Iniciar transacción
        $pdo->beginTransaction();

        // Obtener un trabajo pendiente y bloquear la fila
        $stmt = $pdo->prepare("SELECT * FROM translation_queue WHERE status = 'pending' AND attempts < 5 ORDER BY created_at ASC LIMIT 1 FOR UPDATE SKIP LOCKED");
        $stmt->execute();
        $job = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($job) {
            // Marcar el trabajo como 'processing'
            $updateStmt = $pdo->prepare("UPDATE translation_queue SET status = 'processing', attempts = attempts + 1, processed_at = NOW() WHERE id = ?");
            $updateStmt->execute([$job['id']]);
            custom_log("[JOB #{$job['id']}] Trabajo obtenido. Marcado como 'processing'. Intento #" . ($job['attempts'] + 1));
        }

        // Confirmar la transacción
        $pdo->commit();

    } catch (Exception $e) {
        if ($pdo->inTransaction()) {
            $pdo->rollBack();
        }
        custom_log("Error al obtener trabajo de la cola: " . $e->getMessage());
        sleep(5); // Esperar antes de reintentar
        continue;
    }

    if ($job) {
        try {
            $success = false;

            if ($job['platform'] === 'discord') {
                // --- LÓGICA MEJORADA PARA DISCORD USANDO UN ARRAY ---
                custom_log("[JOB #{$job['id']}] Procesando trabajo para Discord con múltiples idiomas.");
                $targetLangs = explode(',', $job['target_lang']);
                
                $discordSender = new DiscordSender($_ENV['DISCORD_BOT_TOKEN']);
                
                // Pre-procesar el texto para proteger las menciones de Discord
                $originalText = $job['text_to_translate'];
                $textToTranslateClean = handleDiscordMentions($originalText, 'to_placeholder');

                // Construir el embed como un array simple
                $embedData = [
                    'title' => 'Traducciones',
                    'color' => 0x4A90E2, // Un color azul
                    'timestamp' => date('c'),
                    'fields' => []
                ];

                $translationCount = 0;
                foreach ($targetLangs as $langCode) {
                    if (empty($langCode)) continue;

                    $translatedText = $translator->translateHtml($textToTranslateClean, $job['source_lang'], $langCode);
                    
                    if ($translatedText && trim(strtolower($translatedText)) !== trim(strtolower($textToTranslateClean))) {
                        // Post-procesar para restaurar las menciones de Discord
                        // Primero, decodificar cualquier entidad HTML que el traductor haya podido introducir
                        $decodedText = html_entity_decode($translatedText, ENT_QUOTES | ENT_HTML5, 'UTF-8');
                        $restoredText = handleDiscordMentions($decodedText, 'from_placeholder');

                        // Obtener nombre del idioma y bandera
                        $langInfoStmt = $pdo->prepare("SELECT language_name, flag_emoji FROM supported_languages WHERE language_code = ?");
                        $langInfoStmt->execute([$langCode]);
                        $langInfo = $langInfoStmt->fetch(PDO::FETCH_ASSOC);

                        $fieldName = ($langInfo['flag_emoji'] ?? '🏳️') . ' ' . ($langInfo['language_name'] ?? strtoupper($langCode));
                        
                        $embedData['fields'][] = ['name' => $fieldName, 'value' => $restoredText];
                        $translationCount++;
                    }
                }

                if ($translationCount > 0) {
                    custom_log("[JOB #{$job['id']}] Enviando embed con {$translationCount} traducciones.");
                    $response = $discordSender->sendEmbedData($job['chat_id'], $embedData);
                    if ($response) {
                        $success = true;
                    }
                } else {
                    // Si no hubo traducciones válidas, consideramos el trabajo completado para no reintentarlo.
                    custom_log("[JOB #{$job['id']}] No se generaron traducciones válidas. Marcando como completado.");
                    $success = true; 
                }

            } else {
                // --- LÓGICA MEJORADA PARA TELEGRAM USANDO UN SOLO MENSAJE HTML ---
                custom_log("[JOB #{$job['id']}] Procesando trabajo para Telegram con múltiples idiomas.");
                $targetLangs = explode(',', $job['target_lang']);
                $telegram = new TelegramSender($_ENV['TELEGRAM_BOT_TOKEN'], $pdo);

                $htmlOutput = "<b>Traducciones:</b>\n\n";
                $translationCount = 0;

                foreach ($targetLangs as $langCode) {
                    if (empty($langCode)) continue;

                    $translatedText = $translator->translateHtml($job['text_to_translate'], $job['source_lang'], $langCode);

                    if ($translatedText && trim(strtolower($translatedText)) !== trim(strtolower($job['text_to_translate']))) {
                        // Obtener nombre del idioma y bandera
                        $langInfoStmt = $pdo->prepare("SELECT language_name, flag_emoji FROM supported_languages WHERE language_code = ?");
                        $langInfoStmt->execute([$langCode]);
                        $langInfo = $langInfoStmt->fetch(PDO::FETCH_ASSOC);

                        $lineTitle = ($langInfo['flag_emoji'] ?? '🏳️') . ' <b>' . ($langInfo['language_name'] ?? strtoupper($langCode)) . '</b>';
                        
                        // Append to the HTML string
                        $htmlOutput .= $lineTitle . "\n" . $translatedText . "\n\n";
                        $translationCount++;
                    }
                }

                if ($translationCount > 0) {
                    custom_log("[JOB #{$job['id']}] Enviando mensaje HTML con {$translationCount} traducciones a Telegram.");
                    $response = $telegram->sendMessage($job['chat_id'], trim($htmlOutput), [
                        'parse_mode' => 'HTML',
                        'reply_to_message_id' => $job['message_id']
                    ]);
                    if ($response) {
                        $success = true;
                    }
                } else {
                    custom_log("[JOB #{$job['id']}] No se generaron traducciones válidas para Telegram. Marcando como completado.");
                    $success = true;
                }
            }

            // Marcar estado final del trabajo
            if ($success) {
                $finalStmt = $pdo->prepare("UPDATE translation_queue SET status = 'completed' WHERE id = ?");
                $finalStmt->execute([$job['id']]);
                custom_log("[JOB #{$job['id']}] Trabajo completado exitosamente.");
            } else {
                throw new Exception("El envío a la plataforma '{$job['platform']}' falló o no se generaron traducciones.");
            }

        } catch (Exception $e) {
            $errorMessage = $e->getMessage();
            custom_log("[JOB #{$job['id']}] Error al procesar el trabajo: " . $errorMessage);
            $failStmt = $pdo->prepare("UPDATE translation_queue SET status = 'failed', error_message = ? WHERE id = ?");
            $failStmt->execute([$errorMessage, $job['id']]);
        }
    } else {
        // Si no hay trabajos, esperar
        custom_log("No hay trabajos pendientes. Esperando...");
        sleep(2);
    }
    
    pcntl_signal_dispatch();
}

custom_log("--- PROCESADOR DE COLA DETENIDO ---");

/**
 * Maneja las menciones de Discord, reemplazándolas por placeholders antes de la traducción
 * y restaurándolas después.
 *
 * @param string $text El texto a procesar.
 * @param string $direction 'to_placeholder' para reemplazar menciones por placeholders, 'from_placeholder' para restaurarlas.
 * @return string El texto procesado.
 */
function handleDiscordMentions($text, $direction = 'to_placeholder') {
    static $mentionMap = [];

    if ($direction === 'to_placeholder') {
        $mentionMap = [];
        $placeholderCounter = 0;
        // Simplificado para incluir usuarios, roles y canales
        $pattern = '/<(@!?\d+|@&\d+|#\d+)>/';

        return preg_replace_callback($pattern, function($matches) use (&$mentionMap, &$placeholderCounter) {
            $originalMention = $matches[0]; // Ej: <@12345>
            $placeholder = "MENTION{$placeholderCounter}"; // Ej: MENTION0
            $mentionMap[$placeholder] = $originalMention;
            $placeholderCounter++;
            return '<span class="notranslate">' . $placeholder . '</span>';
        }, $text);

    } elseif ($direction === 'from_placeholder') {
        // Decodificar entidades HTML primero
        $decodedText = html_entity_decode($text, ENT_QUOTES | ENT_HTML5, 'UTF-8');

        // Iterar sobre el mapa y reemplazar cada placeholder
        foreach ($mentionMap as $placeholder => $originalMention) {
            // El patrón busca el placeholder, permitiendo espacios y sin ser sensible a mayúsculas/minúsculas
            $patt = '/<span class="notranslate">\s*' . preg_quote($placeholder, '/') . '\s*<\/span>/i';
            $decodedText = preg_replace($patt, $originalMention, $decodedText, 1);
        }
        return $decodedText;
    }
    return $text;
}

