export interface RosIfaceIndexRow {
  ".id"?: string
  name?: string
  ifindex?: string
}

const cache = new Map<number, Map<number, string>>()
const fetchedAt = new Map<number, number>()
const lastAttempt = new Map<number, number>()

export const IFACE_CACHE_TTL_MS = 60_000

/** RouterOS `.id` (`*A`) → SNMP ifIndex (10). */
export function rosIdToIfIndex(id: string | undefined | null): number | null {
  if (!id) return null
  const raw = String(id).trim()
  const hex = raw.startsWith("*") ? raw.slice(1) : raw
  if (!hex || !/^[0-9a-fA-F]+$/.test(hex)) return null
  const n = parseInt(hex, 16)
  return Number.isFinite(n) ? n : null
}

export function rememberServerIfaces(serverId: number, rows: RosIfaceIndexRow[]): void {
  const map = new Map<number, string>()
  for (const row of rows) {
    const name = String(row.name ?? "").trim()
    if (!name) continue
    const fromProp = Number.parseInt(String(row.ifindex ?? ""), 10)
    const fromId = rosIdToIfIndex(row[".id"])
    if (Number.isFinite(fromProp) && fromProp > 0) map.set(fromProp, name)
    if (fromId != null && fromId > 0) map.set(fromId, name)
  }
  cache.set(serverId, map)
  fetchedAt.set(serverId, Date.now())
}

export function resolveIfaceName(serverId: number, indexOrName: string): { name: string; index: string } {
  const trimmed = String(indexOrName ?? "").trim()
  if (!trimmed || trimmed === "0") return { name: "—", index: trimmed }
  if (!/^\d+$/.test(trimmed)) return { name: trimmed, index: "" }
  const idx = Number(trimmed)
  const name = cache.get(serverId)?.get(idx)
  if (name) return { name, index: trimmed }
  return { name: `#${trimmed}`, index: trimmed }
}

export function ifaceCacheHas(serverId: number): boolean {
  return cache.has(serverId)
}

export function ifaceCacheFresh(serverId: number, ttlMs = IFACE_CACHE_TTL_MS): boolean {
  const prev = fetchedAt.get(serverId) ?? 0
  return Boolean(prev && Date.now() - prev < ttlMs && cache.has(serverId))
}

/** Не ходить в REST, пока кэш жив или с момента последней попытки не прошёл TTL. */
export function shouldRefreshIfaces(serverId: number, ttlMs = IFACE_CACHE_TTL_MS): boolean {
  if (ifaceCacheFresh(serverId, ttlMs)) return false
  const attempted = lastAttempt.get(serverId) ?? 0
  return !(attempted && Date.now() - attempted < ttlMs)
}

export function markIfaceRefreshAttempt(serverId: number, at = Date.now()): void {
  lastAttempt.set(serverId, at)
}

export function resetIfaceCacheForTests(): void {
  cache.clear()
  fetchedAt.clear()
  lastAttempt.clear()
}
