import nodemailer from 'nodemailer'
import type { Transporter } from 'nodemailer'
import { prisma } from '@/lib/prisma'

// Cached transporter and config hash to detect changes
let cachedTransporter: Transporter | null = null
let cachedConfigHash = ''
let cachedFrom = ''

/**
 * Get SMTP transporter using database settings with env var fallback.
 * Caches the transporter and rebuilds it when settings change.
 */
async function getTransporter(): Promise<{ transporter: Transporter; from: string }> {
  // Read DB settings
  const dbSettings = await prisma.systemSettings.findMany({
    where: {
      key: { in: ['smtp_host', 'smtp_port', 'smtp_user', 'smtp_password', 'email_from'] },
    },
    select: { key: true, value: true },
  })

  const db: Record<string, string> = {}
  for (const s of dbSettings) {
    db[s.key] = s.value
  }

  // DB settings take priority, env vars as fallback
  const host = db.smtp_host || process.env.SMTP_HOST || 'localhost'
  const port = db.smtp_port || process.env.SMTP_PORT || '587'
  const user = db.smtp_user || process.env.SMTP_USER || ''
  const pass = db.smtp_password || process.env.SMTP_PASS || ''
  const from = db.email_from || process.env.EMAIL_FROM || 'MOPC Platform <noreply@monaco-opc.com>'

  // Check if config changed since last call
  const configHash = `${host}:${port}:${user}:${pass}:${from}`
  if (cachedTransporter && configHash === cachedConfigHash) {
    return { transporter: cachedTransporter, from: cachedFrom }
  }

  // Create new transporter
  cachedTransporter = nodemailer.createTransport({
    host,
    port: parseInt(port),
    secure: port === '465',
    auth: { user, pass },
  })
  cachedConfigHash = configHash
  cachedFrom = from

  return { transporter: cachedTransporter, from: cachedFrom }
}

// Legacy references for backward compat — default sender from env
const defaultFrom = process.env.EMAIL_FROM || 'MOPC Platform <noreply@monaco-opc.com>'

// =============================================================================
// Brand Colors & Logo URLs
// =============================================================================

const BRAND = {
  red: '#de0f1e',
  redHover: '#b91c1c',
  darkBlue: '#053d57',
  teal: '#557f8c',
  white: '#fefefe',
  lightGray: '#f5f5f5',
  textDark: '#1f2937',
  textMuted: '#6b7280',
}

const getSmallLogoUrl = () => 'https://s3.monaco-opc.com/public/MOPC-blue-small.png'
const getBigLogoUrl = () => 'https://s3.monaco-opc.com/public/MOPC-blue-long.png'

// =============================================================================
// Email Template Wrapper & Helpers
// =============================================================================

/**
 * Wrap email content with consistent branding:
 * - Small logo at top of white content box
 * - Big logo in dark blue footer
 */
function getEmailWrapper(content: string): string {
  return `
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>MOPC</title>
  <!--[if mso]>
  <noscript>
    <xml>
      <o:OfficeDocumentSettings>
        <o:PixelsPerInch>96</o:PixelsPerInch>
      </o:OfficeDocumentSettings>
    </xml>
  </noscript>
  <![endif]-->
</head>
<body style="margin: 0; padding: 0; background-color: ${BRAND.darkBlue}; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased;">
  <table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0" style="background-image: url('https://s3.monaco-opc.com/public/ocean.png'); background-size: cover; background-position: center top; background-repeat: no-repeat; background-color: ${BRAND.darkBlue};">
    <tr>
      <td align="center" style="padding: 40px 20px;">
        <!-- Main Container -->
        <table role="presentation" width="600" cellspacing="0" cellpadding="0" border="0" style="max-width: 600px; width: 100%;">

          <!-- Content Box -->
          <tr>
            <td style="background-color: ${BRAND.white}; border-radius: 12px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);">
              <table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0">
                <!-- Small Logo Header -->
                <tr>
                  <td align="center" style="padding: 32px 40px 24px 40px;">
                    <img src="${getSmallLogoUrl()}" alt="MOPC" width="100" height="auto" style="display: block; border: 0; max-width: 100px;">
                  </td>
                </tr>
                <!-- Email Content -->
                <tr>
                  <td style="padding: 0 40px 32px 40px;">
                    ${content}
                  </td>
                </tr>
                <!-- Footer -->
                <tr>
                  <td style="padding: 0 40px 32px 40px; border-top: 1px solid #e5e7eb;">
                    <table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0">
                      <tr>
                        <td align="center" style="padding-top: 24px;">
                          <img src="${getBigLogoUrl()}" alt="Monaco Ocean Protection Challenge" width="180" height="auto" style="display: block; border: 0; max-width: 180px; margin-bottom: 12px;">
                        </td>
                      </tr>
                      <tr>
                        <td align="center">
                          <p style="color: ${BRAND.textMuted}; font-size: 13px; margin: 0; line-height: 1.5;">
                            Together for a healthier ocean
                          </p>
                          <p style="color: ${BRAND.textMuted}; font-size: 12px; margin: 8px 0 0 0;">
                            &copy; ${new Date().getFullYear()} Monaco Ocean Protection Challenge
                          </p>
                        </td>
                      </tr>
                    </table>
                  </td>
                </tr>
              </table>
            </td>
          </tr>

        </table>
      </td>
    </tr>
  </table>
</body>
</html>
`
}

