import nodemailer from 'nodemailer';
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

// Email templates for different notification types
const emailTemplates = {
  info: {
    color: '#3b82f6',
    backgroundColor: '#eff6ff',
    icon: 'ℹ️'
  },
  success: {
    color: '#10b981',
    backgroundColor: '#ecfdf5',
    icon: '✅'
  },
  warning: {
    color: '#f59e0b',
    backgroundColor: '#fffbeb',
    icon: '⚠️'
  },
  error: {
    color: '#ef4444',
    backgroundColor: '#fef2f2',
    icon: '❌'
  },
  reminder: {
    color: '#8b5cf6',
    backgroundColor: '#f3e8ff',
    icon: '⏰'
  },
  status: {
    color: '#6366f1',
    backgroundColor: '#eef2ff',
    icon: '📊'
  }
};

// Create Nodemailer transporter with configurable email provider settings
function createTransporter() {
  // Default configuration for common providers
  const providerConfigs = {
    gmail: {
      host: 'smtp.gmail.com',
      port: 587,
      secure: false
    },
    outlook: {
      host: 'smtp-mail.outlook.com',
      port: 587,
      secure: false
    },
    yahoo: {
      host: 'smtp.mail.yahoo.com',
      port: 587,
      secure: false
    },
    proton: {
      host: 'mail.protonmail.ch',
      port: 587,
      secure: false,
      tls: {
        ciphers: 'SSLv3',
        rejectUnauthorized: false
      }
    }
  };

  // Get provider from environment or default to custom
  const provider = process.env.EMAIL_PROVIDER?.toLowerCase() || 'custom';
  
  // Use provider-specific config or custom config
  let config;
  if (providerConfigs[provider]) {
    config = {
      ...providerConfigs[provider],
      auth: {
        user: process.env.EMAIL_USER,
        pass: process.env.EMAIL_PASSWORD
      }
    };
  } else {
    // Custom SMTP configuration
    config = {
      host: process.env.SMTP_HOST,
      port: parseInt(process.env.SMTP_PORT) || 587,
      secure: process.env.SMTP_SECURE === 'true', // true for SSL (port 465), false for STARTTLS (port 587)
      auth: {
        user: process.env.EMAIL_USER,
        pass: process.env.EMAIL_PASSWORD
      }
    };

    // Add custom TLS settings if provided
    if (process.env.SMTP_TLS_CIPHERS || process.env.SMTP_TLS_REJECT_UNAUTHORIZED) {
      config.tls = {};
      if (process.env.SMTP_TLS_CIPHERS) {
        config.tls.ciphers = process.env.SMTP_TLS_CIPHERS;
      }
      if (process.env.SMTP_TLS_REJECT_UNAUTHORIZED) {
        config.tls.rejectUnauthorized = process.env.SMTP_TLS_REJECT_UNAUTHORIZED === 'true';
      }
    }
  }

  return nodemailer.createTransport(config);
}

// Generate HTML email template
function generateEmailTemplate(notificationType, subject, message, processName) {
  const template = emailTemplates[notificationType] || emailTemplates.info;
  
  return `
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>${subject}</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 0; padding: 0; background-color: #f5f5f5; }
        .container { max-width: 600px; margin: 0 auto; background-color: white; }
        .header { background-color: ${template.backgroundColor}; padding: 20px; border-bottom: 3px solid ${template.color}; }
        .header h1 { color: ${template.color}; margin: 0; font-size: 24px; }
        .icon { font-size: 32px; margin-bottom: 10px; }
        .content { padding: 30px; }
        .message { font-size: 16px; line-height: 1.6; color: #333; margin-bottom: 20px; }
        .footer { background-color: #f8f9fa; padding: 20px; text-align: center; font-size: 12px; color: #6c757d; border-top: 1px solid #e9ecef; }
        .process-info { background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0; border-left: 4px solid ${template.color}; }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <div class="icon">${template.icon}</div>
            <h1>${subject}</h1>
        </div>
        <div class="content">
            <div class="message">
                ${message.replace(/\n/g, '<br>')}
            </div>
            ${processName ? `
            <div class="process-info">
                <strong>Process:</strong> ${processName}
            </div>
            ` : ''}
        </div>
        <div class="footer">
            <p>This is an automated notification from the Corrad Process Management System.</p>
            <p>Please do not reply to this email.</p>
        </div>
    </div>
</body>
</html>
  `;
}

