import crypto from "node:crypto";
import path from "node:path";
import process from "node:process";
import { fileURLToPath } from "node:url";

import dotenv from "dotenv";
import express from "express";
import { cert, getApps, initializeApp } from "firebase-admin/app";
import { FieldValue, getFirestore } from "firebase-admin/firestore";

dotenv.config();

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const ROOT_DIR = path.resolve(__dirname, "..");
const PUBLIC_DIR = path.join(ROOT_DIR, "public");

const PUERTO = Number(process.env.PUERTO || 3000);
const ORIGENES_PERMITIDOS = (process.env.ORIGENES_PERMITIDOS || "")
  .split(",")
  .map((valor) => valor.trim())
  .filter(Boolean);

const ESCENARIOS = {
  escenario_1: {
    codigo: "escenario_1",
    nombre: "Tienda Impulso",
    subtitulo: "0-150 envíos mensuales",
  },
  escenario_2: {
    codigo: "escenario_2",
    nombre: "Tienda Escala",
    subtitulo: "150-300 envíos mensuales",
  },
  escenario_3: {
    codigo: "escenario_3",
    nombre: "Enterprise",
    subtitulo: "300 o más envíos mensuales",
  },
};

const almacenamientoTemporal = {
  leads: new Map(),
  accesos: new Map(),
  eventos: [],
};

let dbCache = null;
let modoTemporalNotificado = false;

const app = express();

app.disable("x-powered-by");
app.use(express.json({ limit: "1mb" }));
app.use(configurarCors);
app.use(
  express.static(PUBLIC_DIR, {
    extensions: ["html"],
  })
);

app.get("/", (_req, res) => {
  res.sendFile(path.join(PUBLIC_DIR, "index.html"));
});

app.get(["/index.html", "/camp.html"], (req, res) => {
  const fileName = req.path === "/camp.html" ? "camp.html" : "index.html";
  res.sendFile(path.join(PUBLIC_DIR, fileName));
});

app.get(["/variante-a", "/variante-a/", "/variante-b", "/variante-b/", "/registro", "/registro/"], (_req, res) => {
  res.redirect(301, "/");
});

app.post("/api/leads", async (req, res) => {
  try {
    const leadNormalizado = normalizarLeadEntrada(req.body);
    const errores = validarLead(leadNormalizado);

    if (errores.length > 0) {
      return res.status(400).json({
        ok: false,
        errores,
      });
    }

    const escenario = obtenerEscenarioPorVolumen(
      leadNormalizado.operacion_logistica.volumen_envios_mensuales
    );
    const token = generarTokenContinuacion();
    const urlContinuacion = construirUrlContinuacion(req, token);
    const configuracionEscenario = crearConfiguracionEscenario(escenario.codigo);
    const leadGuardado = await guardarLead({
      lead: leadNormalizado,
      escenario,
      token,
      urlContinuacion,
      configuracionEscenario,
    });

    let estadoCorreo = {
      enviado: false,
      razon: null,
    };

    try {
      estadoCorreo = await enviarCorreoSeguimiento({
        lead: leadNormalizado,
        escenario,
        token,
        urlContinuacion,
        idLead: leadGuardado.idLead,
        configuracionEscenario,
      });
    } catch (error) {
      console.error("Error al enviar el correo de seguimiento:", error);
      estadoCorreo = {
        enviado: false,
        razon: error.message,
      };
    }

    return res.status(201).json({
      ok: true,
      id_lead: leadGuardado.idLead,
      token_continuacion: token,
      url_continuacion: urlContinuacion,
      escenario_codigo: escenario.codigo,
      escenario_nombre: escenario.nombre,
      escenario_subtitulo: escenario.subtitulo,
      configuracion_escenario: configuracionEscenario,
      correo_enviado: estadoCorreo.enviado,
      correo_razon: estadoCorreo.razon,
    });
  } catch (error) {
    console.error("Error al crear el lead:", error);
    return res.status(500).json({
      ok: false,
      error: "No fue posible procesar el lead.",
    });
  }
});

