<?php

require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/includes/db.php';
require_once __DIR__ . '/includes/env_loader.php';

use Discord\Discord;
use Discord\Parts\Channel\Message;
use Discord\Parts\Guild\Guild;
use Discord\Parts\User\Member;
use Discord\WebSockets\Intents;
use Discord\WebSockets\Event;

$token = $_ENV['DISCORD_BOT_TOKEN'] ?? getenv('DISCORD_BOT_TOKEN');

$discord = new Discord([
    'token' => $token,
    'intents' => Intents::GUILDS | Intents::GUILD_MESSAGES | Intents::DIRECT_MESSAGES | Intents::GUILD_MEMBERS | Intents::GUILD_MESSAGE_REACTIONS | Intents::MESSAGE_CONTENT,
]);

$discord->on('ready', function (Discord $discord) {
    echo "Bot de Discord conectado como: {$discord->user->username}" . PHP_EOL;
    
    $guild = $discord->guilds->first();
    if ($guild) {
        echo "Servidor: {$guild->name}" . PHP_EOL;
    }
});

$discord->on(Event::GUILD_MEMBER_ADD, function (Member $member, Discord $discord) {
    echo "Nuevo miembro: {$member->user->username}" . PHP_EOL;
    
    try {
        $pdo = getDbConnection();
        
        $stmt = $pdo->prepare("
            INSERT INTO recipients (platform_id, name, type, platform, language_code, chat_mode)
            VALUES (?, ?, 'user', 'discord', 'es', 'agent')
            ON DUPLICATE KEY UPDATE name = VALUES(name)
        ");
        $stmt->execute([
            $member->user->id,
            $member->user->username
        ]);
        
        echo "Usuario registrado en la base de datos" . PHP_EOL;
        
        if (!isExistingDiscordUser($pdo, $member->user->id)) {
            sendDiscordWelcomeMessage($pdo, $member, $discord);
        }
        
    } catch (Exception $e) {
        echo "Error al registrar usuario: " . $e->getMessage() . PHP_EOL;
    }
});

$discord->on(Event::MESSAGE_CREATE, function (Message $message, Discord $discord) {
    if ($message->author->bot) {
        return;
    }
    
    $content = $message->content;
    $channelId = $message->channel_id;
    $userId = $message->author->id;
    $username = $message->author->username;
    
    try {
        $pdo = getDbConnection();
        
        $isNewUser = !isExistingDiscordUser($pdo, $userId);
        
        registerDiscordUser($pdo, $message->author);
        
        if ($isNewUser) {
            sendDiscordWelcomeMessageOnMessage($pdo, $message, $username);
        }
        
        if (str_starts_with($content, '#')) {
            $command = ltrim($content, '#');
            handleTemplateCommand($pdo, $message, $command);
            
        } elseif (str_starts_with($content, '/')) {
            handleSlashCommand($pdo, $message, $content);
            
        } else {
            handleRegularMessage($pdo, $message, $content);
        }
        
    } catch (Exception $e) {
        echo "Error: " . $e->getMessage() . PHP_EOL;
    }
});

$discord->on(Event::INTERACTION_CREATE, function ($interaction, Discord $discord) {
    try {
        handleButtonInteraction($interaction, $discord);
    } catch (Exception $e) {
        echo "Error en interacción: " . $e->getMessage() . PHP_EOL;
    }
});

function handleTemplateCommand(PDO $pdo, Message $message, string $command): void
{
    try {
        $stmt = $pdo->prepare("SELECT * FROM recurrent_messages WHERE telegram_command = ?");
        $stmt->execute([$command]);
        $template = $stmt->fetch();
        
        if ($template) {
            require_once __DIR__ . '/discord/converters/HtmlToDiscordMarkdownConverter.php';
            require_once __DIR__ . '/discord/DiscordSender.php';
            require_once __DIR__ . '/src/Translate.php';
            
            $converter = new \Discord\Converters\HtmlToDiscordMarkdownConverter();
        
        $images = $converter->extractImages($template['message_content']);
        $contentWithoutImages = $converter->removeImages($template['message_content']);
        $content = $converter->convert($contentWithoutImages);
        
        require_once __DIR__ . '/discord/DiscordSender.php';
        require_once __DIR__ . '/src/Translate.php';
        
        $sender = new \Discord\DiscordSender();
        
        $plainText = $template['message_content'];
        $plainText = preg_replace('/<br\s*\/?>/i', "\n", $plainText);
        $plainText = preg_replace('/<\/p>/i', "\n", $plainText);
        $plainText = preg_replace('/<p[^>]*>/i', '', $plainText);
        $plainText = strip_tags($plainText);
        $plainText = html_entity_decode($plainText, ENT_QUOTES | ENT_HTML5, 'UTF-8');
        $plainText = trim($plainText);
        
        $translationButtons = getDiscordTranslationButtons($pdo, $plainText);
        
        if (!empty($images)) {
            $sender->sendMessageWithImages((string)$message->channel_id, $content, $images, $translationButtons);
        } else {
            $sender->sendMessage((string)$message->channel_id, $content, null, $translationButtons);
        }
        
    } else {
        $message->channel->sendMessage("❌ Plantilla no encontrada: #{$command}");
    }
    } catch (Exception $e) {
        $message->channel->sendMessage("❌ Error: " . $e->getMessage());
    }
}

function getDiscordTranslationButtons(PDO $pdo, string $text): array
{
    $stmt = $pdo->query("SELECT language_code, flag_emoji FROM supported_languages WHERE is_active = 1");
    $languages = $stmt->fetchAll();
    
    if (count($languages) <= 1) {
        return [];
    }
    
    // Guardar texto en BD con hash consistente
    $textHash = md5($text);
    $stmt = $pdo->prepare("INSERT INTO translation_cache (text_hash, original_text) VALUES (?, ?) ON DUPLICATE KEY UPDATE original_text = VALUES(original_text)");
    $stmt->execute([$textHash, $text]);
    
    $buttons = [];
    foreach ($languages as $lang) {
        $buttons[] = [
            'label' => $lang['flag_emoji'] . ' ' . strtoupper($lang['language_code']),
            'custom_id' => 'translate_' . $lang['language_code'] . ':' . $textHash,
            'style' => 1
        ];
    }
    
    return [
        [
            'type' => 1,
            'components' => array_slice($buttons, 0, 5)
        ]
    ];
}

function handleSlashCommand(PDO $pdo, Message $message, string $content): void
{
    $parts = explode(' ', $content);
    $cmd = strtolower(str_replace('/', '', $parts[0]));
    $args = array_slice($parts, 1);
    
    echo "Comando recibido: {$cmd}" . PHP_EOL;
    
    switch ($cmd) {
        case 'comandos':
            require_once __DIR__ . '/discord/DiscordSender.php';
            
            $msg = "📋 **Comandos disponibles:**\n\n";
            $msg .= "`/comandos` - Ver comandos\n";
            $msg .= "`/setlang [código]` - Establecer idioma\n";
            $msg .= "`/bienvenida` - Mensaje de bienvenida\n";
            $msg .= "`/agente` - Cambiar a modo IA\n";
            
            $stmt = $pdo->query("SELECT name, telegram_command FROM recurrent_messages WHERE telegram_command IS NOT NULL AND telegram_command != '' ORDER BY name");
            $customCommands = $stmt->fetchAll();
            
            if (!empty($customCommands)) {
                $msg .= "\n📦 **Plantillas:**\n";
                foreach ($customCommands as $cmd) {
                    $msg .= "`#" . htmlspecialchars($cmd['telegram_command']) . "` - " . htmlspecialchars($cmd['name']) . "\n";
                }
            }
            
            $translationButtons = getDiscordTranslationButtons($pdo, $msg);
            $sender = new \Discord\DiscordSender();
            $sender->sendMessage((string)$message->channel_id, $msg, null, $translationButtons);
            break;
            
        case 'setlang':
            $langCode = $args[0] ?? 'es';
            $stmt = $pdo->prepare("UPDATE recipients SET language_code = ? WHERE platform_id = ? AND platform = 'discord'");
            $stmt->execute([$langCode, $message->author->id]);
            $message->channel->sendMessage("✅ Idioma actualizado a: " . strtoupper($langCode));
            break;
            
        case 'bienvenida':
            $stmt = $pdo->query("SELECT * FROM telegram_bot_messages WHERE id = 1");
            $config = $stmt->fetch();
            
            if ($config && $config['is_active']) {
                require_once __DIR__ . '/discord/DiscordSender.php';
                
                $text = str_replace('{user_name}', $message->author->username, $config['message_text']);
                
                // Convertir HTML a texto plano para botones de traducción
                $plainText = html_entity_decode(strip_tags($text), ENT_QUOTES | ENT_HTML5, 'UTF-8');
                // Limpiar espacios múltiples pero preservar saltos de línea
                $plainText = preg_replace('/[ \t]+/', ' ', $plainText);
                $plainText = preg_replace('/\n\s*\n/', "\n", $plainText);
                $translationButtons = getDiscordTranslationButtons($pdo, $plainText);
                
                $sender = new \Discord\DiscordSender();
                $sender->sendMessage((string)$message->channel_id, $text, null, $translationButtons);
            }
            break;
            
        case 'agente':
            $builder = \Discord\Builders\MessageBuilder::new();
            $builder->setContent("🤖 **Selecciona un modo de chat:**");
            
            $row = new \Discord\Builders\Components\ActionRow();
            
            $btnBot = \Discord\Builders\Components\Button::new(\Discord\Builders\Components\Button::STYLE_PRIMARY)
                ->setLabel('Seguir con Bot')
                ->setCustomId('chat_mode_bot:' . $message->author->id);
            $btnIa = \Discord\Builders\Components\Button::new(\Discord\Builders\Components\Button::STYLE_SUCCESS)
                ->setLabel('Platicar con IA')
                ->setCustomId('chat_mode_ia:' . $message->author->id);
            
            $row->addComponent($btnBot);
            $row->addComponent($btnIa);
            $builder->addComponent($row);
            
            $message->channel->sendMessage($builder);
            break;
            
        default:
            $message->channel->sendMessage("Comando desconocido. Usa /comandos para ver los disponibles.");
    }
}

function handleRegularMessage(PDO $pdo, Message $message, string $content): void
{
    $stmt = $pdo->prepare("SELECT chat_mode FROM recipients WHERE platform_id = ? AND platform = 'discord'");
    $stmt->execute([$message->author->id]);
    $recipient = $stmt->fetch();
    
    if ($recipient && $recipient['chat_mode'] === 'ia') {
        sendToN8NIA($message, $content);
    } else {
        handleAutoTranslationWithButtons($pdo, $message, $content);
    }
}

function sendToN8NIA(Message $message, string $userMessage): void
{
    require_once __DIR__ . '/includes/env_loader.php';
    
    $webhookUrl = trim($_ENV['N8N_IA_WEBHOOK_URL_DISCORD'] ?? getenv('N8N_IA_WEBHOOK_URL_DISCORD') ?? '');
    $webhookUrl = trim($webhookUrl, '"');
    
    if (!empty($webhookUrl)) {
        $data = [
            'user_id' => (string)$message->author->id,
            'username' => $message->author->username,
            'message' => $userMessage
        ];
        
        $jsonData = json_encode($data);
        
        $ch = curl_init($webhookUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Content-Length: ' . strlen($jsonData)
        ]);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        if ($httpCode >= 200 && $httpCode < 300) {
            $result = json_decode($response, true);
            $reply = $result['reply'] ?? $result['message'] ?? $response;
            $message->channel->sendMessage($reply);
            return;
        }
        
        error_log("N8N Discord IA Error: HTTP $httpCode - Response: $response");
    }
    
    require_once __DIR__ . '/src/IA/Agent.php';
    $agent = new \IA\Agent();
    
    try {
        $response = $agent->generateResponse($userMessage);
        $message->channel->sendMessage($response);
    } catch (\Exception $e) {
        $message->channel->sendMessage("❌ Error: " . $e->getMessage());
        error_log("IA Agent Discord Error: " . $e->getMessage());
    }
}

