import { type NextRequest, NextResponse } from "next/server";
import { google } from "googleapis";
import * as nodemailer from "nodemailer";

export const runtime = "nodejs";

const rateLimitMap = new Map<string, { count: number; resetTime: number }>();
const RATE_LIMIT_WINDOW = 60 * 1000;
const MAX_REQUESTS = 3;

function checkRateLimit(ip: string): boolean {
  const now = Date.now();
  const record = rateLimitMap.get(ip);

  if (!record || now > record.resetTime) {
    rateLimitMap.set(ip, { count: 1, resetTime: now + RATE_LIMIT_WINDOW });
    return true;
  }

  if (record.count >= MAX_REQUESTS) return false;

  record.count++;
  return true;
}

// Función simple para enviar email via SMTP usando node-smtp
async function sendEmailViaSMTP(
  to: string,
  from: string,
  subject: string,
  html: string,
  replyTo: string
): Promise<boolean> {
  try {
    console.log("[v0] Preparando envío de email via SMTP...");
    console.log("[v0] To:", to);
    console.log("[v0] From:", from);
    console.log("[v0] ReplyTo:", replyTo);

    // Intentar usar nodemailer
    const transporter = nodemailer.createTransport({
      host: process.env.SMTP_HOST,
      port: parseInt(process.env.SMTP_PORT || "587"),
      secure: process.env.SMTP_SECURE === "true",
      auth: {
        user: process.env.SMTP_USER,
        pass: process.env.SMTP_PASS,
      },
    });

    console.log("[v0] Transporter creado, enviando email...");

    const result = await transporter.sendMail({
      from,
      to,
      replyTo,
      subject,
      html,
    });

    console.log("[v0] Email enviado exitosamente");
    console.log("[v0] MessageId:", result.messageId);
    return true;
  } catch (error) {
    console.error("[v0] Error en sendEmailViaSMTP:", error);
    throw error;
  }
}

function createTransporter() {
  return nodemailer.createTransport({
    host: process.env.SMTP_HOST,
    port: parseInt(process.env.SMTP_PORT || "587"),
    secure: process.env.SMTP_SECURE === "true",
    auth: {
      user: process.env.SMTP_USER,
      pass: process.env.SMTP_PASS,
    },
  });
}

/**
 * Añade una fila a la planilla de Google Sheets con los datos de la inscripción.
 * Requiere GOOGLE_SHEET_ID y credenciales (GOOGLE_SERVICE_ACCOUNT_EMAIL + GOOGLE_PRIVATE_KEY).
 * En la primera fila de la hoja poné los encabezados:
 * Fecha | Nombre y Apellido | Email | Teléfono | Tipo de cruce | Tipo documento | Número documento | País | Provincia | Localidad | Domicilio | Fecha nacimiento | Ocupación | Estudios | Estado físico | Actividad física | Conocimientos cabalgata | Sabe ensillar | Hábito fumar | Cómo se enteró | Por qué se anotó | Qué le aportaría | Participa asociación | Comentarios adicionales
 */