app.get("/api/escenario/:token", async (req, res) => {
  try {
    const resultado = await obtenerLeadPorToken(req.params.token);

    if (!resultado) {
      return res.status(404).json({
        ok: false,
        error: "No encontramos una continuidad válida para este lead.",
      });
    }

    const { idLead, lead, escenario } = resultado;
    return res.json({
      ok: true,
      id_lead: idLead,
      escenario_codigo: escenario.codigo,
      escenario_nombre: escenario.nombre,
      escenario_subtitulo: escenario.subtitulo,
      configuracion_escenario: resultado.configuracionEscenario,
      datos: convertirLeadAFormatoCliente(lead),
    });
  } catch (error) {
    console.error("Error al resolver el escenario:", error);
    return res.status(500).json({
      ok: false,
      error: "No fue posible cargar el escenario solicitado.",
    });
  }
});

app.get("/continuar/:token", (req, res) => {
  res.redirect(construirUrlContinuacion(req, req.params.token));
});

app.post("/api/eventos/:escenarioCodigo", async (req, res) => {
  try {
    await registrarEventoEscenario(req.params.escenarioCodigo, req.body || {});
    return res.status(204).end();
  } catch (error) {
    console.error("Error al registrar evento de escenario:", error);
    return res.status(500).json({
      ok: false,
      error: "No fue posible registrar el evento.",
    });
  }
});

app.listen(PUERTO, () => {
  console.log(`API disponible en http://localhost:${PUERTO}`);
});

function configurarCors(req, res, next) {
  const origin = req.headers.origin;

  if (origin) {
    const permitirTodo = ORIGENES_PERMITIDOS.length === 0 || ORIGENES_PERMITIDOS.includes("*");
    const originPermitido = permitirTodo || ORIGENES_PERMITIDOS.includes(origin);

    if (originPermitido) {
      res.setHeader("Access-Control-Allow-Origin", permitirTodo ? origin : origin);
      res.setHeader("Vary", "Origin");
    }
  }

  res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");

  if (req.method === "OPTIONS") {
    return res.status(204).end();
  }

  return next();
}

function normalizarTexto(valor) {
  return typeof valor === "string" ? valor.trim() : "";
}

function normalizarTextoOpcional(valor) {
  const texto = normalizarTexto(valor);
  return texto || null;
}

function normalizarArreglo(valor) {
  if (!Array.isArray(valor)) {
    return [];
  }

  return valor.map((item) => normalizarTexto(item)).filter(Boolean);
}

function normalizarLeadEntrada(payload = {}) {
  const negocio = payload.negocio || {};
  const contacto = payload.contacto || {};
  const operacion = payload.operacion_logistica || {};
  const sitioWeb = operacion.sitio_web || {};
  const canales = normalizarArreglo(operacion.canales_de_venta);
  const usaSitioWeb = Boolean(sitioWeb.usa_sitio_web) || canales.includes("Sitio web / tienda online");

  return {
    negocio: {
      nombre_negocio: normalizarTexto(negocio.nombre_negocio),
      instagram: normalizarTextoOpcional(negocio.instagram),
    },
    contacto: {
      nombre: normalizarTexto(contacto.nombre),
      telefono: normalizarTexto(contacto.telefono),
      correo: normalizarTexto(contacto.correo).toLowerCase(),
    },
    operacion_logistica: {
      tipo_productos: normalizarTexto(operacion.tipo_productos),
      volumen_envios_mensuales: normalizarTexto(operacion.volumen_envios_mensuales),
      origen_despacho: normalizarTexto(operacion.origen_despacho),
      canales_de_venta: canales,
      sitio_web: {
        usa_sitio_web: usaSitioWeb,
        tecnologia: usaSitioWeb ? normalizarTextoOpcional(sitioWeb.tecnologia) : null,
        interes_integracion: usaSitioWeb ? normalizarTextoOpcional(sitioWeb.interes_integracion) : null,
      },
      problema_principal: normalizarTexto(operacion.problema_principal),
    },
  };
}