function handleAutoTranslationWithButtons(PDO $pdo, Message $message, string $text): void
{
    try {
        require_once __DIR__ . '/src/Translate.php';
        $translator = new src\Translate();
        
        // Detectar idioma del mensaje
        $detectedLang = $translator->detectLanguage($text) ?? 'es';
        
        // Obtener idiomas activos de la base de datos
        $stmt = $pdo->query("SELECT language_code, flag_emoji FROM supported_languages WHERE is_active = 1");
        $activeLanguages = $stmt->fetchAll();
        
        if (count($activeLanguages) <= 1) {
            return; // No hay suficientes idiomas para traducir
        }
        
        // Guardar texto en la base de datos con hash consistente
        $textHash = md5($text);
        $stmt = $pdo->prepare("INSERT INTO translation_cache (text_hash, original_text) VALUES (?, ?) ON DUPLICATE KEY UPDATE original_text = VALUES(original_text)");
        $stmt->execute([$textHash, $text]);
        
        // Preparar botones
        $buttons = [];
        foreach ($activeLanguages as $lang) {
            if ($lang['language_code'] !== $detectedLang) {
                $buttons[] = [
                    'label' => $lang['flag_emoji'] . ' ' . strtoupper($lang['language_code']),
                    'custom_id' => 'translate_' . $lang['language_code'] . ':' . $textHash,
                    'style' => 1
                ];
            }
        }
        
        // Enviar mensaje con botones usando MessageBuilder correctamente
        if (!empty($buttons)) {
            $messageText = "🌐 **Traducciones disponibles:**\nHaz clic en una bandera para ver la traducción (solo tú la verás)";
            
            // Crear MessageBuilder
            $builder = \Discord\Builders\MessageBuilder::new();
            $builder->setContent($messageText);
            
            // Crear ActionRow con botones
            $row = new \Discord\Builders\Components\ActionRow();
            
            foreach ($buttons as $btn) {
                $button = \Discord\Builders\Components\Button::new(\Discord\Builders\Components\Button::STYLE_PRIMARY)
                    ->setLabel($btn['label'])
                    ->setCustomId($btn['custom_id']);
                $row->addComponent($button);
            }
            
            $builder->addComponent($row);
            $message->channel->sendMessage($builder);
        }
        
    } catch (Exception $e) {
        error_log("Discord translation buttons error: " . $e->getMessage());
    }
}

