#!/usr/bin/env bun
import { sendGrid } from "./vestaboard"

const ROWS = 6
const COLS = 22

const charToCode = (c: string): number => {
  if (c === " ") return 0
  if (c >= "A" && c <= "Z") return c.charCodeAt(0) - 64
  if (c >= "a" && c <= "z") return c.charCodeAt(0) - 96
  if (c >= "0" && c <= "9") return c.charCodeAt(0) - 48 + 27
  const special: Record<string, number> = {
    "!": 37,
    "@": 38,
    "#": 39,
    $: 40,
    "(": 41,
    ")": 42,
    "-": 44,
    "+": 46,
    "&": 47,
    "=": 48,
    ";": 49,
    ":": 50,
    "'": 52,
    '"': 53,
    "%": 54,
    ",": 55,
    ".": 56,
    "/": 59,
    "?": 60,
    "°": 62,
    "🟥": 63,
    "🟧": 64,
    "🟨": 65,
    "🟩": 66,
    "🟦": 67,
    "🟪": 68,
    "⬜": 69,
    "⬛": 70,
  }
  return special[c] ?? 0
}

const blankGrid = (): number[][] => Array.from({ length: ROWS }, () => Array(COLS).fill(0))

const textToGrid = (text: string): number[][] => {
  const grid = blankGrid()
  const lines = text.split("\n").slice(0, ROWS)

  lines.forEach((line, row) => {
    const chars = [...line].slice(0, COLS)
    const startCol = Math.floor((COLS - chars.length) / 2)
    chars.forEach((char, i) => {
      grid[row]![startCol + i] = charToCode(char)
    })
  })

  // Vertically center if fewer lines than rows
  if (lines.length < ROWS) {
    const offset = Math.floor((ROWS - lines.length) / 2)
    const centered = blankGrid()
    lines.forEach((_, i) => {
      centered[i + offset] = grid[i] as any
    })
    return centered
  }

  return grid
}

const usage = `
Usage: bun src/vesta/cli.ts <message>

Examples:
  bun src/vesta/cli.ts "Hello World"
  bun src/vesta/cli.ts "Line 1" "Line 2" "Line 3"
  echo "Piped text" | bun src/vesta/cli.ts

Special characters: ! @ # $ ( ) - + & = ; : ' " % , . / ?
Colors: 🟥 🟧 🟨 🟩 🟦 🟪 ⬜ ⬛
`

const main = async () => {
  let text: string

  if (process.argv.length > 2) {
    text = process.argv.slice(2).join("\n")
  } else if (!process.stdin.isTTY) {
    text = await Bun.stdin.text()
  } else {
    console.log(usage)
    process.exit(1)
  }

  text = text.trim()
  if (!text) {
    console.error("Error: Empty message")
    process.exit(1)
  }

  console.log(`Sending: "${text.replace(/\n/g, " | ")}"`)
  const grid = textToGrid(text)
  await sendGrid(grid)
}

main()