function validarLead(lead) {
  const errores = [];

  if (!lead.negocio.nombre_negocio) {
    errores.push("nombre_negocio es obligatorio.");
  }

  if (!lead.contacto.nombre) {
    errores.push("contacto.nombre es obligatorio.");
  }

  if (!lead.contacto.telefono) {
    errores.push("contacto.telefono es obligatorio.");
  }

  if (!lead.contacto.correo || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(lead.contacto.correo)) {
    errores.push("contacto.correo debe ser un email válido.");
  }

  if (!lead.operacion_logistica.tipo_productos) {
    errores.push("operacion_logistica.tipo_productos es obligatorio.");
  }

  if (!lead.operacion_logistica.volumen_envios_mensuales) {
    errores.push("operacion_logistica.volumen_envios_mensuales es obligatorio.");
  }

  if (!lead.operacion_logistica.origen_despacho) {
    errores.push("operacion_logistica.origen_despacho es obligatorio.");
  }

  if (lead.operacion_logistica.canales_de_venta.length === 0) {
    errores.push("operacion_logistica.canales_de_venta debe tener al menos un valor.");
  }

  if (!lead.operacion_logistica.problema_principal) {
    errores.push("operacion_logistica.problema_principal es obligatorio.");
  }

  if (
    lead.operacion_logistica.sitio_web.usa_sitio_web &&
    !lead.operacion_logistica.sitio_web.tecnologia
  ) {
    errores.push("operacion_logistica.sitio_web.tecnologia es obligatoria cuando usa_sitio_web es true.");
  }

  if (
    lead.operacion_logistica.sitio_web.usa_sitio_web &&
    !lead.operacion_logistica.sitio_web.interes_integracion
  ) {
    errores.push(
      "operacion_logistica.sitio_web.interes_integracion es obligatorio cuando usa_sitio_web es true."
    );
  }

  return errores;
}

function obtenerEscenarioPorVolumen(volumen) {
  const valor = normalizarTexto(volumen).toLowerCase();

  if (valor.startsWith("0-50")) {
    return ESCENARIOS.escenario_1;
  }

  if (valor.startsWith("50-150")) {
    return ESCENARIOS.escenario_1;
  }

  if (valor.startsWith("150-300")) {
    return ESCENARIOS.escenario_2;
  }

  if (valor.startsWith("300-800")) {
    return ESCENARIOS.escenario_3;
  }

  if (valor.startsWith("800")) {
    return ESCENARIOS.escenario_3;
  }

  return ESCENARIOS.escenario_2;
}

function obtenerConfiguracionEscenarioBase(codigo) {
  if (codigo === "escenario_1") {
    const duracionOfertaMinutos = leerEnteroPositivo(process.env.IMPULSO_OFERTA_MINUTOS, 20);
    return {
      tipo_tienda: "Tienda Impulso",
      url_video: normalizarTexto(process.env.URL_VIDEO_ESCENARIO_1),
      url_registro_oferta:
        normalizarTexto(process.env.URL_REGISTRO_OFERTA_ESCENARIO_1) ||
        normalizarTexto(process.env.URL_COMENZAR_ESCENARIO_1),
      url_registro_base: normalizarTexto(process.env.URL_REGISTRO_BASE_ESCENARIO_1),
      texto_oferta:
        "Registrate ahora y obten un 20% de dcto en tus envios el primer mes.",
      duracion_oferta_minutos: duracionOfertaMinutos,
    };
  }

  if (codigo === "escenario_2") {
    return {
      tipo_tienda: "Tienda Escala",
      url_video: normalizarTexto(process.env.URL_VIDEO_ESCENARIO_2),
      telefono_whatsapp: normalizarTexto(process.env.TELEFONO_WHATSAPP_ESCENARIO_2) || "56941121090",
    };
  }

  const videosEnterprise = [
    normalizarTexto(process.env.URL_VIDEO_ESCENARIO_3_A),
    normalizarTexto(process.env.URL_VIDEO_ESCENARIO_3_B),
    normalizarTexto(process.env.URL_VIDEO_ESCENARIO_3),
  ].filter(Boolean);

  return {
    tipo_tienda: "Enterprise",
    url_video: "",
    opciones_video: videosEnterprise,
    url_calendly: normalizarTexto(process.env.URL_CALENDLY_ESCENARIO_3),
  };
}