async function appendInscripcionToSheet(
  row: Record<string, unknown>
): Promise<void> {
  const sheetId = process.env.GOOGLE_SHEET_ID;
  const email = process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL;
  const privateKey = process.env.GOOGLE_PRIVATE_KEY?.replace(/\\n/g, "\n");

  if (!sheetId || !email || !privateKey) {
    console.log(
      "[v0] Google Sheets no configurado (falta GOOGLE_SHEET_ID o credenciales), se omite planilla."
    );
    return;
  }

  const auth = new google.auth.GoogleAuth({
    credentials: { client_email: email, private_key: privateKey },
    scopes: ["https://www.googleapis.com/auth/spreadsheets"],
  });

  const sheets = google.sheets({ version: "v4", auth });
  const sheetName = process.env.GOOGLE_SHEET_NAME || "Inscripciones";

  // Log para verificar en servidor que se escribe en la planilla correcta
  const idPreview =
    sheetId.length > 12
      ? `${sheetId.slice(0, 8)}...${sheetId.slice(-4)}`
      : sheetId;
  console.log(
    "[v0] Planilla: ID",
    idPreview,
    "| Hoja:",
    sheetName
  );

  const formatVal = (v: unknown) =>
    v != null && String(v).trim() !== "" ? String(v).trim() : "";

  const fecha = new Date().toLocaleString("es-AR", {
    timeZone: "America/Argentina/Buenos_Aires",
  });
  const tipoCruceLabel =
    row.tipoCruce === "mula"
      ? "Cruce a lomo de mula"
      : row.tipoCruce === "pie"
      ? "Cruce a pie"
      : formatVal(row.tipoCruce);

  const values = [
    [
      fecha,
      formatVal(row.nombreApellido),
      formatVal(row.email),
      formatVal(row.telefono),
      tipoCruceLabel,
      formatVal(row.tipoDocumento),
      formatVal(row.numeroDocumento),
      formatVal(row.pais),
      formatVal(row.provincia),
      formatVal(row.localidad),
      formatVal(row.domicilio),
      formatVal(row.fechaNacimiento),
      formatVal(row.ocupacion),
      formatVal(row.estudios),
      formatVal(row.estadoFisico),
      formatVal(row.actividadFisica),
      formatVal(row.conocimientosCabalgata),
      formatVal(row.sabeEnsillar),
      formatVal(row.habitoFumar),
      formatVal(row.comoSeEntero),
      formatVal(row.porQueSeAnoto),
      formatVal(row.queLeAportaria),
      formatVal(row.participaAsociacion),
      formatVal(row.comentariosAdicionales),
    ],
  ];

  // Buscar la primera fila vacía (desde fila 2) para no dejar huecos
  const readRange = `${sheetName}!A2:A500`;
  const readRes = await sheets.spreadsheets.values.get({
    spreadsheetId: sheetId,
    range: readRange,
  });
  const rows = (readRes.data.values ?? []) as string[][];
  let firstEmptyRow = 2 + rows.length;
  for (let i = 0; i < rows.length; i++) {
    const cell = rows[i]?.[0];
    if (cell == null || String(cell).trim() === "") {
      firstEmptyRow = 2 + i;
      break;
    }
  }

  const writeRange = `${sheetName}!A${firstEmptyRow}:X${firstEmptyRow}`;
  console.log("[v0] Planilla: escribiendo en primera fila vacía:", writeRange);
  await sheets.spreadsheets.values.update({
    spreadsheetId: sheetId,
    range: writeRange,
    valueInputOption: "USER_ENTERED",
    requestBody: { values },
  });
  console.log("[v0] Planilla: fila", firstEmptyRow, "actualizada correctamente.");
}