/**
 * Generate a styled CTA button
 */
function ctaButton(url: string, text: string): string {
  return `
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0" style="margin: 24px 0;">
  <tr>
    <td align="center">
      <a href="${url}" target="_blank" style="display: inline-block; background-color: ${BRAND.red}; color: #ffffff; text-decoration: none; padding: 16px 40px; border-radius: 8px; font-weight: 600; font-size: 16px; mso-padding-alt: 0;">
        <!--[if mso]>
        <i style="letter-spacing: 40px; mso-font-width: -100%; mso-text-raise: 30pt;">&nbsp;</i>
        <![endif]-->
        <span style="mso-text-raise: 15pt;">${text}</span>
        <!--[if mso]>
        <i style="letter-spacing: 40px; mso-font-width: -100%;">&nbsp;</i>
        <![endif]-->
      </a>
    </td>
  </tr>
</table>
`
}

/**
 * Generate styled section title
 */
function sectionTitle(text: string): string {
  return `<h2 style="color: ${BRAND.darkBlue}; margin: 0 0 16px 0; font-size: 22px; font-weight: 600; line-height: 1.3;">${text}</h2>`
}

/**
 * Generate styled paragraph
 */
function paragraph(text: string): string {
  return `<p style="color: ${BRAND.textDark}; margin: 0 0 16px 0; font-size: 15px; line-height: 1.6;">${text}</p>`
}

/**
 * Generate styled info box
 */
function infoBox(content: string, variant: 'warning' | 'info' | 'success' = 'info'): string {
  const colors = {
    warning: { bg: '#fef3c7', border: '#f59e0b', text: '#92400e' },
    info: { bg: '#e0f2fe', border: '#0ea5e9', text: '#0369a1' },
    success: { bg: '#dcfce7', border: '#22c55e', text: '#166534' },
  }
  const c = colors[variant]
  return `
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0" style="margin: 20px 0;">
  <tr>
    <td style="background-color: ${c.bg}; border-left: 4px solid ${c.border}; border-radius: 0 8px 8px 0; padding: 16px 20px;">
      <p style="color: ${c.text}; margin: 0; font-size: 14px; font-weight: 500;">${content}</p>
    </td>
  </tr>
</table>
`
}

/**
 * Generate styled stat card
 */
function statCard(label: string, value: string | number): string {
  return `
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0" style="margin: 20px 0;">
  <tr>
    <td style="background-color: ${BRAND.lightGray}; border-radius: 12px; padding: 24px; text-align: center;">
      <p style="color: ${BRAND.textMuted}; margin: 0 0 8px 0; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 1px;">${label}</p>
      <p style="color: ${BRAND.darkBlue}; margin: 0; font-size: 42px; font-weight: 700; line-height: 1;">${value}</p>
    </td>
  </tr>
</table>
`
}

// =============================================================================
// Email Templates
// =============================================================================

interface EmailTemplate {
  subject: string
  html: string
  text: string
}

/**
 * Generate magic link email template
 */
function getMagicLinkTemplate(url: string, expiryMinutes: number = 15): EmailTemplate {
  const content = `
    ${sectionTitle('Sign in to your account')}
    ${paragraph('Click the button below to securely sign in to the MOPC Platform.')}
    ${infoBox(`<strong>This link expires in ${expiryMinutes} minutes</strong>`, 'warning')}
    ${ctaButton(url, 'Sign In to MOPC')}
    <p style="color: ${BRAND.textMuted}; margin: 24px 0 0 0; font-size: 13px; text-align: center;">
      If you didn't request this email, you can safely ignore it.
    </p>
  `

  return {
    subject: 'Sign in to MOPC Platform',
    html: getEmailWrapper(content),
    text: `
Sign in to MOPC Platform
=========================

Click the link below to sign in to your account:

${url}

This link will expire in ${expiryMinutes} minutes.

If you didn't request this email, you can safely ignore it.

---
Monaco Ocean Protection Challenge
Together for a healthier ocean.
    `,
  }
}

/**
 * Generate generic invitation email template (not round-specific)
 */