function crearConfiguracionEscenario(codigo) {
  const base = obtenerConfiguracionEscenarioBase(codigo);

  if (codigo === "escenario_1") {
    const minutosOferta = leerEnteroPositivo(base.duracion_oferta_minutos, 20);
    return {
      ...base,
      duracion_oferta_minutos: minutosOferta,
      oferta_activa_hasta: new Date(Date.now() + minutosOferta * 60 * 1000).toISOString(),
    };
  }

  if (codigo === "escenario_3") {
    const opciones = Array.isArray(base.opciones_video) ? base.opciones_video.filter(Boolean) : [];
    const urlVideo = opciones.length > 0 ? elegirAleatorio(opciones) : "";
    const { opciones_video: _opcionesVideo, ...baseSinOpciones } = base;

    return {
      ...baseSinOpciones,
      url_video: urlVideo,
    };
  }

  return base;
}

function leerEnteroPositivo(valor, fallback) {
  const numero = Number.parseInt(valor, 10);
  return Number.isFinite(numero) && numero > 0 ? numero : fallback;
}

function elegirAleatorio(valores) {
  return valores[Math.floor(Math.random() * valores.length)];
}

function generarTokenContinuacion() {
  return crypto.randomBytes(24).toString("hex");
}

function construirUrlBaseWeb(req) {
  const urlBaseConfigurada = normalizarTexto(process.env.URL_PUBLICA_WEB);
  if (urlBaseConfigurada) {
    return new URL(urlBaseConfigurada).toString();
  }

  return `${req.protocol}://${req.get("host")}/`;
}

function construirUrlContinuacion(req, token) {
  const url = new URL(construirUrlBaseWeb(req));
  url.searchParams.set("token", token);
  return url.toString();
}

function convertirLeadAFormatoCliente(lead) {
  return {
    businessName: lead.negocio.nombre_negocio,
    instagram: lead.negocio.instagram || "",
    contactName: lead.contacto.nombre,
    phone: lead.contacto.telefono,
    email: lead.contacto.correo,
    productType: lead.operacion_logistica.tipo_productos,
    volume: lead.operacion_logistica.volumen_envios_mensuales,
    origin: lead.operacion_logistica.origen_despacho,
    channels: lead.operacion_logistica.canales_de_venta,
    websitePlatform: lead.operacion_logistica.sitio_web.tecnologia || "",
    integrationInterest: lead.operacion_logistica.sitio_web.interes_integracion || "",
    problem: lead.operacion_logistica.problema_principal,
  };
}

function obtenerConfiguracionFirebaseAdmin() {
  const projectId = normalizarTexto(process.env.FIREBASE_PROJECT_ID);
  const clientEmail = normalizarTexto(process.env.FIREBASE_CLIENT_EMAIL);
  const privateKey = normalizarTexto(process.env.FIREBASE_PRIVATE_KEY).replace(/\\n/g, "\n");

  if (projectId && clientEmail && privateKey) {
    return {
      projectId,
      clientEmail,
      privateKey,
    };
  }

  if (projectId) {
    return { projectId };
  }

  return null;
}

