import { getAuthRoleLabel } from '@/business/auth/selectors';
import { hasAnyPermission } from '@/business/auth/permissions';
import { getModuleByRoutePath } from '@/shared/constants/moduleRoutes';
import type { ScopeTier } from '@/business/scope/selectors';
import type { CampusInfo, Module, ModuleId, UserRole } from '@/shared/types/app';
import type { CurrentUser } from '@/shared/types/auth';

export function getAccessibleModules(
  modules: readonly Module[],
  user: CurrentUser | null | undefined,
): readonly Module[] {
  return modules.filter((module) => hasAnyPermission(user, module.permissions));
}

const ALL_STAFF_TIERS: readonly ScopeTier[] = [
  'organization',
  'school',
  'campus',
  'class',
];

/**
 * The scope tiers at which each module appears in the sidebar. Layered on top of
 * permission access: a module shows only if the user has one of its required
 * permissions AND the
 * effective scope tier (own, or a drilled-into tenant) is listed here. Modules
 * not listed default to all staff tiers.
 */
const MODULE_SCOPE_TIERS: Partial<Record<ModuleId, readonly ScopeTier[]>> = {
  'platform-dashboard': ['global'],
  // Organization/location management: visible at manager scopes.
  'organization-management': ['global', 'organization', 'school', 'campus'],
  'user-admin': ['global', 'organization', 'school', 'campus'],
  class: ['class'],
  classroom: ['organization', 'school', 'campus', 'class'],
  timer: ['class'],
  qbs: ['organization', 'campus', 'class'],
  // Leadership dashboard: each leader sees it at their own tier (owner/
  // superintendent → organization, principal/registrar → school, director →
  // campus). Never shown via drill-down (see getScopedModules).
  director: ['organization', 'school', 'campus'],
  'parent-comm': ['school', 'campus', 'class', 'external'],
  esa: ['school', 'campus', 'class', 'external'],
  walkthrough: ['organization', 'school', 'campus'],
  'internal-comm': ['global', ...ALL_STAFF_TIERS],
  community: [...ALL_STAFF_TIERS, 'external'],
  vocational: [...ALL_STAFF_TIERS, 'external'],
};

/**
 * Sidebar modules for the user, scoped to the effective tier (own tier, or the
 * tenant they have drilled into). The Director Dashboard is the campus
 * director's own page and is never shown via drill-down.
 */
export function getScopedModules(
  modules: readonly Module[],
  user: CurrentUser | null | undefined,
  effectiveTier: ScopeTier,
  isDrilled: boolean,
): readonly Module[] {
  return getAccessibleModules(modules, user).filter((module) => {
    const tiers = MODULE_SCOPE_TIERS[module.id] ?? ALL_STAFF_TIERS;
    if (!tiers.includes(effectiveTier)) {
      return false;
    }
    if (module.id === 'director' && isDrilled) {
      return false;
    }
    return true;
  });
}

export function canAccessScopedModuleRoute(
  modules: readonly Module[],
  pathname: string,
  user: CurrentUser | null | undefined,
  effectiveTier: ScopeTier,
  isDrilled: boolean,
): boolean {
  const module = getModuleByRoutePath(pathname);
  if (!module) return true;
  return getScopedModules(modules, user, effectiveTier, isDrilled)
    .some((allowed) => allowed.id === module.id);
}

export function getScopedModuleRouteRedirectPath(
  modules: readonly Module[],
  pathname: string,
  user: CurrentUser | null | undefined,
  effectiveTier: ScopeTier,
  isDrilled: boolean,
): string | null {
  const currentModule = getModuleByRoutePath(pathname);
  if (!currentModule) return null;

  const scopedModules = getScopedModules(modules, user, effectiveTier, isDrilled);
  if (scopedModules.some((module) => module.id === currentModule.id)) {
    return null;
  }

  return scopedModules[0]?.routePath ?? null;
}

/** Role-specific name for the shared leadership dashboard (`director` module). */
const LEADERSHIP_DASHBOARD_LABELS: Partial<Record<UserRole, string>> = {
  owner: 'Owner Dashboard',
  superintendent: 'Superintendent Dashboard',
  principal: 'Principal Dashboard',
  registrar: 'Registrar Dashboard',
  director: 'Director Dashboard',
};

export function getLeadershipDashboardName(role: UserRole): string {
  return LEADERSHIP_DASHBOARD_LABELS[role] ?? 'Leadership Dashboard';
}

/**
 * Rewrites the shared leadership dashboard's sidebar label so each role sees its
 * own name (Owner Dashboard, Principal Dashboard, …) rather than the generic
 * "Director Dashboard".
 */
export function withRoleAwareModuleNames(
  modules: readonly Module[],
  role: UserRole,
): readonly Module[] {
  return modules.map((module) =>
    module.id === 'director'
      ? { ...module, name: getLeadershipDashboardName(role) }
      : module,
  );
}

export function canAccessModule(
  modules: readonly Module[],
  moduleId: ModuleId,
  user: CurrentUser | null | undefined,
): boolean {
  const module = modules.find((item) => item.id === moduleId);
  return module ? hasAnyPermission(user, module.permissions) : false;
}

export function getAccessibleModuleId(
  modules: readonly Module[],
  moduleId: ModuleId,
  user: CurrentUser | null | undefined,
): ModuleId {
  return canAccessModule(modules, moduleId, user) ? moduleId : 'dashboard';
}

export function getSidebarRoleLabel(role: UserRole): string {
  return getAuthRoleLabel(role);
}

export function getSidebarCampusInitial(campusInfo?: CampusInfo): string | null {
  const mascot = campusInfo?.mascot.trim();

  if (!mascot) {
    return null;
  }

  return mascot.charAt(0).toUpperCase();
}

export function shouldShowMobileSidebarOverlay(isMobile: boolean, mobileSidebarOpen: boolean): boolean {
  return isMobile && mobileSidebarOpen;
}
