import ExcelJS from 'exceljs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import fs from 'node:fs/promises'

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

// Convierte letras de columna (ej: "Q") a número (17)
function colLettersToNumber(letters) {
  let num = 0
  for (const ch of letters.toUpperCase()) {
    const val = ch.charCodeAt(0) - 64 // 'A' -> 1
    num = num * 26 + val
  }
  return num
}

async function generarCodigoDesdeExcel() {
  try {
    const rutaExcel = path.join(__dirname, 'formato_ambulancias.xlsx')
    console.log('Leyendo archivo desde:', rutaExcel)

    const libro = new ExcelJS.Workbook()
    await libro.xlsx.readFile(rutaExcel)

    const hoja = libro.getWorksheet(1)
    if (!hoja) {
      console.error('No se encontró la primera hoja del Excel')
      return
    }

    const nombreHoja = hoja.name || 'Hoja1'

    let codigo = ''
    codigo += "import ExcelJS from 'exceljs'\n\n"
    codigo += "async function crearArchivo() {\n"
    codigo += "  const workbook = new ExcelJS.Workbook()\n"
    codigo += `  const sheet = workbook.addWorksheet(${JSON.stringify(nombreHoja)})\n\n`

    // Vamos a detectar hasta dónde llega de verdad el formato
    let ultimaColumnaConAlgo = 0
    let ultimaFilaConAlgo = 0

    // 1️⃣ Valores + formato de cada celda (tal cual la plantilla)
    hoja.eachRow({ includeEmpty: true }, (row, rowNumber) => {
      let filaTieneAlgo = false

      row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
        const addr      = cell.address
        const val       = cell.value
        const fill      = cell.fill
        const border    = cell.border
        const alignment = cell.alignment

        const tieneValor =
          val !== null && val !== undefined && val !== ''

        const tieneFormato =
          !!fill ||
          (border && Object.keys(border).length > 0) ||
          (alignment && Object.keys(alignment).length > 0)

        if (tieneValor || tieneFormato) {
          filaTieneAlgo = true
          if (colNumber > ultimaColumnaConAlgo) ultimaColumnaConAlgo = colNumber
        }

        // ✅ Valor
        if (tieneValor) {
          if (typeof val === 'string') {
            codigo += `  sheet.getCell('${addr}').value = ${JSON.stringify(val)};\n`
          } else if (typeof val === 'number') {
            codigo += `  sheet.getCell('${addr}').value = ${val};\n`
          } else if (typeof val === 'boolean') {
            codigo += `  sheet.getCell('${addr}').value = ${val};\n`
          } else if (val instanceof Date) {
            codigo += `  sheet.getCell('${addr}').value = new Date(${val.getFullYear()}, ${val.getMonth()}, ${val.getDate()});\n`
          } else if (val && typeof val === 'object' && val.formula) {
            codigo += `  sheet.getCell('${addr}').value = { formula: ${JSON.stringify(
              val.formula
            )}, result: ${JSON.stringify(val.result || null)} };\n`
          }
        }

        // 🎨 Color / relleno
        if (fill) {
          codigo += `  sheet.getCell('${addr}').fill = ${JSON.stringify(fill)};\n`
        }

        // 📏 Bordes
        if (border && Object.keys(border).length > 0) {
          codigo += `  sheet.getCell('${addr}').border = ${JSON.stringify(border)};\n`
        }

        // 📐 Alineación
        if (alignment && Object.keys(alignment).length > 0) {
          codigo += `  sheet.getCell('${addr}').alignment = ${JSON.stringify(alignment)};\n`
        }
      })

      if (filaTieneAlgo && rowNumber > ultimaFilaConAlgo) {
        ultimaFilaConAlgo = rowNumber
      }
    })

    codigo += '\n'
    codigo += '  // 2️⃣ Merges (bloques / uniones de celdas)\n'
    const merges = (hoja.model && hoja.model.merges) ? hoja.model.merges : []

    merges.forEach((rango) => {
      // ejemplo rango: "B3:R3"
      codigo += `  sheet.mergeCells('${rango}');\n`

      const partes = rango.split(':')
      if (partes.length === 2) {
        const fin = partes[1] // "R3"
        const match = fin.match(/^([A-Za-z]+)(\d+)$/)
        if (match) {
          const colLetters = match[1]
          const rowStr = match[2]
          const colNum = colLettersToNumber(colLetters)
          const rowNum = parseInt(rowStr, 10)

          if (!isNaN(colNum) && colNum > ultimaColumnaConAlgo) {
            ultimaColumnaConAlgo = colNum
          }
          if (!isNaN(rowNum) && rowNum > ultimaFilaConAlgo) {
            ultimaFilaConAlgo = rowNum
          }
        }
      }
    })

    // Seguridad por si algo raro:
    if (ultimaColumnaConAlgo === 0) ultimaColumnaConAlgo = hoja.columnCount || 1
    if (ultimaFilaConAlgo === 0) ultimaFilaConAlgo = hoja.rowCount || 1

    // 3️⃣ Ajuste: borde derecho en la última columna utilizada
    codigo += '\n  // 3️⃣ Ajuste: borde derecho en la última columna utilizada\n'
    codigo += `  const ultimaColumna = ${ultimaColumnaConAlgo};\n`
    codigo += `  const ultimaFila = ${ultimaFilaConAlgo};\n`
    codigo += '  for (let fila = 1; fila <= ultimaFila; fila++) {\n'
    codigo += '    const celda = sheet.getRow(fila).getCell(ultimaColumna);\n'
    codigo += '    const bordeAnterior = celda.border || {};\n'
    codigo += '    celda.border = {\n'
    codigo += '      ...bordeAnterior,\n'
    codigo += "      right: bordeAnterior.right && bordeAnterior.right.style ? bordeAnterior.right : { style: 'thin' },\n"
    codigo += '    };\n'
    codigo += '  }\n\n'

    codigo += "  await workbook.xlsx.writeFile('./salida.xlsx')\n"
    codigo += "  console.log('Archivo generado desde plantilla_autorizacion.js')\n"
    codigo += "}\n\n"
    codigo += "crearArchivo().catch(console.error)\n"

    const rutaSalidaCodigo = path.join(__dirname, 'plantilla_autorizacion_ambulancias.js')
    await fs.writeFile(rutaSalidaCodigo, codigo, 'utf8')

    console.log('✅ Código de plantilla generado en:', rutaSalidaCodigo)
  } catch (err) {
    console.error('Error en generarCodigoDesdeExcel:', err)
  }
}

generarCodigoDesdeExcel()
