import nodemailer, { type Transporter } from 'nodemailer';
import { env, emailConfigurado } from '@/lib/env';

let _transport: Transporter | null = null;

// Transport perezoso: solo se crea cuando hay SMTP configurado y se va a enviar de verdad.
function getTransport(): Transporter | null {
  if (!emailConfigurado()) return null;
  if (_transport) return _transport;
  const port = Number(env.SMTP_PORT ?? 587);
  _transport = nodemailer.createTransport({
    host: env.SMTP_HOST,
    port,
    secure: port === 465, // 465 = TLS implícito; 587/1025 = STARTTLS/none
    auth: env.SMTP_USER ? { user: env.SMTP_USER, pass: env.SMTP_PASS } : undefined,
  });
  return _transport;
}

function escapeHtml(s: string): string {
  return s.replace(/[&<>"]/g, (c) =>
    c === '&' ? '&amp;' : c === '<' ? '&lt;' : c === '>' ? '&gt;' : '&quot;',
  );
}

const primerNombre = (nombre: string) => nombre.split(' ')[0] || nombre;

// Color de marca del reformista para el acento del email (botón, barra, enlaces).
export type EmailBrand = {
  primary: string;
  primaryDark: string;
  contrast: string;
  logoUrl?: string | null;
};

const BRAND_DEFECTO: EmailBrand = { primary: '#0a0a0a', primaryDark: '#1a1a1a', contrast: '#ffffff' };

type EmailParts = {
  brand: EmailBrand;
  empresa: string;
  preheader: string;
  headline: string;
  parrafosHtml: string[]; // HTML seguro: las variables ya vienen escapadas
  cta?: { url: string; label: string } | null;
  footer: string;
  logoCid?: string | null; // si hay logo, se incrusta como adjunto inline (cid:)
};

type LogoAdjunto = { filename: string; content?: Buffer; path?: string; cid: string; contentType?: string };

const LOGO_CID = 'logoempresa';

// Prepara el logo como adjunto inline (CID) para que se vea en todos los clientes (Gmail bloquea
// las imágenes en data URI directas). Acepta data URI (base64), URL http(s), o ruta /public
// (se vuelve absoluta con APP_URL). Devuelve null si no hay logo usable.
function prepararLogo(logoUrl: string | null | undefined): LogoAdjunto | null {
  if (!logoUrl) return null;
  if (logoUrl.startsWith('data:')) {
    const coma = logoUrl.indexOf(',');
    if (coma === -1) return null;
    const mime = logoUrl.slice(5, coma).split(';')[0] || 'image/png';
    const ext = mime.split('/')[1]?.replace('+xml', '') || 'png';
    const content = Buffer.from(logoUrl.slice(coma + 1), 'base64');
    return { filename: `logo.${ext}`, content, cid: LOGO_CID, contentType: mime };
  }
  if (/^https?:\/\//.test(logoUrl)) return { filename: 'logo', path: logoUrl, cid: LOGO_CID };
  if (logoUrl.startsWith('/') && env.APP_URL) {
    return { filename: 'logo', path: `${env.APP_URL}${logoUrl}`, cid: LOGO_CID };
  }
  return null;
}

const FONT = "-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif";

// Email transaccional: una columna (máx 600px), mobile-first, dark mode, botón bulletproof (tabla),
// estilos inline como base + <style> para dark/responsive. Compatible con Gmail/Apple Mail/Outlook.
function construirEmailHtml(p: EmailParts): string {
  const empresa = escapeHtml(p.empresa);
  const logo = p.logoCid
    ? `<img src="cid:${p.logoCid}" alt="${empresa}" height="40" style="max-height:40px;max-width:200px;display:block;border:0;" />`
    : `<span class="email-logo-name" style="font-size:18px;font-weight:700;color:#1a1a1a;letter-spacing:-0.2px;">${empresa}</span>`;

  const cta = p.cta
    ? `<tr><td style="height:28px;line-height:28px;">&nbsp;</td></tr>
       <tr><td align="center">
         <table role="presentation" cellpadding="0" cellspacing="0" border="0" style="margin:0 auto;">
           <tr><td style="border-radius:10px;background:${p.brand.primary};">
             <a class="btn-a" href="${escapeHtml(p.cta.url)}" target="_blank"
                style="display:inline-block;padding:15px 30px;font-family:${FONT};font-size:16px;font-weight:600;line-height:1;color:${p.brand.contrast};text-decoration:none;border-radius:10px;">
               ${escapeHtml(p.cta.label)}
             </a>
           </td></tr>
         </table>
       </td></tr>`
    : '';

  const parrafos = p.parrafosHtml
    .map(
      (html) =>
        `<tr><td class="email-text" style="font-family:${FONT};font-size:16px;line-height:1.65;color:#3f3f46;padding-bottom:16px;">${html}</td></tr>`,
    )
    .join('');

  return `<!DOCTYPE html>
<html lang="es" style="margin:0;padding:0;">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="color-scheme" content="light dark" />
<meta name="supported-color-schemes" content="light dark" />
<title>${empresa}</title>
<style>
  @media (prefers-color-scheme: dark) {
    .email-body { background:#0b0b0c !important; }
    .email-card { background:#18181b !important; }
    .email-head { background:#18181b !important; }
    .email-title { color:#fafafa !important; }
    .email-text { color:#d4d4d8 !important; }
    .email-muted { color:#a1a1aa !important; }
    .email-rule { border-color:#27272a !important; }
    .email-logo-name { color:#fafafa !important; }
  }
  @media (max-width:600px) {
    .email-card { width:100% !important; border-radius:0 !important; }
    .email-pad { padding-left:24px !important; padding-right:24px !important; }
    .btn-a { display:block !important; padding-left:0 !important; padding-right:0 !important; width:100%; box-sizing:border-box; text-align:center; }
  }
</style>
</head>
<body class="email-body" style="margin:0;padding:0;background:#f4f4f5;">
<div style="display:none;max-height:0;overflow:hidden;opacity:0;color:transparent;">${escapeHtml(p.preheader)}</div>
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0" style="background:#f4f4f5;">
  <tr><td align="center" style="padding:32px 12px;">
    <table role="presentation" class="email-card" width="600" cellpadding="0" cellspacing="0" border="0" style="width:600px;max-width:600px;background:#ffffff;border-radius:14px;overflow:hidden;">
      <tr><td style="height:4px;line-height:4px;background:${p.brand.primary};font-size:0;">&nbsp;</td></tr>
      <tr><td class="email-head email-pad" style="padding:24px 40px 8px 40px;">
        ${logo}
      </td></tr>
      <tr><td class="email-pad" style="padding:8px 40px 0 40px;">
        <h1 class="email-title" style="margin:0 0 18px 0;font-family:${FONT};font-size:26px;line-height:1.25;font-weight:800;color:#18181b;letter-spacing:-0.4px;">${escapeHtml(p.headline)}</h1>
        <table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0">
          ${parrafos}
          ${cta}
        </table>
      </td></tr>
      <tr><td class="email-pad" style="padding:28px 40px 0 40px;">
        <table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0">
          <tr><td class="email-rule" style="border-top:1px solid #e4e4e7;font-size:0;line-height:0;">&nbsp;</td></tr>
        </table>
      </td></tr>
      <tr><td class="email-pad email-muted" style="padding:16px 40px 32px 40px;font-family:${FONT};font-size:13px;line-height:1.5;color:#71717a;">${escapeHtml(p.footer)}</td></tr>
    </table>
  </td></tr>
</table>
</body>
</html>`;
}

function construirEmailText(p: EmailParts): string {
  const lineas = [p.headline, '', ...p.parrafosHtml.map(stripHtml), ''];
  if (p.cta) lineas.push(`${p.cta.label}: ${p.cta.url}`, '');
  lineas.push('—', p.footer);
  return lineas.join('\n');
}

const stripHtml = (html: string) =>
  html
    .replace(/<[^>]+>/g, '')
    .replace(/&amp;/g, '&')
    .replace(/&lt;/g, '<')
    .replace(/&gt;/g, '>')
    .replace(/&quot;/g, '"');

// Email de entrega del presupuesto con el PDF adjunto (COPY-GUIDE §6.b). Best-effort: si no hay
// SMTP configurado o el envío falla devuelve false sin lanzar, para no romper el pipeline.
export async function enviarPresupuestoEmail(opts: {
  to: string;
  nombre: string;
  empresa: string;
  pdf: Buffer;
  filename: string;
  brand?: EmailBrand;
  cta?: { url: string; label: string } | null;
}): Promise<boolean> {
  const transport = getTransport();
  if (!transport) return false;

  const empresaB = `<strong>${escapeHtml(opts.empresa)}</strong>`;
  const logo = prepararLogo(opts.brand?.logoUrl);
  const parts: EmailParts = {
    brand: opts.brand ?? BRAND_DEFECTO,
    empresa: opts.empresa,
    preheader: 'Dentro: el render de cómo quedaría y el desglose por partidas (PDF adjunto).',
    headline: `Aquí está tu presupuesto, ${primerNombre(opts.nombre)}`,
    parrafosHtml: [
      `Hemos preparado el <strong>presupuesto orientativo</strong> de tu reforma. En el PDF adjunto tienes el render de cómo quedaría tu espacio y el desglose por partidas.`,
      `<em>Es una estimación.</em> El precio definitivo lo confirma ${empresaB} en una <strong>visita gratuita</strong> en tu casa, donde lo mide todo al detalle y lo ajusta. Sin compromiso.`,
      `¿Dudas con el render o con alguna partida? Respóndenos y te lo explicamos.`,
    ],
    cta: opts.cta ?? null,
    footer: `Presupuesto orientativo. El precio final puede variar según la visita técnica. · ${opts.empresa}`,
    logoCid: logo ? logo.cid : null,
  };

  const attachments: Array<{
    filename: string;
    content?: Buffer;
    path?: string;
    cid?: string;
    contentType?: string;
  }> = [{ filename: opts.filename, content: opts.pdf, contentType: 'application/pdf' }];
  if (logo) attachments.push(logo);

  try {
    await transport.sendMail({
      from: env.EMAIL_FROM,
      to: opts.to,
      subject: 'Aquí está tu presupuesto de reforma',
      html: construirEmailHtml(parts),
      text: construirEmailText(parts),
      attachments,
    });
    return true;
  } catch (err) {
    console.error('enviarPresupuestoEmail error:', err);
    return false;
  }
}

// Email con el enlace al formulario para subir imágenes (COPY-GUIDE §6.b), usado en el canal
// llamada. Best-effort, mismas garantías que el anterior.
export async function enviarEnlaceFormulario(opts: {
  to: string;
  nombre: string;
  empresa: string;
  url: string;
  brand?: EmailBrand;
}): Promise<boolean> {
  const transport = getTransport();
  if (!transport) return false;

  const empresaB = `<strong>${escapeHtml(opts.empresa)}</strong>`;
  const logo = prepararLogo(opts.brand?.logoUrl);
  const parts: EmailParts = {
    brand: opts.brand ?? BRAND_DEFECTO,
    empresa: opts.empresa,
    preheader: 'Un minuto para subir las fotos de cada zona y seguimos con tu presupuesto.',
    headline: `Enséñanos tu espacio, ${primerNombre(opts.nombre)}`,
    parrafosHtml: [
      `Para preparar tu render y tu presupuesto, ${empresaB} necesita ver cómo está ahora tu espacio.`,
      `Sube unas fotos de cada zona desde el botón de abajo. Tardas un minuto y puedes añadir las que quieras.`,
      `En cuanto las tengamos, seguimos con tu presupuesto.`,
    ],
    cta: { url: encodeURI(opts.url), label: 'Subir mis fotos' },
    footer: opts.empresa,
    logoCid: logo ? logo.cid : null,
  };

  try {
    await transport.sendMail({
      from: env.EMAIL_FROM,
      to: opts.to,
      subject: 'Sube las fotos de tu reforma',
      html: construirEmailHtml(parts),
      text: construirEmailText(parts),
      attachments: logo ? [logo] : undefined,
    });
    return true;
  } catch (err) {
    console.error('enviarEnlaceFormulario error:', err);
    return false;
  }
}

export { construirEmailHtml, construirEmailText };
