/**
 * SLM Framework - Notifications Service
 * Sistema de notificaciones multi-canal
 *
 * Canales soportados:
 * - ✅ Email (Nodemailer) - Implementado
 * - 🚧 Slack - Preparado para futuro
 * - 🚧 WhatsApp - Preparado para futuro
 */

require('dotenv').config();
const nodemailer = require('nodemailer');

// Logger se carga de forma "lazy"
let logger = null;
function getLogger() {
    if (!logger) {
        try {
            logger = require('./logger.slm');
        } catch (err) {
            logger = console;
        }
    }
    return logger;
}

//======================================================================================================================
// CONFIGURACIÓN
//======================================================================================================================

const config = {
    // Email configuration
    email: {
        enabled: process.env.NOTIFICATIONS_EMAIL_ENABLED === 'true',
        host: process.env.SMTP_HOST || 'localhost',
        port: parseInt(process.env.SMTP_PORT || '1025'), // MailHog default
        secure: process.env.SMTP_SECURE === 'true',
        auth: {
            user: process.env.SMTP_USER || '',
            pass: process.env.SMTP_PASS || ''
        },
        from: process.env.SMTP_FROM || 'noreply@slm-framework.local',
        fromName: process.env.SMTP_FROM_NAME || 'SLM Framework API'
    },

    // Slack configuration (futuro)
    slack: {
        enabled: process.env.NOTIFICATIONS_SLACK_ENABLED === 'true',
        webhookUrl: process.env.SLACK_WEBHOOK_URL || '',
        channel: process.env.SLACK_CHANNEL || '#alerts',
        username: process.env.SLACK_USERNAME || 'SLM Framework Bot',
        iconEmoji: process.env.SLACK_ICON_EMOJI || ':robot_face:'
    },

    // WhatsApp configuration (futuro)
    whatsapp: {
        enabled: process.env.NOTIFICATIONS_WHATSAPP_ENABLED === 'true',
        apiUrl: process.env.WHATSAPP_API_URL || '',
        apiKey: process.env.WHATSAPP_API_KEY || '',
        phoneNumber: process.env.WHATSAPP_PHONE || ''
    },

    // General configuration
    defaultChannel: process.env.NOTIFICATIONS_DEFAULT_CHANNEL || 'email',
    retryAttempts: parseInt(process.env.NOTIFICATIONS_RETRY_ATTEMPTS || '3'),
    retryDelay: parseInt(process.env.NOTIFICATIONS_RETRY_DELAY || '5000')
};

//======================================================================================================================
// EMAIL SERVICE (Nodemailer)
//======================================================================================================================

let emailTransporter = null;

/**
 * Crea el transportador de email
 * @returns {Object} Transportador de Nodemailer
 */
function createEmailTransporter() {
    if (emailTransporter) {
        return emailTransporter;
    }

    try {
        const transportConfig = {
            host: config.email.host,
            port: config.email.port,
            secure: config.email.secure
        };

        // Solo agregar auth si hay credenciales
        if (config.email.auth.user && config.email.auth.pass) {
            transportConfig.auth = config.email.auth;
        }

        emailTransporter = nodemailer.createTransport(transportConfig);

        getLogger().info('Email transporter created', {
            type: 'EMAIL_TRANSPORTER',
            host: config.email.host,
            port: config.email.port,
            secure: config.email.secure
        });

        return emailTransporter;
    } catch (error) {
        getLogger().error('Error creating email transporter', {
            type: 'EMAIL_TRANSPORTER_ERROR',
            error: error.message
        });
        throw error;
    }
}

/**
 * Envía un email
 * @param {Object} options - Opciones del email
 * @param {string} options.to - Destinatario
 * @param {string} options.subject - Asunto
 * @param {string} options.text - Contenido texto plano
 * @param {string} options.html - Contenido HTML (opcional)
 * @returns {Promise<Object>} Resultado del envío
 */
async function sendEmail({ to, subject, text, html = null }) {
    if (!config.email.enabled) {
        getLogger().info('Email notifications disabled, skipping', {
            type: 'EMAIL_DISABLED',
            to,
            subject
        });
        return { success: false, message: 'Email notifications disabled' };
    }

    if (!to) {
        throw new Error('Email recipient (to) is required');
    }

    try {
        const transporter = createEmailTransporter();

        const mailOptions = {
            from: `"${config.email.fromName}" <${config.email.from}>`,
            to,
            subject,
            text
        };

        if (html) {
            mailOptions.html = html;
        }

        const info = await transporter.sendMail(mailOptions);

        getLogger().info('Email sent successfully', {
            type: 'EMAIL_SENT',
            to,
            subject,
            messageId: info.messageId
        });

        return {
            success: true,
            messageId: info.messageId,
            response: info.response
        };

    } catch (error) {
        getLogger().error('Error sending email', {
            type: 'EMAIL_ERROR',
            to,
            subject,
            error: error.message
        });
        throw error;
    }
}

/**
 * Envía un email con reintentos
 * @param {Object} options - Opciones del email
 * @param {number} attempts - Intentos restantes
 * @returns {Promise<Object>} Resultado del envío
 */
