export type InterfaceType = "ether" | "gre" | "wg" | "other"

export function mapRosInterfaceType(raw: string | undefined | null, name?: string): InterfaceType {
  const t = String(raw ?? "").trim().toLowerCase()
  if (t === "ether" || t === "ethernet" || t.startsWith("ether")) return "ether"
  // RouterOS /interface type for GRE is "gre-tunnel" (also gre, gre6, gre6-tunnel)
  if (t === "gre" || t.startsWith("gre-") || t.startsWith("gre6")) return "gre"
  if (t === "wg" || t === "wireguard") return "wg"

  const n = String(name ?? "").trim().toLowerCase()
  if (n.startsWith("gre") || n.includes("gre-tunnel")) return "gre"
  if (n.startsWith("wg-") || n.startsWith("wireguard")) return "wg"
  if (n.startsWith("ether") || n.startsWith("sfp")) return "ether"
  return "other"
}

export interface ParsedRosIface {
  name: string
  type: InterfaceType
  running: boolean
  disabled: boolean
}

function asBool(raw: unknown): boolean {
  if (typeof raw === "boolean") return raw
  const s = String(raw ?? "").trim().toLowerCase()
  return s === "true" || s === "yes" || s === "1"
}

export function parseRawInterfaces(json: string | null | undefined): ParsedRosIface[] {
  if (!json) return []
  try {
    const parsed = JSON.parse(json) as unknown
    const arr = Array.isArray(parsed) ? parsed : []
    const out: ParsedRosIface[] = []
    for (const item of arr) {
      if (!item || typeof item !== "object") continue
      const rec = item as Record<string, unknown>
      const name = String(rec.name ?? "").trim()
      if (!name) continue
      out.push({
        name,
        type: mapRosInterfaceType(String(rec.type ?? ""), name),
        running: asBool(rec.running),
        disabled: asBool(rec.disabled),
      })
    }
    return out
  } catch {
    return []
  }
}

export function isUniqueConstraintError(err: unknown): boolean {
  if (!err || typeof err !== "object") return false
  const rec = err as { code?: unknown; message?: unknown }
  const code = String(rec.code ?? "")
  const msg = String(rec.message ?? "")
  return code.includes("SQLITE_CONSTRAINT") || /unique constraint/i.test(msg)
}