// Resolve recipients based on recipient type
async function resolveRecipients(recipientType, recipientData, processVariables) {
  const recipients = [];

  try {
    switch (recipientType) {
      case 'email':
        // Direct email address
        if (recipientData.recipientEmail && isValidEmail(recipientData.recipientEmail)) {
          recipients.push({
            email: recipientData.recipientEmail,
            name: recipientData.recipientEmail
          });
        }
        break;

      case 'user':
        // Look up user from database
        if (recipientData.recipientUser) {
          const user = await prisma.user.findUnique({
            where: { id: recipientData.recipientUser },
            select: { email: true, name: true, firstname: true, lastname: true }
          });
          
          if (user && user.email && isValidEmail(user.email)) {
            const displayName = user.name || `${user.firstname || ''} ${user.lastname || ''}`.trim() || user.email;
            recipients.push({
              email: user.email,
              name: displayName
            });
          }
        }
        break;

      case 'role':
        // Look up users by role
        if (recipientData.recipientRole) {
          const usersWithRole = await prisma.user.findMany({
            where: {
              userrole: {
                some: {
                  roleid: recipientData.recipientRole
                }
              }
            },
            select: { email: true, name: true, firstname: true, lastname: true }
          });

          usersWithRole.forEach(user => {
            if (user.email && isValidEmail(user.email)) {
              const displayName = user.name || `${user.firstname || ''} ${user.lastname || ''}`.trim() || user.email;
              recipients.push({
                email: user.email,
                name: displayName
              });
            }
          });
        }
        break;

      case 'variable':
        // Get recipient from process variable
        if (recipientData.recipientVariable && processVariables[recipientData.recipientVariable]) {
          const variableValue = processVariables[recipientData.recipientVariable];
          
          if (typeof variableValue === 'string' && isValidEmail(variableValue)) {
            recipients.push({
              email: variableValue,
              name: variableValue
            });
          } else if (typeof variableValue === 'object' && variableValue.email && isValidEmail(variableValue.email)) {
            recipients.push({
              email: variableValue.email,
              name: variableValue.name || variableValue.email
            });
          }
        }
        break;

      case 'group':
        // For future implementation - group-based recipients
        console.warn('Group-based recipients not yet implemented');
        break;

      default:
        console.warn(`Unknown recipient type: ${recipientType}`);
    }
  } catch (error) {
    console.error('Error resolving recipients:', error);
  }

  return recipients;
}

// Validate email address
function isValidEmail(email) {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(email);
}

// Substitute variables in text
function substituteVariables(text, variables) {
  if (typeof text !== 'string') return text;
  
  // Replace {{variable}} format
  text = text.replace(/\{\{\s*([a-zA-Z0-9_]+)\s*\}\}/g, (match, varName) => {
    const value = variables[varName];
    if (value === undefined || value === null) return '';
    if (typeof value === 'object') return JSON.stringify(value);
    return String(value);
  });
  
  // Replace {variable} format
  text = text.replace(/\{([a-zA-Z0-9_]+)\}/g, (match, varName) => {
    const value = variables[varName];
    if (value === undefined || value === null) return '';
    if (typeof value === 'object') return JSON.stringify(value);
    return String(value);
  });
  
  return text;
}

