/**
 * Portal JWT RBAC helpers (mirrors @authportal/shared hasPermission).
 * Format: mm:<section>:<read|write|admin>
 */

export type AuthUser = {
  id: string
  email: string
  name: string
  apps: string[]
  permissions: string[]
  isAdmin?: boolean
}

export function hasPermission(
  granted: readonly string[],
  required: string,
): boolean {
  if (granted.includes(required)) return true
  if (required.startsWith("mm:users:") && granted.includes("mm:settings:admin")) {
    return true
  }
  const parts = required.split(":")
  if (parts.length !== 3) return false
  const [app, section, action] = parts
  if (action === "read") {
    return (
      granted.includes(`${app}:${section}:write`) ||
      granted.includes(`${app}:${section}:admin`)
    )
  }
  if (action === "write") {
    return granted.includes(`${app}:${section}:admin`)
  }
  return false
}

type Rule = {
  methods: string[]
  match: (path: string) => boolean
  permission: string
}

const RULES: Rule[] = [
  {
    methods: ["GET", "POST", "PUT", "PATCH", "DELETE"],
    match: (p) =>
      p.startsWith("/api/system") ||
      p.startsWith("/api/scheduler") ||
      p.startsWith("/api/evobgp"),
    permission: "mm:settings:admin",
  },
  {
    methods: ["GET"],
    match: (p) => p.startsWith("/api/users"),
    permission: "mm:users:read",
  },
  {
    methods: ["POST", "PUT", "PATCH", "DELETE"],
    match: (p) => p.startsWith("/api/users"),
    permission: "mm:users:write",
  },
  {
    methods: ["GET"],
    match: (p) => p.startsWith("/api/sidebar-counts") || p.startsWith("/api/events"),
    permission: "mm:dashboard:read",
  },
  {
    methods: ["GET"],
    match: (p) => p.startsWith("/api/servers"),
    permission: "mm:servers:read",
  },
  {
    methods: ["POST", "PUT", "PATCH", "DELETE"],
    match: (p) => p.startsWith("/api/servers"),
    permission: "mm:servers:write",
  },
  {
    methods: ["GET"],
    match: (p) => p.startsWith("/api/filters"),
    permission: "mm:filters:read",
  },
  {
    methods: ["POST", "PUT", "PATCH", "DELETE"],
    match: (p) => p.startsWith("/api/filters"),
    permission: "mm:filters:write",
  },
  {
    methods: ["GET"],
    match: (p) => p.startsWith("/api/bgp"),
    permission: "mm:bgp:read",
  },
  {
    methods: ["POST", "PUT", "PATCH", "DELETE"],
    match: (p) => p.startsWith("/api/bgp"),
    permission: "mm:bgp:write",
  },
  {
    methods: ["GET"],
    match: (p) => p.startsWith("/api/uptime"),
    permission: "mm:uptime:read",
  },
  {
    methods: ["POST", "PUT", "PATCH", "DELETE"],
    match: (p) => p.startsWith("/api/uptime"),
    permission: "mm:uptime:write",
  },
  {
    methods: ["GET"],
    match: (p) => p.startsWith("/api/traffic"),
    permission: "mm:traffic:read",
  },
  {
    methods: ["POST", "PUT", "PATCH", "DELETE"],
    match: (p) => p.startsWith("/api/traffic"),
    permission: "mm:traffic:write",
  },
  {
    methods: ["GET"],
    match: (p) => p.startsWith("/api/alerts"),
    permission: "mm:alerts:read",
  },
  {
    methods: ["POST", "PUT", "PATCH", "DELETE"],
    match: (p) => p.startsWith("/api/alerts"),
    permission: "mm:alerts:write",
  },
  {
    methods: ["GET"],
    match: (p) => p.startsWith("/api/backups"),
    permission: "mm:backups:read",
  },
  {
    methods: ["POST", "PUT", "PATCH", "DELETE"],
    match: (p) => p.startsWith("/api/backups"),
    permission: "mm:backups:write",
  },
  {
    methods: ["GET"],
    match: (p) => p.startsWith("/api/certificates"),
    permission: "mm:certificates:read",
  },
  {
    methods: ["POST", "PUT", "PATCH", "DELETE"],
    match: (p) => p.startsWith("/api/certificates"),
    permission: "mm:certificates:write",
  },
  {
    methods: ["GET"],
    match: (p) =>
      p.startsWith("/api/network") ||
      p.startsWith("/api/ospf") ||
      p.startsWith("/api/recursive") ||
      p.startsWith("/api/probes") ||
      p.startsWith("/api/internet-path") ||
      p.startsWith("/api/exec") ||
      p.startsWith("/api/wireguard") ||
      p.startsWith("/api/firewall"),
    permission: "mm:network:read",
  },
  {
    methods: ["POST", "PUT", "PATCH", "DELETE"],
    match: (p) =>
      p.startsWith("/api/network") ||
      p.startsWith("/api/ospf") ||
      p.startsWith("/api/recursive") ||
      p.startsWith("/api/probes") ||
      p.startsWith("/api/internet-path") ||
      p.startsWith("/api/exec") ||
      p.startsWith("/api/wireguard") ||
      p.startsWith("/api/firewall"),
    permission: "mm:network:write",
  },
]

/** Resolve required permission for method+path, or null if public / unknown. */
export function permissionForRequest(
  method: string,
  path: string,
): string | null {
  const m = method.toUpperCase()
  const pathname = path.split("?")[0] ?? path
  for (const rule of RULES) {
    if (!rule.methods.includes(m)) continue
    if (rule.match(pathname)) return rule.permission
  }
  if (pathname.startsWith("/api/")) return "mm:dashboard:read"
  return null
}
