/**
 * Script para importar inscripciones desde los correos ya recibidos en la casilla
 * y cargarlos en la planilla de Google Sheets.
 *
 * Uso: pnpm run import-emails
 *
 * Importante: ejecutalo una sola vez para no duplicar filas. Si lo corrés de nuevo,
 * se volverán a agregar las mismas inscripciones (podés mover/archivar esos mails
 * antes de una segunda ejecución si querés evitar duplicados).
 *
 * Requiere en .env:
 * - IMAP_HOST (ej: imap.purelymail.com para Purely Mail)
 * - IMAP_USER (email completo, ej: info@crucedelosandes.com.ar)
 * - IMAP_PASS (contraseña o App Password)
 * - GOOGLE_SHEET_ID, GOOGLE_SERVICE_ACCOUNT_EMAIL, GOOGLE_PRIVATE_KEY
 * - GOOGLE_SHEET_NAME (opcional, default "Inscripciones")
 *
 * Si no están IMAP_*, usa SMTP_USER y SMTP_PASS con IMAP_HOST por defecto.
 */

import * as dotenv from "dotenv"
import * as path from "path"
import { ImapFlow } from "imapflow"
import { simpleParser } from "mailparser"
import * as cheerio from "cheerio"
import { google } from "googleapis"

// Cargar .env desde la raíz del proyecto
dotenv.config({ path: path.resolve(process.cwd(), ".env") })

const IMAP_HOST = process.env.IMAP_HOST || "imap.purelymail.com"
const IMAP_PORT = parseInt(process.env.IMAP_PORT || "993", 10)
const IMAP_USER = process.env.IMAP_USER || process.env.SMTP_USER
const IMAP_PASS = process.env.IMAP_PASS || process.env.SMTP_PASS

const GOOGLE_SHEET_ID = process.env.GOOGLE_SHEET_ID
const GOOGLE_SERVICE_ACCOUNT_EMAIL = process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL
const GOOGLE_PRIVATE_KEY = process.env.GOOGLE_PRIVATE_KEY?.replace(/\\n/g, "\n")
const GOOGLE_SHEET_NAME = process.env.GOOGLE_SHEET_NAME || "Inscripciones"

// Mapeo: texto del <th> en el correo -> clave del campo (mismo orden que la planilla)
const LABEL_TO_KEY: Record<string, string> = {
  Modalidad: "tipoCruce",
  "Nombre y Apellido": "nombreApellido",
  "Tipo de Documento": "tipoDocumento",
  "Número de Documento": "numeroDocumento",
  Email: "email",
  Teléfono: "telefono",
  "Fecha de Nacimiento": "fechaNacimiento",
  Ocupación: "ocupacion",
  "Estudios Cursados": "estudios",
  País: "pais",
  Provincia: "provincia",
  Localidad: "localidad",
  Domicilio: "domicilio",
  "Estado Físico y de Salud": "estadoFisico",
  "¿Realiza alguna actividad física o deporte?": "actividadFisica",
  "¿Tiene conocimientos sobre montar?": "conocimientosCabalgata",
  "¿Sabe ensillar?": "sabeEnsillar",
  "Hábito de Fumar": "habitoFumar",
  "¿Cómo se enteró del Cruce de los Andes?": "comoSeEntero",
  "¿Por qué se anotó para participar del Cruce de los Andes?": "porQueSeAnoto",
  "¿Qué le aportaría ser expedicionario del próximo Cruce?": "queLeAportaria",
  "¿Participa en alguna Asociación o Institución afín?": "participaAsociacion",
  "Comentarios Adicionales": "comentariosAdicionales",
}

// Orden de columnas en la planilla (igual que en route.ts)
const ROW_KEYS = [
  "fecha",
  "nombreApellido",
  "email",
  "telefono",
  "tipoCruce",
  "tipoDocumento",
  "numeroDocumento",
  "pais",
  "provincia",
  "localidad",
  "domicilio",
  "fechaNacimiento",
  "ocupacion",
  "estudios",
  "estadoFisico",
  "actividadFisica",
  "conocimientosCabalgata",
  "sabeEnsillar",
  "habitoFumar",
  "comoSeEntero",
  "porQueSeAnoto",
  "queLeAportaria",
  "participaAsociacion",
  "comentariosAdicionales",
]

