import { useMemo } from 'react';
import { useAuth } from '@/context/auth';
import { APP_ROLES, ADMIN_ROLE_CODES, isAdminRoleCode, type AdminRoleCode } from '@/constants';

/**
 * The set of admin consoles the current principal may act on. **UI hint only** — the server enforces
 * every command's role scope (a `support` admin who forges a payout request still 403s). We derive it so
 * the shell never *shows* a control the current role can't use (phase §3 "Routing & RBAC", §5).
 *
 * The matrix mirrors the product's five worklists (verification / refund / payout / support-alert / RBAC)
 * plus the config/holiday/audit/moderation/partner surfaces, keyed off the fine-grained role codes:
 *  - `super_admin` — everything (only role that may grant/revoke roles).
 *  - `admin`       — everything except role management.
 *  - `finance`     — refunds, payouts, config, audit.
 *  - `support`     — verification, support-alerts, tickets.
 *  - `moderation`  — review moderation.
 */
export interface AdminCapabilities {
  /** True when the principal holds any admin role at all (drives whether the console is reachable). */
  isAdmin: boolean;
  canVerify: boolean;
  canRefund: boolean;
  canPayout: boolean;
  canModerate: boolean;
  canConfig: boolean;
  canManageAlerts: boolean;
  canManageTickets: boolean;
  canManagePartners: boolean;
  canViewAudit: boolean;
  canManageRoles: boolean;
  /** The effective fine-grained roles used for the matrix (post dev-fallback). */
  roles: AdminRoleCode[];
}

const has = (roles: AdminRoleCode[], ...allowed: AdminRoleCode[]) => roles.some((r) => allowed.includes(r));

/**
 * Reads the session's fine-grained `roleCodes` (hydrated from `/me` by `useSessionRoleSync`). When a
 * session is coarse-admin (mock auth, or `/me` not yet fine-hydrated) but carries no admin code, we fall
 * back to a plain `admin` so the console is usable in dev — never `super_admin`, so the roles screen stays
 * correctly hidden. This is a display convenience; authorization is always the server's.
 */
export function useAdminCapabilities(): AdminCapabilities {
  const [state] = useAuth();

  return useMemo<AdminCapabilities>(() => {
    const user = state.currentUser;
    const coarseAdmin = !!user?.roles?.includes(APP_ROLES.ADMIN);
    let roles = (user?.roleCodes ?? []).filter(isAdminRoleCode);
    if (roles.length === 0 && coarseAdmin) roles = ['admin'];

    const isAdmin = roles.length > 0;
    return {
      isAdmin,
      canVerify: has(roles, 'super_admin', 'admin', 'support'),
      canRefund: has(roles, 'super_admin', 'admin', 'finance'),
      canPayout: has(roles, 'super_admin', 'admin', 'finance'),
      canModerate: has(roles, 'super_admin', 'admin', 'moderation'),
      canConfig: has(roles, 'super_admin', 'admin', 'finance'),
      canManageAlerts: has(roles, 'super_admin', 'admin', 'support'),
      canManageTickets: has(roles, 'super_admin', 'admin', 'support'),
      canManagePartners: has(roles, 'super_admin', 'admin'),
      canViewAudit: has(roles, 'super_admin', 'admin'),
      canManageRoles: has(roles, 'super_admin'),
      roles,
    };
  }, [state.currentUser]);
}

/** The full ordered admin role-code list — for the (deferred) RBAC grid + any role picker. */
export { ADMIN_ROLE_CODES };