async function sendEmailWithRetry(options, attempts = config.retryAttempts) {
    try {
        return await sendEmail(options);
    } catch (error) {
        if (attempts > 1) {
            getLogger().warning('Email send failed, retrying', {
                type: 'EMAIL_RETRY',
                attemptsLeft: attempts - 1,
                delay: config.retryDelay
            });

            await new Promise(resolve => setTimeout(resolve, config.retryDelay));
            return sendEmailWithRetry(options, attempts - 1);
        }

        throw error;
    }
}

//======================================================================================================================
// SLACK SERVICE (Preparado para futuro)
//======================================================================================================================

/**
 * Envía notificación a Slack
 * @param {Object} options - Opciones de la notificación
 * @param {string} options.text - Texto del mensaje
 * @param {string} options.channel - Canal (opcional)
 * @param {Array} options.attachments - Adjuntos Slack (opcional)
 * @returns {Promise<Object>} Resultado del envío
 */
async function sendSlackNotification({ text, channel = null, attachments = null }) {
    if (!config.slack.enabled) {
        getLogger().info('Slack notifications disabled, skipping', {
            type: 'SLACK_DISABLED',
            text: text.substring(0, 50)
        });
        return { success: false, message: 'Slack notifications disabled' };
    }

    if (!config.slack.webhookUrl) {
        throw new Error('Slack webhook URL not configured');
    }

    try {
        // TODO: Implementar envío a Slack usando webhook
        // const axios = require('axios');
        //
        // const payload = {
        //     username: config.slack.username,
        //     icon_emoji: config.slack.iconEmoji,
        //     channel: channel || config.slack.channel,
        //     text
        // };
        //
        // if (attachments) {
        //     payload.attachments = attachments;
        // }
        //
        // const response = await axios.post(config.slack.webhookUrl, payload);

        getLogger().info('Slack notification would be sent (not implemented yet)', {
            type: 'SLACK_NOT_IMPLEMENTED',
            channel: channel || config.slack.channel,
            text: text.substring(0, 50)
        });

        return {
            success: false,
            message: 'Slack integration not implemented yet'
        };

    } catch (error) {
        getLogger().error('Error sending Slack notification', {
            type: 'SLACK_ERROR',
            error: error.message
        });
        throw error;
    }
}

//======================================================================================================================
// WHATSAPP SERVICE (Preparado para futuro)
//======================================================================================================================

/**
 * Envía notificación a WhatsApp
 * @param {Object} options - Opciones de la notificación
 * @param {string} options.phoneNumber - Número de teléfono
 * @param {string} options.message - Mensaje
 * @returns {Promise<Object>} Resultado del envío
 */
async function sendWhatsAppNotification({ phoneNumber, message }) {
    if (!config.whatsapp.enabled) {
        getLogger().info('WhatsApp notifications disabled, skipping', {
            type: 'WHATSAPP_DISABLED',
            phoneNumber
        });
        return { success: false, message: 'WhatsApp notifications disabled' };
    }

    if (!config.whatsapp.apiUrl || !config.whatsapp.apiKey) {
        throw new Error('WhatsApp API not configured');
    }

    try {
        // TODO: Implementar envío a WhatsApp usando API
        // Ejemplo usando Twilio WhatsApp API:
        //
        // const twilio = require('twilio');
        // const client = twilio(accountSid, authToken);
        //
        // const result = await client.messages.create({
        //     from: `whatsapp:${config.whatsapp.phoneNumber}`,
        //     to: `whatsapp:${phoneNumber}`,
        //     body: message
        // });

        getLogger().info('WhatsApp notification would be sent (not implemented yet)', {
            type: 'WHATSAPP_NOT_IMPLEMENTED',
            phoneNumber
        });

        return {
            success: false,
            message: 'WhatsApp integration not implemented yet'
        };

    } catch (error) {
        getLogger().error('Error sending WhatsApp notification', {
            type: 'WHATSAPP_ERROR',
            error: error.message
        });
        throw error;
    }
}

//======================================================================================================================
// NOTIFICACIÓN MULTI-CANAL
//======================================================================================================================

/**
 * Envía notificación a múltiples canales
 * @param {Object} options - Opciones de la notificación
 * @param {string} options.subject - Asunto/título
 * @param {string} options.message - Mensaje
 * @param {Array<string>} options.channels - Canales a usar ['email', 'slack', 'whatsapp']
 * @param {Object} options.emailRecipients - Destinatarios de email
 * @param {Object} options.slackOptions - Opciones específicas de Slack
 * @param {Object} options.whatsappRecipients - Destinatarios de WhatsApp
 * @returns {Promise<Object>} Resultados por canal
 */