function handleButtonInteraction($interaction, Discord $discord): void
{
    $data = $interaction->data;
    $customId = $data->custom_id ?? '';
    
    if (str_starts_with($customId, 'translate_')) {
        handleTranslateInteraction($interaction, $customId);
    } elseif (str_starts_with($customId, 'chat_mode_')) {
        try {
            require_once __DIR__ . '/includes/db.php';
            
            $pdo = getDbConnection();
            
            $parts = explode(':', $customId, 2);
            $mode = str_replace('chat_mode_', '', $parts[0]);
            $userId = $parts[1] ?? '';
            
            if (empty($userId)) {
                $builder = \Discord\Builders\MessageBuilder::new()
                    ->setContent('❌ Error: Usuario no identificado');
                $interaction->respondWithMessage($builder, true);
                return;
            }
            
            $chatMode = ($mode === 'ia') ? 'ia' : 'bot';
            $stmt = $pdo->prepare("UPDATE recipients SET chat_mode = ? WHERE platform_id = ? AND platform = 'discord'");
            $stmt->execute([$chatMode, $userId]);
            
            if ($chatMode === 'ia') {
                $builder = \Discord\Builders\MessageBuilder::new()
                    ->setContent("✅ **Modo IA activado.** Ahora puedes platicar conmigo. Escribe cualquier cosa y la enviaré a la IA.");
            } else {
                $builder = \Discord\Builders\MessageBuilder::new()
                    ->setContent("✅ **Modo Bot activado.** Ahora puedes usar comandos como #comando y traducción.");
            }
            
            $interaction->respondWithMessage($builder, true);
            
        } catch (Exception $e) {
            error_log("Discord chat mode error: " . $e->getMessage());
            $builder = \Discord\Builders\MessageBuilder::new()
                ->setContent('❌ Error al cambiar el modo de chat');
            $interaction->respondWithMessage($builder, true);
        }
    }
}