function normalizeValue(raw: string): string {
  const v = raw.replace(/\s+/g, " ").trim()
  if (v === "No proporcionado" || v === "") return ""
  return v
}

function parseHtmlToFields(html: string): Record<string, string> {
  const $ = cheerio.load(html)
  const data: Record<string, string> = {}

  $("table tr").each((_, tr) => {
    const thText = $(tr).find("th").first().text().trim().replace(/\s+/g, " ")
    const tdHtml = $(tr).find("td").first().html() ?? ""
    if (!thText) return
    const cellText = cheerio.load(tdHtml).root().text().trim().replace(/\s+/g, " ")
    const key = LABEL_TO_KEY[thText]
    if (key) data[key] = normalizeValue(cellText)
  })

  return data
}

function buildRowFromFields(
  fields: Record<string, string>,
  fecha: string
): string[] {
  const row: string[] = []
  for (const key of ROW_KEYS) {
    if (key === "fecha") {
      row.push(fecha)
      continue
    }
    row.push(fields[key] ?? "")
  }
  return row
}

async function appendRowsToSheet(rows: string[][]): Promise<void> {
  if (!GOOGLE_SHEET_ID || !GOOGLE_SERVICE_ACCOUNT_EMAIL || !GOOGLE_PRIVATE_KEY) {
    throw new Error("Faltan GOOGLE_SHEET_ID o credenciales de Google")
  }

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

  const sheets = google.sheets({ version: "v4", auth })

  await sheets.spreadsheets.values.append({
    spreadsheetId: GOOGLE_SHEET_ID,
    range: GOOGLE_SHEET_NAME,
    valueInputOption: "USER_ENTERED",
    insertDataOption: "INSERT_ROWS",
    requestBody: { values: rows },
  })
}

async function main(): Promise<void> {
  if (!IMAP_USER || !IMAP_PASS) {
    console.error(
      "Faltan IMAP_USER e IMAP_PASS (o SMTP_USER y SMTP_PASS) en .env"
    )
    process.exit(1)
  }

  console.log("Conectando a", IMAP_HOST, "como", IMAP_USER, "...")
  const client = new ImapFlow({
    host: IMAP_HOST,
    port: IMAP_PORT,
    secure: true,
    auth: { user: IMAP_USER, pass: IMAP_PASS },
  })

  const rowsToAppend: string[][] = []

  try {
    await client.connect()
    const lock = await client.getMailboxLock("INBOX")

    try {
      // Buscar por asunto que contenga "Nueva inscripción" (el mail tiene "Nueva inscripción - Nombre")
      const messages = client.fetch(
        { subject: "Nueva inscripción" },
        { source: true, uid: true }
      )

      for await (const msg of messages) {
        const source = msg.source
        if (!source) continue

        const parsed = await simpleParser(source)
        const html = parsed.html
        const date = parsed.date

        if (!html || !html.includes("Nueva Inscripción para el Cruce")) {
          console.log("  Saltando mensaje (sin HTML esperado o distinto asunto)")
          continue
        }

        const fields = parseHtmlToFields(html)
        if (!fields.nombreApellido && !fields.email) {
          console.log("  Saltando mensaje (no se pudieron extraer datos)")
          continue
        }

        const fecha = date
          ? date.toLocaleString("es-AR", {
              timeZone: "America/Argentina/Buenos_Aires",
            })
          : new Date().toLocaleString("es-AR", {
              timeZone: "America/Argentina/Buenos_Aires",
            })

        const row = buildRowFromFields(fields, fecha)
        rowsToAppend.push(row)
        console.log("  Inscripción:", fields.nombreApellido || fields.email)
      }
    } finally {
      lock.release()
    }
  } finally {
    client.logout().catch(() => {})
  }

  if (rowsToAppend.length === 0) {
    console.log("No se encontraron correos de inscripción para importar.")
    return
  }

  console.log("\nCargando", rowsToAppend.length, "fila(s) en la planilla...")
  await appendRowsToSheet(rowsToAppend)
  console.log("Listo. Se importaron", rowsToAppend.length, "inscripción(es).")
}

main().catch((err) => {
  console.error(err)
  process.exit(1)
})
