import type { Provider } from "../../../provider/provider"

const HEADERS = ["Model", "Access", "Snippet", "Latency"]
const PADDING = 9

const tty = process.stderr.isTTY ?? false

function color(style: string): string {
  return tty ? style : ""
}

function sanitize(text: string): string {
  return text.replace(/\x1b\[[0-9;]*m/g, "").replace(/[\x00-\x1f\x7f]/g, "")
}

function truncate(text: string, max: number): string {
  if (max < 4) return text.substring(0, max)
  return text.length > max ? text.substring(0, max - 3) + "..." : text
}

export function formatTable(rows: string[][], width: number): { header: string; separator: string; rows: string[] } {
  const clean = rows.map((row) => row.map((cell) => sanitize(cell ?? "")))
  const widths = HEADERS.map((h, i) => Math.max(h.length, ...clean.map((row) => row[i].length)))
  const total = widths.reduce((sum, item) => sum + item, 0) + PADDING
  const min = HEADERS[2].length + 3

  if (total > width && widths[2] > min) {
    const overflow = total - width
    widths[2] = Math.max(min, widths[2] - overflow)
  }

  const header = HEADERS.map((h, i) => h.padEnd(widths[i])).join(" | ")
  const separator = "-".repeat(header.length)
  const body = clean.map((row) => {
    const current = [row[0], row[1], row[2] ? truncate(row[2], widths[2]) : row[2], row[3]]
    return current.map((cell, i) => cell.padEnd(widths[i])).join(" | ")
  })

  return { header, separator, rows: body }
}

export function formatMarkdown(rows: string[][]): string {
  const escaped = rows.map((row) => row.map((cell) => sanitize(cell ?? "").replace(/\|/g, "\\|")))
  const widths = HEADERS.map((h, i) => Math.max(h.length, ...escaped.map((row) => row[i].length)))
  const pad = (text: string, i: number) => text.padEnd(widths[i])
  const header = "| " + HEADERS.map((h, i) => pad(h, i)).join(" | ") + " |"
  const separator = "| " + widths.map((w) => "-".repeat(w)).join(" | ") + " |"
  const body = escaped.map((row) => "| " + row.map((cell, i) => pad(cell, i)).join(" | ") + " |")

  return [header, separator, ...body].join("\n")
}

export function isTextModel(model: Provider.Model): boolean {
  return model.capabilities.input.text && model.capabilities.output.text
}
