// Staff roster + role/permission system.
// Roles, in descending order of power: owner > senior > admin > trial

const ROLES = {
  owner:  { id: "owner",  label: "Owner",         tier: 4, color: "#c8a8ff" },
  senior: { id: "senior", label: "Senior Admin",  tier: 3, color: "#8b95ff" },
  admin:  { id: "admin",  label: "Admin",         tier: 2, color: "#7eb6d9" },
  trial:  { id: "trial",  label: "Trial Admin",   tier: 1, color: "#7ec495" },
};

const STAFF = [
  { id: "mara", name: "Mara",  handle: "mara",  role: "owner",  initials: "MA" },
  { id: "rin",  name: "Rin",   handle: "rin",   role: "owner",  initials: "RI" },
  { id: "sten", name: "Sten",  handle: "sten",  role: "senior", initials: "ST" },
  { id: "veld", name: "Veld",  handle: "veld",  role: "admin",  initials: "VE" },
  { id: "ash",  name: "Ash",   handle: "ash",   role: "admin",  initials: "AS" },
  { id: "koba", name: "Koba",  handle: "koba",  role: "trial",  initials: "KO" },
];

// Permission predicates. Each returns either:
//   true / false                       — allowed / not allowed
//   { allowed: false, reason: "…" }    — denied with explanation for tooltip
//   { allowed: true,  cap: <number> }  — allowed but capped (e.g. trial admin can only temp ban ≤ 24h)
const PERMS = {
  // Player actions
  "player.kick":      (r) => true,
  "player.tempban":   (r) => r === "trial" ? { allowed: true, cap: 1440 /* mins = 24h */ } : true,
  "player.permban":   (r) => r === "trial" ? deny("Permanent bans are restricted to Admin and above.") : true,
  "player.networkban":(r) => (r === "owner" || r === "senior") ? true : deny("Network-wide bans are restricted to Senior Admin and above."),
  "player.unban.any": (r) => (r === "owner" || r === "senior") ? true : false,
  "player.unban.own": (r) => r !== "trial",
  "player.pm":        (r) => true,
  "player.note":      (r) => true,
  // Server actions
  "server.broadcast.one": (r) => r !== "trial",
  "server.broadcast.all": (r) => (r === "owner" || r === "senior"),
  "server.power":         (r) => (r === "owner" || r === "senior") ? true : deny("Restart and shutdown are restricted to Senior Admin and above."),
  // Data visibility
  "view.ip":          (r) => r !== "trial",
  "view.audit.all":   (r) => r !== "trial",
  // Staff management
  "staff.manage":     (r) => r === "owner",
};

function deny(reason) { return { allowed: false, reason }; }

// Resolve a permission check to {allowed, reason, cap}.
function check(role, action) {
  const fn = PERMS[action];
  if (!fn) return { allowed: false, reason: "Unknown action: " + action };
  const out = fn(role);
  if (out === true) return { allowed: true };
  if (out === false) return { allowed: false, reason: "Not permitted at your tier." };
  return out;
}

// Sugar: returns just the boolean.
function can(role, action) { return check(role, action).allowed; }

// Mask IPs for low-tier roles
function maskIP(ip, role) {
  if (can(role, "view.ip")) return ip;
  // 192.168.1.42 -> 192.168.•.•
  const p = ip.split(".");
  return `${p[0]}.${p[1]}.•.•`;
}
function maskGUID(g, role) {
  if (can(role, "view.ip")) return g;
  // Mask middle of GUID
  if (g.length > 12) return g.slice(0,6) + "…" + g.slice(-4);
  return g;
}

// Context
const AuthCtx = React.createContext(null);

const MOCK_USER = { id: "mara", handle: "mara", display_name: "Mara", role: "owner", initials: "MA" };

const AuthProvider = ({ user, initialUser, children }) => {
  // Accepts either a full user object (live mode) or a STAFF id (mock mode).
  let resolved = user;
  if (!resolved) {
    resolved = STAFF.find(s => s.id === initialUser) || MOCK_USER;
  }
  const role = resolved.role;
  const value = {
    user: resolved,
    role,
    roleMeta: ROLES[role] || { id: role, label: role, tier: 0 },
    can: (a) => can(role, a),
    check: (a) => check(role, a),
    maskIP: (ip) => maskIP(ip, role),
    maskGUID: (g) => maskGUID(g, role),
  };
  return <AuthCtx.Provider value={value}>{children}</AuthCtx.Provider>;
};
const useAuth = () => React.useContext(AuthCtx);

// Gated button — disables and adds title-attr tooltip if denied.
const GatedButton = ({ action, children, className = "btn", title, onClick, ...rest }) => {
  const { check } = useAuth();
  const result = check(action);
  const denied = !result.allowed;
  return (
    <button
      className={className}
      onClick={denied ? (e) => e.preventDefault() : onClick}
      disabled={denied}
      title={denied ? result.reason : title}
      style={denied ? { opacity: 0.45, cursor: "not-allowed" } : undefined}
      {...rest}
    >
      {children}
    </button>
  );
};

Object.assign(window, { ROLES, STAFF, PERMS, check, can, maskIP, maskGUID, AuthProvider, useAuth, GatedButton });