async function sendMultiChannelNotification({
    subject,
    message,
    channels = ['email'],
    emailRecipients = null,
    slackOptions = null,
    whatsappRecipients = null
}) {
    const results = {};

    for (const channel of channels) {
        try {
            switch (channel) {
                case 'email':
                    if (emailRecipients) {
                        results.email = await sendEmailWithRetry({
                            to: emailRecipients,
                            subject,
                            text: message
                        });
                    }
                    break;

                case 'slack':
                    results.slack = await sendSlackNotification({
                        text: `*${subject}*\n\n${message}`,
                        ...slackOptions
                    });
                    break;

                case 'whatsapp':
                    if (whatsappRecipients) {
                        results.whatsapp = await sendWhatsAppNotification({
                            phoneNumber: whatsappRecipients,
                            message: `*${subject}*\n\n${message}`
                        });
                    }
                    break;

                default:
                    getLogger().warning('Unknown notification channel', {
                        type: 'UNKNOWN_CHANNEL',
                        channel
                    });
            }
        } catch (error) {
            results[channel] = {
                success: false,
                error: error.message
            };
        }
    }

    return results;
}

//======================================================================================================================
// TEMPLATES DE NOTIFICACIONES
//======================================================================================================================

/**
 * Envía notificación de error del sistema
 * @param {Object} errorInfo - Información del error
 * @returns {Promise<Object>} Resultado del envío
 */
async function sendSystemErrorNotification(errorInfo) {
    const subject = `[ERROR] ${errorInfo.type || 'System Error'} - SLM Framework API`;
    const message = `
Error del Sistema

Tipo: ${errorInfo.type || 'Unknown'}
Timestamp: ${new Date().toISOString()}
Servidor: ${process.env.API_NAME || 'SLM Framework API'}

Mensaje: ${errorInfo.message || 'No message'}

${errorInfo.stack ? `Stack Trace:\n${errorInfo.stack}` : ''}

${errorInfo.details ? `Detalles:\n${JSON.stringify(errorInfo.details, null, 2)}` : ''}
    `.trim();

    return await sendEmailWithRetry({
        to: process.env.SYSTEM_ERROR_EMAIL || process.env.MEMORY_ALERT_EMAIL || '',
        subject,
        text: message
    });
}

/**
 * Envía notificación de servicio
 * @param {Object} serviceInfo - Información del servicio
 * @returns {Promise<Object>} Resultado del envío
 */
async function sendServiceNotification(serviceInfo) {
    const subject = `[INFO] ${serviceInfo.title || 'Service Notification'} - SLM Framework API`;
    const message = `
${serviceInfo.title || 'Notificación del Servicio'}

Timestamp: ${new Date().toISOString()}
Servidor: ${process.env.API_NAME || 'SLM Framework API'}

${serviceInfo.message || ''}

${serviceInfo.details ? `Detalles:\n${JSON.stringify(serviceInfo.details, null, 2)}` : ''}
    `.trim();

    return await sendEmailWithRetry({
        to: process.env.SERVICE_NOTIFICATION_EMAIL || process.env.MEMORY_ALERT_EMAIL || '',
        subject,
        text: message
    });
}

//======================================================================================================================
// VERIFICACIÓN Y TESTING
//======================================================================================================================

/**
 * Verifica la configuración de notificaciones
 * @returns {Object} Estado de cada canal
 */
async function checkNotificationsStatus() {
    const status = {
        email: {
            enabled: config.email.enabled,
            configured: !!(config.email.host && config.email.from),
            ready: false
        },
        slack: {
            enabled: config.slack.enabled,
            configured: !!config.slack.webhookUrl,
            ready: false
        },
        whatsapp: {
            enabled: config.whatsapp.enabled,
            configured: !!(config.whatsapp.apiUrl && config.whatsapp.apiKey),
            ready: false
        }
    };

    // Verificar email
    if (status.email.enabled && status.email.configured) {
        try {
            const transporter = createEmailTransporter();
            await transporter.verify();
            status.email.ready = true;
        } catch (error) {
            status.email.error = error.message;
        }
    }

    // Slack y WhatsApp siempre false hasta implementar
    status.slack.ready = false;
    status.whatsapp.ready = false;

    return status;
}

/**
 * Envía email de prueba
 * @param {string} to - Destinatario
 * @returns {Promise<Object>} Resultado del envío
 */
async function sendTestEmail(to) {
    return await sendEmail({
        to,
        subject: '[TEST] SLM Framework API - Test Email',
        text: `
Este es un email de prueba del sistema de notificaciones.

Servidor: ${process.env.API_NAME || 'SLM Framework API'}
Timestamp: ${new Date().toISOString()}
Environment: ${process.env.NODE_ENV || 'development'}

Si recibes este mensaje, el sistema de notificaciones por email está funcionando correctamente.

---
SLM Framework Notifications System
        `.trim()
    });
}

//======================================================================================================================
// EXPORTS
//======================================================================================================================

module.exports = {
    // Email
    sendEmail,
    sendEmailWithRetry,
    sendTestEmail,

    // Slack (futuro)
    sendSlackNotification,

    // WhatsApp (futuro)
    sendWhatsAppNotification,

    // Multi-canal
    sendMultiChannelNotification,

    // Templates
    sendSystemErrorNotification,
    sendServiceNotification,

    // Verificación
    checkNotificationsStatus,

    // Configuración
    config
};