function getGenericInvitationTemplate(
  name: string,
  url: string,
  role: string
): EmailTemplate {
  const roleLabel = role === 'JURY_MEMBER' ? 'jury member' : role.toLowerCase().replace('_', ' ')
  const greeting = name ? `Hello ${name},` : 'Hello,'

  const content = `
    ${sectionTitle(greeting)}
    ${paragraph(`You've been invited to join the Monaco Ocean Protection Challenge platform as a <strong>${roleLabel}</strong>.`)}
    ${paragraph('Click the button below to set up your account and get started.')}
    ${ctaButton(url, 'Accept Invitation')}
    ${infoBox('This link will expire in 7 days.', 'info')}
  `

  return {
    subject: "You're invited to join the MOPC Platform",
    html: getEmailWrapper(content),
    text: `
${greeting}

You've been invited to join the Monaco Ocean Protection Challenge platform as a ${roleLabel}.

Click the link below to set up your account and get started:

${url}

This link will expire in 7 days.

---
Monaco Ocean Protection Challenge
Together for a healthier ocean.
    `,
  }
}

/**
 * Generate evaluation reminder email template
 */
function getEvaluationReminderTemplate(
  name: string,
  pendingCount: number,
  roundName: string,
  deadline: string,
  assignmentsUrl: string
): EmailTemplate {
  const greeting = name ? `Hello ${name},` : 'Hello,'

  // Deadline alert box (styled differently from info box)
  const deadlineBox = `
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0" style="margin: 20px 0;">
  <tr>
    <td style="background-color: #fef2f2; border-left: 4px solid ${BRAND.red}; border-radius: 0 8px 8px 0; padding: 16px 20px;">
      <p style="color: #991b1b; margin: 0 0 4px 0; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 1px;">Deadline</p>
      <p style="color: #7f1d1d; margin: 0; font-size: 16px; font-weight: 700;">${deadline}</p>
    </td>
  </tr>
</table>
`

  const content = `
    ${sectionTitle(greeting)}
    ${paragraph(`This is a friendly reminder about your pending evaluations for <strong style="color: ${BRAND.darkBlue};">${roundName}</strong>.`)}
    ${statCard('Pending Evaluations', pendingCount)}
    ${deadlineBox}
    ${paragraph('Your expert evaluation helps identify the most promising ocean conservation projects. Please complete your reviews before the deadline.')}
    ${ctaButton(assignmentsUrl, 'View My Assignments')}
  `

  return {
    subject: `Reminder: ${pendingCount} evaluation${pendingCount !== 1 ? 's' : ''} awaiting your review`,
    html: getEmailWrapper(content),
    text: `
${greeting}

This is a friendly reminder that you have ${pendingCount} pending evaluation${pendingCount !== 1 ? 's' : ''} for ${roundName}.

Deadline: ${deadline}

Please complete your evaluations before the deadline to ensure your feedback is included in the selection process.

View your assignments: ${assignmentsUrl}

---
Monaco Ocean Protection Challenge
Together for a healthier ocean.
    `,
  }
}

/**
 * Generate announcement email template
 */
function getAnnouncementTemplate(
  name: string,
  title: string,
  message: string,
  ctaText?: string,
  ctaUrl?: string
): EmailTemplate {
  const greeting = name ? `Hello ${name},` : 'Hello,'
  const ctaTextPlain = ctaText && ctaUrl ? `\n${ctaText}: ${ctaUrl}\n` : ''

  // Escape HTML in message but preserve line breaks
  const formattedMessage = message
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/\n/g, '<br>')

  // Title card with success styling
  const titleCard = `
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0" style="margin: 20px 0;">
  <tr>
    <td style="background-color: #ecfdf5; border-left: 4px solid #059669; border-radius: 0 12px 12px 0; padding: 20px 24px;">
      <h3 style="color: #065f46; margin: 0; font-size: 18px; font-weight: 700;">${title}</h3>
    </td>
  </tr>
</table>
`

  const content = `
    ${sectionTitle(greeting)}
    ${titleCard}
    <div style="color: ${BRAND.textDark}; font-size: 15px; line-height: 1.7; margin: 20px 0;">
      ${formattedMessage}
    </div>
    ${ctaText && ctaUrl ? ctaButton(ctaUrl, ctaText) : ''}
  `

  return {
    subject: title,
    html: getEmailWrapper(content),
    text: `
${greeting}

${title}

${message}
${ctaTextPlain}
---
Monaco Ocean Protection Challenge
Together for a healthier ocean.
    `,
  }
}

/**
 * Generate jury invitation email template
 */
function getJuryInvitationTemplate(
  name: string,
  url: string,
  roundName: string
): EmailTemplate {
  const greeting = name ? `Hello ${name},` : 'Hello,'

  const content = `
    ${sectionTitle(greeting)}
    ${paragraph(`You've been invited to serve as a jury member for <strong style="color: ${BRAND.darkBlue};">${roundName}</strong>.`)}
    ${paragraph('As a jury member, you\'ll evaluate innovative ocean protection projects and help select the most promising initiatives.')}
    ${ctaButton(url, 'Accept Invitation')}
    <p style="color: ${BRAND.textMuted}; margin: 20px 0 0 0; font-size: 13px; text-align: center;">
      This link will allow you to access the platform and view your assigned projects.
    </p>
  `

  return {
    subject: `You're invited to evaluate projects for ${roundName}`,
    html: getEmailWrapper(content),
    text: `
${greeting}

You've been invited to serve as a jury member for ${roundName}.

As a jury member, you'll evaluate innovative ocean protection projects and help select the most promising initiatives.

Click the link below to accept your invitation:

${url}

---
Monaco Ocean Protection Challenge
Together for a healthier ocean.
    `,
  }
}