export async function POST(request: NextRequest) {
  console.log("\n\n");
  console.log(
    "================================================================================"
  );
  console.log("[v0] 🚀 POST /api/contact RECIBIDA");
  console.log("[v0] Método:", request.method);
  console.log("[v0] URL:", request.url);
  console.log(
    "================================================================================"
  );

  try {
    const ip =
      request.headers.get("x-forwarded-for") ||
      request.headers.get("x-real-ip") ||
      "unknown";
    console.log("[v0] IP del cliente:", ip);

    if (!checkRateLimit(ip)) {
      console.log("[v0] ❌ Rate limit excedido para IP:", ip);
      return NextResponse.json(
        {
          success: false,
          error:
            "Demasiadas solicitudes. Por favor intenta nuevamente en un minuto.",
        },
        { status: 429 }
      );
    }

    console.log("[v0] ✅ Rate limit check passed");
    console.log("[v0] 📨 Leyendo body del request...");

    let body;
    try {
      body = await request.json();
      console.log("[v0] ✅ Body parseado correctamente");
      console.log("[v0] Datos recibidos:", JSON.stringify(body, null, 2));
    } catch (parseError) {
      console.error("[v0] ❌ ERROR al parsear JSON:", parseError);
      return NextResponse.json(
        { success: false, error: "Error al procesar el formulario." },
        { status: 400 }
      );
    }

    const {
      nombreApellido,
      email,
      emailRepetir,
      telefono,
      consentimiento,
      _company,
      tipoCruce,
      tipoDocumento,
      numeroDocumento,
      pais,
      provincia,
      localidad,
      domicilio,
      fechaNacimiento,
      ocupacion,
      estudios,
      estadoFisico,
      actividadFisica,
      conocimientosCabalgata,
      sabeEnsillar,
      habitoFumar,
      comoSeEntero,
      comentariosAdicionales,
      porQueSeAnoto,
      queLeAportaria,
      participaAsociacion,
    } = body;

    // Honeypot
    if (_company) {
      console.log("[v0] ⚠️ HONEYPOT TRIGGERED - probable spam");
      return NextResponse.json({ success: true });
    }

    console.log("[v0] ✅ Honeypot check passed");
    console.log("[v0] 🔍 Validando campos requeridos...");

    if (!nombreApellido || !email) {
      console.log("[v0] ❌ FALTA nombreApellido o email");
      console.log("[v0] nombreApellido:", nombreApellido);
      console.log("[v0] email:", email);
      return NextResponse.json(
        {
          success: false,
          error: "Todos los campos requeridos deben estar completos.",
        },
        { status: 400 }
      );
    }

    if (!consentimiento) {
      console.log("[v0] ❌ CONSENTIMIENTO NO DADO");
      return NextResponse.json(
        {
          success: false,
          error: "Debes autorizar el uso de tus datos para continuar.",
        },
        { status: 400 }
      );
    }

    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(email)) {
      console.log("[v0] ❌ EMAIL INVÁLIDO:", email);
      return NextResponse.json(
        { success: false, error: "Email inválido." },
        { status: 400 }
      );
    }

    if (emailRepetir && emailRepetir !== email) {
      console.log("[v0] ❌ LOS EMAILS NO COINCIDEN");
      return NextResponse.json(
        { success: false, error: "Los emails no coinciden." },
        { status: 400 }
      );
    }

    console.log("[v0] ✅ TODAS LAS VALIDACIONES PASARON");
    console.log("\n[v0] === NUEVA INSCRIPCIÓN VÁLIDA ===");
    console.log("[v0] Nombre:", nombreApellido);
    console.log("[v0] Email:", email);
    console.log("[v0] Tipo de cruce:", tipoCruce);
    console.log("[v0] Teléfono:", telefono);
    console.log("[v0] IP:", ip);
    console.log("[v0] Fecha:", new Date().toISOString());
    console.log("[v0] ===================================\n");

    // Función helper para formatear valores
    const formatValue = (value: string | null | undefined): string => {
      if (!value || value.trim() === "") return "No proporcionado";
      return String(value).trim();
    };

    // Función helper para formatear texto multilínea
    const formatMultiline = (value: string | null | undefined): string => {
      if (!value || value.trim() === "") return "No proporcionado";
      return String(value).replace(/\n/g, "<br>");
    };

    const htmlContent = `
      <!DOCTYPE html>
      <html>
      <head>
        <meta charset="UTF-8">
        <style>
          body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            color: #333;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
          }
          h2 {
            color: #092454;
            border-bottom: 3px solid #092454;
            padding-bottom: 10px;
            margin-top: 30px;
            margin-bottom: 20px;
          }
          h3 {
            color: #092454;
            margin-top: 25px;
            margin-bottom: 15px;
            font-size: 18px;
          }
          table {
            width: 100%;
            border-collapse: collapse;
            margin-bottom: 30px;
            background-color: #ffffff;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
          }
          th {
            background-color: #092454;
            color: #ffffff;
            padding: 12px 15px;
            text-align: left;
            font-weight: bold;
            width: 35%;
          }
          td {
            padding: 12px 15px;
            border-bottom: 1px solid #e0e0e0;
          }
          tr:last-child td {
            border-bottom: none;
          }
          tr:nth-child(even) {
            background-color: #f9f9f9;
          }
          tr:hover {
            background-color: #f5f5f5;
          }
          .footer {
            margin-top: 30px;
            padding-top: 15px;
            border-top: 1px solid #ddd;
            font-size: 12px;
            color: #666;
            text-align: center;
          }
        </style>
      </head>
      <body>
        <h2>Nueva Inscripción para el Cruce de los Andes</h2>
        
        <!-- Tipo de Cruce -->
        <h3>Tipo de Cruce</h3>
        <table>
          <tr>
            <th>Modalidad</th>
            <td>${
              tipoCruce === "mula"
                ? "Cruce a lomo de mula"
                : tipoCruce === "pie"
                ? "Cruce a pie"
                : formatValue(tipoCruce)
            }</td>
          </tr>
        </table>

        <!-- Datos Personales -->
        <h3>Datos Personales</h3>
        <table>
          <tr>
            <th>Nombre y Apellido</th>
            <td>${formatValue(nombreApellido)}</td>
          </tr>
          <tr>
            <th>Tipo de Documento</th>
            <td>${formatValue(tipoDocumento)}</td>
          </tr>
          <tr>
            <th>Número de Documento</th>
            <td>${formatValue(numeroDocumento)}</td>
          </tr>
          <tr>
            <th>Email</th>
            <td>${formatValue(email)}</td>
          </tr>
          <tr>
            <th>Teléfono</th>
            <td>${formatValue(telefono)}</td>
          </tr>
          <tr>
            <th>Fecha de Nacimiento</th>
            <td>${formatValue(fechaNacimiento)}</td>
          </tr>
          <tr>
            <th>Ocupación</th>
            <td>${formatValue(ocupacion)}</td>
          </tr>
          <tr>
            <th>Estudios Cursados</th>
            <td>${formatValue(estudios)}</td>
          </tr>
        </table>

        <!-- Ubicación -->
        <h3>Ubicación</h3>
        <table>
          <tr>
            <th>País</th>
            <td>${formatValue(pais)}</td>
          </tr>
          ${
            provincia
              ? `
          <tr>
            <th>Provincia</th>
            <td>${formatValue(provincia)}</td>
          </tr>
          `
              : ""
          }
          <tr>
            <th>Localidad</th>
            <td>${formatValue(localidad)}</td>
          </tr>
          <tr>
            <th>Domicilio</th>
            <td>${formatValue(domicilio)}</td>
          </tr>
        </table>

        <!-- Estado Físico y Salud -->
        <h3>Estado Físico y de Salud</h3>
        <table>
          <tr>
            <th>Estado Físico y de Salud</th>
            <td>${formatMultiline(estadoFisico)}</td>
          </tr>
          <tr>
            <th>¿Realiza alguna actividad física o deporte?</th>
            <td>${formatValue(actividadFisica)}</td>
          </tr>
          <tr>
            <th>¿Tiene conocimientos sobre montar?</th>
            <td>${formatValue(conocimientosCabalgata)}</td>
          </tr>
          <tr>
            <th>¿Sabe ensillar?</th>
            <td>${formatValue(sabeEnsillar)}</td>
          </tr>
          ${
            habitoFumar
              ? `
          <tr>
            <th>Hábito de Fumar</th>
            <td>${formatValue(habitoFumar)}</td>
          </tr>
          `
              : ""
          }
        </table>

        <!-- Información Adicional -->
        <h3>Información Adicional</h3>
        <table>
          <tr>
            <th>¿Cómo se enteró del Cruce de los Andes?</th>
            <td>${formatValue(comoSeEntero)}</td>
          </tr>
          ${
            porQueSeAnoto
              ? `
          <tr>
            <th>¿Por qué se anotó para participar del Cruce de los Andes?</th>
            <td>${formatMultiline(porQueSeAnoto)}</td>
          </tr>
          `
              : ""
          }
          ${
            queLeAportaria
              ? `
          <tr>
            <th>¿Qué le aportaría ser expedicionario del próximo Cruce?</th>
            <td>${formatMultiline(queLeAportaria)}</td>
          </tr>
          `
              : ""
          }
          ${
            participaAsociacion
              ? `
          <tr>
            <th>¿Participa en alguna Asociación o Institución afín?</th>
            <td>${formatMultiline(participaAsociacion)}</td>
          </tr>
          `
              : ""
          }
          ${
            comentariosAdicionales
              ? `
          <tr>
            <th>Comentarios Adicionales</th>
            <td>${formatMultiline(comentariosAdicionales)}</td>
          </tr>
          `
              : ""
          }
        </table>

        <div class="footer">
          <p>IP: ${ip} | Fecha: ${new Date().toLocaleString("es-AR", {
      timeZone: "America/Argentina/Buenos_Aires",
    })}</p>
        </div>
      </body>
      </html>
    `;

    // Email de confirmación/copia para quien rellenó el formulario
    const htmlContentUsuario = `
      <!DOCTYPE html>
      <html>
      <head>
        <meta charset="UTF-8">
        <style>
          body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 600px; margin: 0 auto; padding: 20px; }
          h2 { color: #092454; border-bottom: 3px solid #092454; padding-bottom: 10px; }
          .mensaje { background: #f0f7ff; padding: 15px; border-radius: 8px; margin: 20px 0; }
          table { width: 100%; border-collapse: collapse; margin: 15px 0; }
          th { background: #092454; color: #fff; padding: 10px; text-align: left; width: 40%; }
          td { padding: 10px; border: 1px solid #e0e0e0; }
          .footer { margin-top: 25px; font-size: 12px; color: #666; text-align: center; }
        </style>
      </head>
      <body>
        <h2>Cruce de los Andes – Inscripción recibida</h2>
        <p>Hola <strong>${formatValue(nombreApellido)}</strong>,</p>
        <div class="mensaje">
          <p>Hemos recibido correctamente tu inscripción para el Cruce de los Andes.</p>
          <p>Te contactaremos a la brevedad ante cualquier novedad.</p>
        </div>
        <p><strong>Resumen de tu inscripción:</strong></p>
        <table>
          <tr><th>Modalidad</th><td>${
            tipoCruce === "mula"
              ? "Cruce a lomo de mula"
              : tipoCruce === "pie"
              ? "Cruce a pie"
              : formatValue(tipoCruce)
          }</td></tr>
          <tr><th>Nombre</th><td>${formatValue(nombreApellido)}</td></tr>
          <tr><th>Email</th><td>${formatValue(email)}</td></tr>
          <tr><th>Teléfono</th><td>${formatValue(telefono)}</td></tr>
          <tr><th>Documento</th><td>${formatValue(tipoDocumento)} ${formatValue(
      numeroDocumento
    )}</td></tr>
          <tr><th>País / Localidad</th><td>${formatValue(pais)} ${
      provincia ? ` / ${formatValue(provincia)}` : ""
    } / ${formatValue(localidad)}</td></tr>
        </table>
        <div class="footer">
          <p>Recibes este correo porque completaste el formulario de inscripción en crucedelosandes.com.ar.</p>
        </div>
      </body>
      </html>
    `;

    // Versión texto plano del correo al usuario (mejora entregabilidad, menos spam)
    const modalidadTexto =
      tipoCruce === "mula"
        ? "Cruce a lomo de mula"
        : tipoCruce === "pie"
        ? "Cruce a pie"
        : formatValue(tipoCruce);
    const textContentUsuario = [
      "Cruce de los Andes – Inscripción recibida",
      "",
      `Hola ${formatValue(nombreApellido)},`,
      "",
      "Hemos recibido correctamente tu inscripción para el Cruce de los Andes.",
      "Te contactaremos a la brevedad ante cualquier novedad.",
      "",
      "Resumen de tu inscripción:",
      `Modalidad: ${modalidadTexto}`,
      `Nombre: ${formatValue(nombreApellido)}`,
      `Email: ${formatValue(email)}`,
      `Teléfono: ${formatValue(telefono)}`,
      `Documento: ${formatValue(tipoDocumento)} ${formatValue(
        numeroDocumento
      )}`,
      `País / Localidad: ${formatValue(pais)}${
        provincia ? ` / ${formatValue(provincia)}` : ""
      } / ${formatValue(localidad)}`,
      "",
      "Recibes este correo porque completaste el formulario de inscripción en crucedelosandes.com.ar.",
    ].join("\r\n");

    // ENV obligatorias. MAIL_TO puede ser uno o más mails separados por coma.
    const mailFrom = process.env.MAIL_FROM;
    const mailTo = process.env.MAIL_TO;

    console.log("[v0] 🔧 Validando configuración SMTP...");
    console.log(
      "[v0] SMTP_HOST:",
      process.env.SMTP_HOST ? "✅ Configurado" : "❌ NO configurado"
    );
    console.log(
      "[v0] SMTP_PORT:",
      process.env.SMTP_PORT ? "✅ Configurado" : "❌ NO configurado"
    );
    console.log(
      "[v0] SMTP_USER:",
      process.env.SMTP_USER ? "✅ Configurado" : "❌ NO configurado"
    );
    console.log(
      "[v0] SMTP_PASS:",
      process.env.SMTP_PASS ? "✅ Configurado" : "❌ NO configurado"
    );
    console.log(
      "[v0] MAIL_FROM:",
      mailFrom ? "✅ Configurado" : "❌ NO configurado"
    );
    console.log(
      "[v0] MAIL_TO:",
      mailTo ? "✅ Configurado" : "❌ NO configurado"
    );

    if (!mailFrom || !mailTo) {
      console.error("[v0] ❌ FALTA MAIL_FROM O MAIL_TO");
      return NextResponse.json(
        {
          success: false,
          error: "Configuración de email incompleta en el servidor.",
        },
        { status: 500 }
      );
    }

    // Email del remitente (por si MAIL_FROM viene como "Nombre <email@...>")
    const mailFromAddress = mailFrom.includes("<")
      ? mailFrom.replace(/^.*<([^>]+)>.*$/, "$1").trim()
      : mailFrom;

    console.log("[v0] ✅ Configuración SMTP completa");
    console.log("[v0] 📧 Intentando enviar email...");

    try {
      await sendEmailViaSMTP(
        mailTo,
        mailFrom,
        `Nueva inscripción - ${nombreApellido}`,
        htmlContent,
        email
      );
      console.log("[v0] ✅✅✅ EMAIL A ADMIN ENVIADO EXITOSAMENTE ✅✅✅");

      // Envío de copia/confirmación al mail de quien rellenó el formulario
      // (multipart text+html y From con nombre para reducir probabilidad de spam)
      try {
        const transporterUsuario = createTransporter();
        await transporterUsuario.sendMail({
          from: { name: "Cruce de los Andes", address: mailFromAddress },
          to: email,
          replyTo: mailFromAddress,
          subject: "Cruce de los Andes – Inscripción recibida",
          text: textContentUsuario,
          html: htmlContentUsuario,
        });
        console.log("[v0] ✅ Email de confirmación enviado al usuario:", email);
      } catch (userEmailError) {
        console.error(
          "[v0] ⚠️ No se pudo enviar la copia al usuario (inscripción sí registrada):",
          (userEmailError as Error).message
        );
      }

      // Cargar inscripción en la planilla de Google Sheets (si está configurada)
      try {
        await appendInscripcionToSheet(body);
        console.log("[v0] ✅ Inscripción cargada en la planilla");
      } catch (sheetError) {
        console.error(
          "[v0] ⚠️ No se pudo cargar en la planilla (inscripción sí registrada):",
          (sheetError as Error).message
        );
      }
    } catch (emailError) {
      console.error("[v0] ❌ ERROR AL ENVIAR EMAIL:", emailError);
      console.error("[v0] Error message:", (emailError as Error).message);
      console.error("[v0] Error stack:", (emailError as Error).stack);
    }

    console.log("[v0] 🎉 Respondiendo al cliente con success: true");
    return NextResponse.json({ success: true });
  } catch (error) {
    console.error(
      "\n" +
        "================================================================================"
    );
    console.error("[v0] ❌❌❌ ERROR NO CAPTURADO ❌❌❌");
    console.error("[v0] Error:", error);
    console.error("[v0] Error message:", (error as Error).message);
    console.error("[v0] Error stack:", (error as Error).stack);
    console.error(
      "================================================================================" +
        "\n"
    );

    return NextResponse.json(
      {
        success: false,
        error: "Error interno del servidor. Por favor intenta nuevamente.",
      },
      { status: 500 }
    );
  }
}
