// Endpoint para imprimir imágenes usando Jimp
import { Jimp } from 'jimp'
import { EposMessageBuilder } from '../../utils/eposBuilder'
import { buildSoapEnvelope, sendToPrinter, parsePrinterResponse } from '../../utils/printer'

export default defineEventHandler(async (event) => {
  try {
    const config = useRuntimeConfig()
    const body = await readBody(event)

    const {
      path,
      width,
      threshold = 128,
      mode = 'mono'
    } = body as {
      path?: string
      width?: number
      threshold?: number
      mode?: string
    }

    if (!path) {
      return {
        ok: false,
        error: 'path required'
      }
    }

    // Leer y procesar imagen
    const img = await Jimp.read(path)
    let targetWidth = width || img.width
    if (targetWidth <= 0) targetWidth = img.width

    const scale = targetWidth / img.width
    const targetHeight = Math.max(1, Math.round(img.height * scale))

    // Resize y convertir a escala de grises
    img.resize({ w: targetWidth, h: targetHeight })
    img.greyscale()

    // Empaquetar bits MSB first por byte
    const bytesPerRow = Math.ceil(targetWidth / 8)
    const out = Buffer.alloc(bytesPerRow * targetHeight)
    let outIdx = 0

    for (let y = 0; y < targetHeight; y++) {
      let byte = 0
      let bit = 7
      let rowBytes = 0

      for (let x = 0; x < targetWidth; x++) {
        const color = img.getPixelColor(x, y)
        // Extraer componente rojo (ya es greyscale, todos los canales son iguales)
        const r = (color >> 24) & 0xFF
        const isBlack = r < threshold

        if (isBlack) byte |= (1 << bit)
        bit--

        if (bit < 0) {
          out[outIdx++] = byte
          rowBytes++
          byte = 0
          bit = 7
        }
      }

      // Rellenar bits restantes
      if (bit !== 7) {
        out[outIdx++] = byte
        rowBytes++
      }

      // Rellenar a bytes completos si es necesario
      while (rowBytes < bytesPerRow) {
        out[outIdx++] = 0
        rowBytes++
      }
    }

    const base64 = out.toString('base64')

    // Construir mensaje ePOS
    const builder = new EposMessageBuilder()
    builder.imageRaw({
      width: targetWidth,
      height: targetHeight,
      mode,
      base64
    })

    const soap = buildSoapEnvelope(builder.build())

    const result = await sendToPrinter(
      soap,
      config.printerHost,
      config.printerDeviceId,
      parseInt(config.printerTimeoutMs)
    )

    const { success, code } = parsePrinterResponse(result.data)

    return {
      ok: success,
      httpStatus: result.status,
      code,
      raw: result.data,
      width: targetWidth,
      height: targetHeight
    }
  } catch (err: any) {
    return {
      ok: false,
      error: err.message
    }
  }
})
