import { useAtomValue } from "@effect/atom-react";
import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";

import { orgMembersAtom } from "../api/account-atoms";
import { useOrganizationId } from "../api/organization-context";
import {
  canCreateWorkspaceConnectionsForHost,
  isTenantAdminMember,
  type TenantMemberRow,
} from "../lib/admin-access";
import type { ShellNavItem } from "./shell";

// ---------------------------------------------------------------------------
// Admin-only nav items.
//
// The console has no role on the session (`/account/me` returns a user and an
// organization, no role), so the current member's role is read off the member
// list — the same derivation cloud's org page already uses for its danger zone.
// Hosts pass their admin-only entries through this hook, which drops them for
// anyone the list doesn't show as an active admin/owner.
//
// This hides a section; it does not protect one. The page behind each item
// renders a denied state off the server's own 401/403, which is the gate that
// matters. Failing closed here is deliberate: while the member list is loading
// or unavailable, showing nothing is better than flashing a section that will
// refuse.
//
// That fail-closed default is also what makes this hook SSR-safe. `orgMembersAtom`
// carries an explicit server value (see `api/account-atoms`), so on the server it
// reads as initial without evaluating — the role is simply UNKNOWN during SSR,
// which lands on `false` here and resolves client-side once the list arrives.
// The hook must never suspend or throw: it runs above the routed outlet, so
// anything it raises takes down the whole server-rendered document.
// ---------------------------------------------------------------------------

/** Whether the current member reads as an admin/owner of this tenant. */
export const useIsTenantAdmin = (): boolean => {
  const members = useAtomValue(orgMembersAtom);
  return AsyncResult.match(members, {
    onInitial: () => false,
    onFailure: () => false,
    onSuccess: ({ value }) => isTenantAdminMember(value.members as readonly TenantMemberRow[]),
  });
};

/** Whether this host and active role allow adding Workspace credentials.
 * Personal connection creation is available to every active member. */
export const useCanCreateWorkspaceConnections = (): boolean => {
  const organizationId = useOrganizationId();
  const isAdmin = useIsTenantAdmin();
  return canCreateWorkspaceConnectionsForHost(organizationId, isAdmin);
};

/**
 * Append admin-only nav items to a host's nav, for admins only.
 *
 * Takes both lists so hosts keep one nav definition and the ordering stays
 * theirs — the admin entries land wherever the host places the call.
 */
export const useAdminNavItems = (
  base: ReadonlyArray<ShellNavItem>,
  adminOnly: ReadonlyArray<ShellNavItem>,
): ReadonlyArray<ShellNavItem> => {
  const isAdmin = useIsTenantAdmin();
  return isAdmin ? [...base, ...adminOnly] : base;
};