export default defineEventHandler(async (event) => {
  try {
    // Only allow POST requests
    if (event.node.req.method !== 'POST') {
      throw createError({
        statusCode: 405,
        statusMessage: 'Method Not Allowed'
      });
    }

    // Parse request body
    const body = await readBody(event);
    const {
      notificationType = 'info',
      recipientType = 'email',
      recipientData = {},
      subject = '',
      message = '',
      processVariables = {},
      processName = '',
      deliveryOptions = { email: true },
      priority = 'medium',
      htmlMessage = '',
      messageFormat = 'text'
    } = body;

    // Validate required fields
    if (!subject && !message) {
      throw createError({
        statusCode: 400,
        statusMessage: 'Subject or message is required'
      });
    }

    // Check if email delivery is enabled
    if (!deliveryOptions.email) {
      return {
        success: true,
        message: 'Email delivery disabled for this notification',
        sent: 0
      };
    }

    // Check environment variables
    if (!process.env.EMAIL_USER || !process.env.EMAIL_PASSWORD) {
      throw createError({
        statusCode: 500,
        statusMessage: 'Email configuration missing. Please set EMAIL_USER and EMAIL_PASSWORD environment variables.'
      });
    }

    // For custom SMTP, also check required SMTP settings
    const provider = process.env.EMAIL_PROVIDER?.toLowerCase() || 'custom';
    if (provider === 'custom' && !process.env.SMTP_HOST) {
      throw createError({
        statusCode: 500,
        statusMessage: 'SMTP configuration missing. Please set SMTP_HOST for custom email provider.'
      });
    }

    // Substitute variables in content
    const processedSubject = substituteVariables(subject, processVariables);
    const processedMessage = substituteVariables(message, processVariables);
    const processedHtmlMessage = htmlMessage ? substituteVariables(htmlMessage, processVariables) : '';

    // Resolve recipients
    const recipients = await resolveRecipients(recipientType, recipientData, processVariables);

    if (recipients.length === 0) {
      throw createError({
        statusCode: 400,
        statusMessage: 'No valid recipients found'
      });
    }

    // Create transporter
    const transporter = createTransporter();

    // Verify connection
    try {
      await transporter.verify();
    } catch (error) {
      console.error('SMTP connection failed:', error);
      throw createError({
        statusCode: 500,
        statusMessage: 'Failed to connect to email server'
      });
    }

    // Prepare email content
    let emailHtml;
    if (messageFormat === 'html' && processedHtmlMessage) {
      emailHtml = processedHtmlMessage;
    } else {
      emailHtml = generateEmailTemplate(notificationType, processedSubject, processedMessage, processName);
    }

    // Send emails
    const results = [];
    let successCount = 0;
    let failureCount = 0;

    for (const recipient of recipients) {
      try {
        const mailOptions = {
          from: {
            name: process.env.EMAIL_FROM_NAME || 'Corrad Process System',
            address: process.env.EMAIL_USER
          },
          to: {
            name: recipient.name,
            address: recipient.email
          },
          subject: processedSubject,
          text: processedMessage,
          html: emailHtml,
          priority: priority === 'high' ? 'high' : priority === 'low' ? 'low' : 'normal'
        };

        const info = await transporter.sendMail(mailOptions);
        
        results.push({
          recipient: recipient.email,
          success: true,
          messageId: info.messageId
        });
        
        successCount++;
        
        console.log(`Email sent successfully to ${recipient.email}:`, info.messageId);
      } catch (error) {
        results.push({
          recipient: recipient.email,
          success: false,
          error: error.message
        });
        
        failureCount++;
        
        console.error(`Failed to send email to ${recipient.email}:`, error.message);
      }
    }

    // Close transporter
    transporter.close();

    // Return results
    return {
      success: successCount > 0,
      message: `Email notification processed. Sent: ${successCount}, Failed: ${failureCount}`,
      sent: successCount,
      failed: failureCount,
      recipients: recipients.length,
      details: results
    };

  } catch (error) {
    console.error('Notification API Error:', error);
    
    // Handle createError objects
    if (error.statusCode) {
      throw error;
    }
    
    // Handle other errors
    throw createError({
      statusCode: 500,
      statusMessage: error.message || 'Failed to send notification'
    });
  }
});