import ForbiddenError from '@/shared/errors/forbidden';
import type { CurrentUser } from '@/db/api/types';

/**
 * Shared tenant/role access helpers used by the feature services. Centralizes
 * the (previously copy-pasted) organization/campus/role checks so every module
 * resolves scope and access the same way.
 */

export function getOrganizationId(currentUser?: CurrentUser): string | null {
  return currentUser?.organizations?.id || currentUser?.organizationId || null;
}

export function getCampusId(currentUser?: CurrentUser): string | null {
  const staff = currentUser?.staff_user;
  if (Array.isArray(staff) && staff[0]?.campusId) {
    return staff[0].campusId;
  }
  return currentUser?.campusId || null;
}

export function getRoleName(
  currentUser?: CurrentUser,
): string | null | undefined {
  return currentUser?.app_role?.name;
}

/** Human-friendly name for the current user (full name, else email, else generic). */
export function getDisplayName(currentUser?: CurrentUser): string {
  const firstName = currentUser?.firstName || '';
  const lastName = currentUser?.lastName || '';
  const fullName = `${firstName} ${lastName}`.trim();

  return fullName || currentUser?.email || 'Staff Member';
}

/** organizationId is a NOT NULL column; callers guard authentication first. */
export function requireOrganizationId(currentUser?: CurrentUser): string {
  const organizationId = getOrganizationId(currentUser);
  if (!organizationId) {
    throw new ForbiddenError();
  }
  return organizationId;
}

/** True if the user has global access (e.g. SuperAdmin, superintendent). */
export function hasGlobalAccess(currentUser?: CurrentUser): boolean {
  return currentUser?.app_role?.globalAccess === true;
}

/**
 * Returns organizationId for filtering, or null if user has global access.
 * Throws ForbiddenError if user has neither global access nor organizationId.
 */
export function getOrganizationIdOrGlobal(
  currentUser?: CurrentUser,
): string | null {
  if (hasGlobalAccess(currentUser)) {
    return null;
  }
  const organizationId = getOrganizationId(currentUser);
  if (!organizationId) {
    throw new ForbiddenError();
  }
  return organizationId;
}

export function requireUserId(currentUser?: CurrentUser): string {
  if (!currentUser?.id) {
    throw new ForbiddenError();
  }
  return currentUser.id;
}

export function assertAuthenticatedTenantUser(currentUser?: CurrentUser): void {
  if (!currentUser?.id) {
    throw new ForbiddenError();
  }
  if (hasGlobalAccess(currentUser) || getOrganizationId(currentUser)) {
    return;
  }
  throw new ForbiddenError();
}

/** True if the user has global access or holds one of the given role names. */
export function hasRoleAccess(
  currentUser: CurrentUser | undefined,
  roleNames: readonly string[],
): boolean {
  const roleName = getRoleName(currentUser);
  return (
    currentUser?.app_role?.globalAccess === true ||
    roleNames.some((name) => name === roleName)
  );
}

/**
 * Restricts users who are not tenant-wide to their own campus. Tenant-wide roles
 * (or global access) see everything.
 */
export function campusScope(
  currentUser: CurrentUser | undefined,
  tenantWideRoleNames: readonly string[],
): { campusId?: string } {
  if (hasRoleAccess(currentUser, tenantWideRoleNames)) {
    return {};
  }
  const campusId = getCampusId(currentUser);
  return campusId ? { campusId } : {};
}