// =============================================================================
// Email Sending Functions
// =============================================================================

/**
 * Send magic link email for authentication
 */
export async function sendMagicLinkEmail(
  email: string,
  url: string
): Promise<void> {
  const expiryMinutes = parseInt(process.env.MAGIC_LINK_EXPIRY || '900') / 60
  const template = getMagicLinkTemplate(url, expiryMinutes)
  const { transporter, from } = await getTransporter()

  await transporter.sendMail({
    from,
    to: email,
    subject: template.subject,
    text: template.text,
    html: template.html,
  })
}

/**
 * Send generic invitation email (not round-specific)
 */
export async function sendInvitationEmail(
  email: string,
  name: string | null,
  url: string,
  role: string
): Promise<void> {
  const template = getGenericInvitationTemplate(name || '', url, role)
  const { transporter, from } = await getTransporter()

  await transporter.sendMail({
    from,
    to: email,
    subject: template.subject,
    text: template.text,
    html: template.html,
  })
}

/**
 * Send jury invitation email (round-specific)
 */
export async function sendJuryInvitationEmail(
  email: string,
  name: string | null,
  url: string,
  roundName: string
): Promise<void> {
  const template = getJuryInvitationTemplate(name || '', url, roundName)
  const { transporter, from } = await getTransporter()

  await transporter.sendMail({
    from,
    to: email,
    subject: template.subject,
    text: template.text,
    html: template.html,
  })
}

/**
 * Send evaluation reminder email
 */
export async function sendEvaluationReminderEmail(
  email: string,
  name: string | null,
  pendingCount: number,
  roundName: string,
  deadline: string,
  assignmentsUrl: string
): Promise<void> {
  const template = getEvaluationReminderTemplate(
    name || '',
    pendingCount,
    roundName,
    deadline,
    assignmentsUrl
  )
  const { transporter, from } = await getTransporter()

  await transporter.sendMail({
    from,
    to: email,
    subject: template.subject,
    text: template.text,
    html: template.html,
  })
}

/**
 * Send announcement email
 */
export async function sendAnnouncementEmail(
  email: string,
  name: string | null,
  title: string,
  message: string,
  ctaText?: string,
  ctaUrl?: string
): Promise<void> {
  const template = getAnnouncementTemplate(
    name || '',
    title,
    message,
    ctaText,
    ctaUrl
  )
  const { transporter, from } = await getTransporter()

  await transporter.sendMail({
    from,
    to: email,
    subject: template.subject,
    text: template.text,
    html: template.html,
  })
}

/**
 * Send a test email to verify SMTP configuration
 */
export async function sendTestEmail(toEmail: string): Promise<boolean> {
  try {
    const content = `
      ${sectionTitle('Test Email')}
      ${paragraph('This is a test email from the MOPC Platform.')}
      ${infoBox('If you received this, your email configuration is working correctly!', 'success')}
      <p style="color: ${BRAND.textMuted}; margin: 20px 0 0 0; font-size: 13px; text-align: center;">
        Sent at ${new Date().toISOString()}
      </p>
    `
    const { transporter, from } = await getTransporter()

    await transporter.sendMail({
      from,
      to: toEmail,
      subject: 'MOPC Platform - Test Email',
      text: 'This is a test email from the MOPC Platform. If you received this, your email configuration is working correctly.',
      html: getEmailWrapper(content),
    })
    return true
  } catch {
    return false
  }
}

/**
 * Verify SMTP connection
 */
export async function verifyEmailConnection(): Promise<boolean> {
  try {
    const { transporter } = await getTransporter()
    await transporter.verify()
    return true
  } catch {
    return false
  }
}
