import { eq } from "drizzle-orm"
import { db } from "../db/index.js"
import { servers } from "../db/schema.js"
import { MikrotikClient } from "./mikrotik.js"

type ServerRow = typeof servers.$inferSelect

interface RosGre {
  ".id"?: string
  name?: string
  "local-address"?: string
  "remote-address"?: string
  "allow-fast-path"?: string
  "clamp-tcp-mss"?: string
  mtu?: string
  "keepalive"?: string
  dscp?: string
  running?: string
  disabled?: string
  comment?: string
}

export type GreTunnelLiveStatus = "up" | "down" | "degraded"

/** Как в UI `/alerts`: `${tunnelName} / ${serverName}`. */
export type GreTunnelLiveRow = {
  targetLabel: string
  status: GreTunnelLiveStatus
}

function mapGreRow(server: ServerRow, g: RosGre, idx: number): GreTunnelLiveRow {
  const running = g.running === "true"
  const disabled = g.disabled === "true"
  const status: GreTunnelLiveStatus = disabled ? "down" : running ? "up" : "degraded"
  const sn = String(server.name ?? "").trim() || String(server.host ?? "").trim() || String(server.id)
  const tn = (String(g.name ?? "").trim() || String(g[".id"] ?? "").trim() || `gre-${idx + 1}`).trim()
  const label = `${tn} / ${sn}`.trim()
  return { targetLabel: label, status }
}

async function fetchGreForServer(server: ServerRow): Promise<GreTunnelLiveRow[]> {
  const client = MikrotikClient.fromServer(server)
  const greRaw = await client.get<RosGre[]>("/interface/gre")
  return greRaw.map((g, idx) => mapGreRow(server, g, idx))
}

/** GRE с включённых серверов — тот же смысл, что `/api/filters/gre-tunnels` (без правил фильтров). */
export async function fetchGreTunnelLiveRows(): Promise<GreTunnelLiveRow[]> {
  const enabledServers = db.select().from(servers).where(eq(servers.enabled, true)).all()
  const results = await Promise.all(
    enabledServers.map(async (server) => {
      try {
        return await fetchGreForServer(server)
      } catch {
        return [] as GreTunnelLiveRow[]
      }
    }),
  )
  return results.flat()
}
