import { readFileSync } from "node:fs"
import path from "node:path"

export type Brand = {
  base: string
  surface: string
  fg: string
  muted: string
  accent: string
  line: string
}

const HEX_RE = /^#[0-9a-fA-F]{6}$/

type BrandKey = keyof Brand

const REQUIRED_KEYS: BrandKey[] = ["base", "surface", "fg", "muted", "accent"]

export function validateBrand(raw: unknown): Brand {
  if (typeof raw !== "object" || raw === null) {
    throw new Error("brand.json must be a JSON object")
  }
  const obj = raw as Record<string, unknown>
  for (const key of REQUIRED_KEYS) {
    if (!(key in obj)) {
      throw new Error(`brand.json missing required key: ${key}`)
    }
    const val = obj[key]
    if (typeof val !== "string" || !HEX_RE.test(val)) {
      throw new Error(`brand.json key '${key}' must be a 6-digit hex color (got: ${String(val)})`)
    }
  }
  if ("line" in obj && typeof obj.line !== "string") {
    throw new Error("brand.json key 'line' must be a string")
  }
  return {
    base: obj.base as string,
    surface: obj.surface as string,
    fg: obj.fg as string,
    muted: obj.muted as string,
    accent: obj.accent as string,
    line: (obj.line as string | undefined) ?? "rgba(255,255,255,0.06)",
  }
}

export function loadBrand(dir: string): Brand {
  const brandPath = path.join(dir, "brand.json")
  const raw = JSON.parse(readFileSync(brandPath, "utf-8"))
  return validateBrand(raw)
}

export function resolveColor(brand: Brand, name: string): string {
  if (name === "none") return "none"
  if (name in brand) return (brand as Record<string, string>)[name]
  throw new Error(`unknown color alias: ${name}`)
}