function obtenerDb() {
  if (dbCache) {
    return dbCache;
  }

  const configuracionFirebase = obtenerConfiguracionFirebaseAdmin();
  if (!configuracionFirebase) {
    informarModoTemporal();
    return null;
  }

  if (getApps().length === 0) {
    if (configuracionFirebase.clientEmail && configuracionFirebase.privateKey) {
      initializeApp({
        credential: cert(configuracionFirebase),
        projectId: configuracionFirebase.projectId,
      });
    } else {
      initializeApp({
        projectId: configuracionFirebase.projectId,
      });
    }
  }

  dbCache = getFirestore();
  return dbCache;
}

function informarModoTemporal() {
  if (modoTemporalNotificado) {
    return;
  }

  modoTemporalNotificado = true;
  console.warn(
    "Firebase Admin no está configurado. El flujo usará almacenamiento temporal en memoria hasta que definas las credenciales."
  );
}

async function guardarLead({ lead, escenario, token, urlContinuacion, configuracionEscenario }) {
  const db = obtenerDb();

  if (!db) {
    const idLead = crypto.randomUUID();
    almacenamientoTemporal.leads.set(idLead, {
      idLead,
      lead,
      escenario_codigo: escenario.codigo,
      fechaCreacion: new Date().toISOString(),
    });
    almacenamientoTemporal.accesos.set(token, {
      token,
      idLead,
      escenario_codigo: escenario.codigo,
      urlContinuacion,
      configuracion_escenario: configuracionEscenario,
      fechaCreacion: new Date().toISOString(),
    });

    return { idLead };
  }

  const leadRef = db.collection("Leads").doc();
  await leadRef.set({
    escenario_codigo: escenario.codigo,
    ...lead,
    metadatos: {
      estado: "nuevo",
      fechaCreacion: FieldValue.serverTimestamp(),
    },
  });

  await db.collection("AccesosEscenario").doc(token).set({
    token,
    id_lead: leadRef.id,
    escenario_codigo: escenario.codigo,
    url_continuacion: urlContinuacion,
    configuracion_escenario: configuracionEscenario,
    fechaCreacion: FieldValue.serverTimestamp(),
  });

  return { idLead: leadRef.id };
}

async function obtenerLeadPorToken(token) {
  const tokenNormalizado = normalizarTexto(token);
  if (!tokenNormalizado) {
    return null;
  }

  const db = obtenerDb();

  if (!db) {
    const acceso = almacenamientoTemporal.accesos.get(tokenNormalizado);
    if (!acceso) {
      return null;
    }

    const leadMemoria = almacenamientoTemporal.leads.get(acceso.idLead);
    if (!leadMemoria) {
      return null;
    }

    return {
      idLead: leadMemoria.idLead,
      lead: leadMemoria.lead,
      escenario: ESCENARIOS[acceso.escenario_codigo] || ESCENARIOS.escenario_2,
      configuracionEscenario:
        acceso.configuracion_escenario || crearConfiguracionEscenario(acceso.escenario_codigo),
    };
  }

  const accesoSnap = await db.collection("AccesosEscenario").doc(tokenNormalizado).get();
  if (!accesoSnap.exists) {
    return null;
  }

  const acceso = accesoSnap.data();
  const leadSnap = await db.collection("Leads").doc(acceso.id_lead).get();
  if (!leadSnap.exists) {
    return null;
  }

  return {
    idLead: leadSnap.id,
    lead: leadSnap.data(),
    escenario: ESCENARIOS[acceso.escenario_codigo] || ESCENARIOS.escenario_2,
    configuracionEscenario:
      acceso.configuracion_escenario || crearConfiguracionEscenario(acceso.escenario_codigo),
  };
}

async function registrarEventoEscenario(escenarioCodigo, payload) {
  const evento = {
    escenario_codigo: normalizarTexto(escenarioCodigo),
    id_lead: normalizarTexto(payload.id_lead) || null,
    accion: normalizarTexto(payload.accion) || null,
    evento: normalizarTexto(payload.evento) || null,
    detalle: payload,
    fechaCreacion: new Date().toISOString(),
  };

  const db = obtenerDb();
  if (!db) {
    almacenamientoTemporal.eventos.push(evento);
    return;
  }

  await db.collection("EventosLead").add({
    ...evento,
    fechaCreacion: FieldValue.serverTimestamp(),
  });
}