function isExistingDiscordUser(PDO $pdo, int $userId): bool
{
    $stmt = $pdo->prepare("SELECT id FROM recipients WHERE platform_id = ? AND platform = 'discord'");
    $stmt->execute([$userId]);
    return $stmt->fetch() !== false;
}

function sendDiscordWelcomeMessage(PDO $pdo, Member $member, Discord $discord): void
{
    $stmt = $pdo->query("SELECT * FROM telegram_bot_messages WHERE id = 1");
    $config = $stmt->fetch();
    
    $username = $member->user->username;
    
    if ($config && $config['is_active']) {
        $text = str_replace('{user_name}', $username, $config['message_text']);
        
        try {
            $member->sendMessage($text);
        } catch (Exception $e) {
            echo "No se pudo enviar mensaje privado: " . $e->getMessage() . PHP_EOL;
        }
    } else {
        try {
            $member->sendMessage("¡Hola {$username}! 👋\n\nUsa /comandos para ver los comandos disponibles.");
        } catch (Exception $e) {
            echo "No se pudo enviar mensaje privado: " . $e->getMessage() . PHP_EOL;
        }
    }
}

function registerDiscordUser(PDO $pdo, $user): void
{
    $stmt = $pdo->prepare("
        INSERT INTO recipients (platform_id, name, type, platform, language_code, chat_mode)
        VALUES (?, ?, 'user', 'discord', 'es', 'agent')
        ON DUPLICATE KEY UPDATE name = VALUES(name)
    ");
    
    $name = $user->username ?? 'Usuario';
    $stmt->execute([$user->id, $name]);
}

function sendDiscordWelcomeMessageOnMessage(PDO $pdo, Message $message, string $username): void
{
    $stmt = $pdo->query("SELECT * FROM telegram_bot_messages WHERE id = 1");
    $config = $stmt->fetch();
    
    if ($config && $config['is_active']) {
        $text = str_replace('{user_name}', $username, $config['message_text']);
        $message->author->sendMessage($text);
    } else {
        $message->author->sendMessage("¡Hola {$username}! 👋\n\nUsa /comandos para ver los comandos disponibles.");
    }
}

function handleTranslateInteraction($interaction, string $customId): void
{
    try {
        require_once __DIR__ . '/includes/db.php';
        require_once __DIR__ . '/src/Translate.php';
        
        $pdo = getDbConnection();
        $translator = new src\Translate();
        
        $parts = explode(':', $customId, 2);
        $targetLang = str_replace('translate_', '', $parts[0]);
        $textHash = $parts[1] ?? '';
        
        // Obtener texto de la base de datos primero
        $stmt = $pdo->prepare("SELECT original_text FROM translation_cache WHERE text_hash = ?");
        $stmt->execute([$textHash]);
        $row = $stmt->fetch();
        
        if (!$row || empty($row['original_text'])) {
            // Enviar error efímero
            $builder = \Discord\Builders\MessageBuilder::new()
                ->setContent('❌ Error: Texto no encontrado');
            $interaction->respondWithMessage($builder, true);
            return;
        }
        
        $originalText = $row['original_text'];
        
        // Responder inmediatamente con "Traduciendo..."
        $loadingBuilder = \Discord\Builders\MessageBuilder::new()
            ->setContent("⏳ Traduciendo a " . strtoupper($targetLang) . "...");
        $interaction->respondWithMessage($loadingBuilder, true);
        
        // Ahora traducir (esto puede tardar)
        $sourceLang = $translator->detectLanguage($originalText) ?? 'es';
        $translated = $translator->translate($originalText, $sourceLang, $targetLang);
        
        if ($translated) {
            // Limpiar todo el HTML
            $translated = strip_tags($translated);
            // Limpiar asteriscos duplicados
            $translated = preg_replace('/\*+/', '', $translated);
            // Limpiar comandos con espacios
            $translated = preg_replace('/\/(\s+)(\w+)/', '/$2', $translated);
            $translated = preg_replace('/#(\s+)(\w+)/', '#$2', $translated);
            // Limpiar saltos de línea extras
            $translated = preg_replace('/\n\s*\n/', "\n", $translated);
            
            // Actualizar la respuesta con la traducción real
            $finalBuilder = \Discord\Builders\MessageBuilder::new()
                ->setContent("🌐 **Traducción (" . strtoupper($targetLang) . "):**\n\n" . trim($translated));
            $interaction->updateOriginalResponse($finalBuilder);
        } else {
            // Actualizar con error
            $errorBuilder = \Discord\Builders\MessageBuilder::new()
                ->setContent("❌ Error al traducir");
            $interaction->updateOriginalResponse($errorBuilder);
        }
        
    } catch (Exception $e) {
        error_log("Discord translate error: " . $e->getMessage());
        try {
            $builder = \Discord\Builders\MessageBuilder::new()
                ->setContent('❌ Error en el proceso de traducción');
            $interaction->respondWithMessage($builder, true);
        } catch (Exception $inner) {
            error_log("Error responding to interaction: " . $inner->getMessage());
        }
    }
}

$discord->run();