async function enviarCorreoSeguimiento({
  lead,
  escenario,
  token,
  urlContinuacion,
  idLead,
  configuracionEscenario,
}) {
  const resendApiKey = normalizarTexto(process.env.RESEND_API_KEY);
  const emailRemitente = normalizarTexto(process.env.EMAIL_REMITENTE);

  if (!resendApiKey || !emailRemitente) {
    console.log(
      JSON.stringify(
        {
          tipo: "correo_pendiente_configuracion",
          id_lead: idLead,
          token,
          escenario_codigo: escenario.codigo,
          correo_destino: lead.contacto.correo,
          url_continuacion: urlContinuacion,
        },
        null,
        2
      )
    );
    return {
      enviado: false,
      razon: "configuracion_correo_incompleta",
    };
  }

  const nombreRemitente = normalizarTexto(process.env.NOMBRE_REMITENTE) || "Altyro Envios";
  const replyTo = normalizarTexto(process.env.EMAIL_REPLY_TO);

  const payloadCorreo = {
    from: `${nombreRemitente} <${emailRemitente}>`,
    to: [lead.contacto.correo],
    subject: construirAsuntoCorreo(escenario),
    html: construirHtmlCorreo({ lead, escenario, urlContinuacion, configuracionEscenario }),
    text: construirTextoCorreo({ lead, escenario, urlContinuacion, configuracionEscenario }),
  };

  if (replyTo) {
    payloadCorreo.reply_to = replyTo;
  }

  const respuesta = await fetch("https://api.resend.com/emails", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${resendApiKey}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(payloadCorreo),
  });

  if (!respuesta.ok) {
    const detalle = await respuesta.text();
    throw new Error(`Resend respondió ${respuesta.status}: ${detalle}`);
  }

  return {
    enviado: true,
    razon: null,
  };
}

function construirAsuntoCorreo(escenario) {
  if (escenario.codigo === "escenario_1") {
    return "Tienda Impulso: aprovecha tu oferta de bienvenida";
  }

  if (escenario.codigo === "escenario_2") {
    return "Tienda Escala: tu siguiente paso en Altyro Envios";
  }

  return "Enterprise: agenda tu reunión con Altyro Envios";
}

function construirMensajeCorreo(escenario, configuracionEscenario) {
  if (escenario.codigo === "escenario_1") {
    const venceTexto = formatearFechaCorreo(configuracionEscenario?.oferta_activa_hasta);
    return {
      segmento: "Tienda Impulso",
      titulo: "Tu perfil quedó listo para comenzar.",
      cuerpo:
        "Tienes una oferta activa por 20 minutos. Registrate ahora y obten un 20% de dcto en tus envios el primer mes.",
      detalle: venceTexto ? `La oferta vence a las ${venceTexto}.` : "",
      cta: "Aprovechar oferta ahora",
      url_video: configuracionEscenario?.url_video || "",
    };
  }

  if (escenario.codigo === "escenario_2") {
    return {
      segmento: "Tienda Escala",
      titulo: "Tu siguiente paso ya está preparado.",
      cuerpo:
        "Te identificamos como Tienda Escala. Revisa el video y continúa con el acompañamiento de uno de nuestros ejecutivos.",
      detalle: "",
      cta: "Ver mi siguiente paso",
      url_video: configuracionEscenario?.url_video || "",
    };
  }

  return {
    segmento: "Enterprise",
    titulo: "Ya puedes avanzar con tu reunión de integración.",
    cuerpo:
      "Te clasificamos como Enterprise. Revisa el video y agenda la reunión que mejor se acomode a tu operación.",
    detalle: "",
    cta: "Agendar reunión",
    url_video: configuracionEscenario?.url_video || "",
  };
}

function construirHtmlCorreo({ lead, escenario, urlContinuacion, configuracionEscenario }) {
  const mensaje = construirMensajeCorreo(escenario, configuracionEscenario);
  const nombre = escaparHtml(lead.contacto.nombre);
  const negocio = escaparHtml(lead.negocio.nombre_negocio);
  const cuerpo = escaparHtml(mensaje.cuerpo);
  const titulo = escaparHtml(mensaje.titulo);
  const cta = escaparHtml(mensaje.cta);
  const segmento = escaparHtml(mensaje.segmento || escenario.nombre);
  const detalle = mensaje.detalle ? escaparHtml(mensaje.detalle) : "";
  const url = escaparHtml(urlContinuacion);
  const urlVideo = escaparHtml(mensaje.url_video || "");
  const videoButton = urlVideo
    ? `<a href="${urlVideo}" style="display:inline-block;padding:13px 20px;border-radius:999px;background:#ffffff;color:#af00cd;text-decoration:none;font-weight:700;border:1px solid rgba(175,0,205,0.16);">Ver video</a>`
    : "";

  return `
    <div style="background:#f4f1f9;padding:32px 16px;font-family:Arial,sans-serif;color:#1f1534;">
      <div style="max-width:560px;margin:0 auto;background:#ffffff;border-radius:28px;padding:36px 32px;box-shadow:0 18px 50px rgba(65,28,98,0.08);">
        <div style="display:inline-block;padding:8px 14px;border-radius:999px;background:#f2e8ff;color:#8227d1;font-size:12px;font-weight:700;letter-spacing:0.08em;text-transform:uppercase;">
          ${segmento}
        </div>
        <h1 style="margin:18px 0 12px;font-size:28px;line-height:1.15;">${titulo}</h1>
        <p style="margin:0 0 12px;font-size:16px;line-height:1.65;">Hola ${nombre}, recibimos la información de <strong>${negocio}</strong>.</p>
        <p style="margin:0 0 24px;font-size:16px;line-height:1.65;">${cuerpo}</p>
        ${detalle ? `<p style="margin:0 0 22px;font-size:14px;line-height:1.6;color:#7a678f;">${detalle}</p>` : ""}
        <div style="display:flex;flex-wrap:wrap;gap:12px;">
          <a href="${url}" style="display:inline-block;padding:14px 22px;border-radius:999px;background:#e54b90;color:#ffffff;text-decoration:none;font-weight:700;">${cta}</a>
          ${videoButton}
        </div>
        <p style="margin:24px 0 0;font-size:13px;line-height:1.6;color:#6e6482;">Si el botón no funciona, abre este enlace: ${url}</p>
      </div>
    </div>
  `;
}

function construirTextoCorreo({ lead, escenario, urlContinuacion, configuracionEscenario }) {
  const mensaje = construirMensajeCorreo(escenario, configuracionEscenario);

  return [
    `Hola ${lead.contacto.nombre},`,
    "",
    `Recibimos la información de ${lead.negocio.nombre_negocio}.`,
    mensaje.segmento,
    mensaje.titulo,
    mensaje.cuerpo,
    mensaje.detalle || "",
    mensaje.url_video ? `Video: ${mensaje.url_video}` : "",
    "",
    `${mensaje.cta}: ${urlContinuacion}`,
  ]
    .filter(Boolean)
    .join("\n");
}

function formatearFechaCorreo(valor) {
  const fecha = new Date(valor);
  if (Number.isNaN(fecha.getTime())) {
    return "";
  }

  return new Intl.DateTimeFormat("es-CL", {
    hour: "2-digit",
    minute: "2-digit",
    hour12: false,
    timeZone: "America/Santiago",
  }).format(fecha);
}

function escaparHtml(valor = "") {
  return String(valor)
    .replaceAll("&", "&amp;")
    .replaceAll("<", "&lt;")
    .replaceAll(">", "&gt;")
    .replaceAll('"', "&quot;")
    .replaceAll("'", "&#39;");
}
