import type { Permission, SecurityContext } from '@i-learned/core';
import { hasAnyPermission } from '@i-learned/core';

/**
 * Role-aware navigation (SPEC.md §31, §32).
 *
 * Every item declares the permissions that make it relevant, and the sidebar
 * renders only what the user can actually reach. This is a **usability**
 * measure, not a security one: the server-side `authorize()` call in each route
 * is the actual gate, and hiding a link never substitutes for it
 * (SPEC.md §0.9).
 */

export interface NavItem {
  label: string;
  href: string;
  /** Item appears when the user holds any one of these. */
  permissions: readonly Permission[];
  /** Lucide icon name, resolved by the client component. */
  icon: string;
  /** Marks the section's landing page, matched exactly rather than by prefix. */
  exact?: boolean;
}

export interface NavSection {
  label: string;
  items: readonly NavItem[];
}

/**
 * The permission that identifies each office's console.
 *
 * Declared once and used by *both* the sidebar and the page guard, so the two
 * can never drift apart — a link that appears must lead somewhere the user can
 * actually open, and a page the user can open must appear in their navigation.
 *
 * These are deliberately narrow. A permission held for a legitimate
 * cross-office reason must not unlock another office's console: a Cashier holds
 * `enrollment.read` so they can see who owes payment, which is not a reason to
 * show them the Registrar's grade-publication and clearance queues. Each entry
 * therefore names a permission only that office holds.
 *
 * SUPERADMIN bypasses all of this by design, and every such access is audited.
 */
export const CONSOLE_PERMISSIONS = {
  admin: ['user.manage', 'role.manage', 'setting.manage'],
  admissions: ['lead.read', 'application.review'],
  dean: ['pre_registration.approve', 'faculty_load.manage'],
  registrar: ['enrollment.review', 'student.manage'],
  cashier: ['payment.create'],
  faculty: ['grade.encode'],
  student: ['self.profile.read'],
} as const satisfies Record<string, readonly Permission[]>;

const ADMIN_NAV: NavSection = {
  label: 'Administration',
  items: [
    { label: 'Dashboard', href: '/admin/dashboard', permissions: CONSOLE_PERMISSIONS.admin, icon: 'LayoutDashboard', exact: true },
    { label: 'Users', href: '/admin/users', permissions: ['user.read', 'user.manage'], icon: 'Users' },
    { label: 'Roles & permissions', href: '/admin/roles', permissions: ['role.manage'], icon: 'ShieldCheck' },
    { label: 'Settings', href: '/admin/settings', permissions: ['setting.manage'], icon: 'Settings' },
    { label: 'Branding', href: '/admin/branding', permissions: ['branding.manage'], icon: 'Palette' },
    { label: 'Analytics', href: '/admin/analytics', permissions: ['analytics.read'], icon: 'ChartBar' },
    { label: 'Audit log', href: '/admin/audit', permissions: ['audit.read'], icon: 'ScrollText' },
    { label: 'Data imports', href: '/admin/imports', permissions: ['import.manage'], icon: 'Upload' },
  ],
};

const ADMISSIONS_NAV: NavSection = {
  label: 'Admissions',
  items: [
    { label: 'Dashboard', href: '/admissions/dashboard', permissions: CONSOLE_PERMISSIONS.admissions, icon: 'LayoutDashboard', exact: true },
    { label: 'Leads', href: '/admissions/leads', permissions: ['lead.read'], icon: 'UserPlus' },
    { label: 'Applications', href: '/admissions/applications', permissions: ['application.read'], icon: 'FileText' },
    { label: 'Requirements', href: '/admissions/requirements', permissions: ['requirement.read'], icon: 'ClipboardCheck' },
    { label: 'Examinations', href: '/admissions/exams', permissions: ['exam.manage'], icon: 'PencilRuler' },
    { label: 'Follow-ups', href: '/admissions/follow-ups', permissions: ['lead.manage'], icon: 'BellRing' },
  ],
};

const DEAN_NAV: NavSection = {
  label: 'College',
  items: [
    { label: 'Dashboard', href: '/dean/dashboard', permissions: CONSOLE_PERMISSIONS.dean, icon: 'LayoutDashboard', exact: true },
    { label: 'Applicants', href: '/dean/applicants', permissions: ['application.review'], icon: 'Users' },
    { label: 'Interviews', href: '/dean/interviews', permissions: ['interview.evaluate'], icon: 'MessagesSquare' },
    { label: 'Transfer evaluations', href: '/dean/transfer-evaluations', permissions: ['transfer_credit.evaluate'], icon: 'ArrowLeftRight' },
    { label: 'Pre-registration', href: '/dean/pre-registration', permissions: ['pre_registration.approve'], icon: 'ClipboardList' },
    { label: 'Faculty load', href: '/dean/faculty-load', permissions: ['faculty_load.manage'], icon: 'CalendarClock' },
    { label: 'Sections', href: '/dean/sections', permissions: ['section.read'], icon: 'LayoutGrid' },
    { label: 'Grade submissions', href: '/dean/grades', permissions: ['grade.submission.monitor'], icon: 'GraduationCap' },
  ],
};

const REGISTRAR_NAV: NavSection = {
  label: 'Registrar',
  items: [
    { label: 'Dashboard', href: '/registrar/dashboard', permissions: CONSOLE_PERMISSIONS.registrar, icon: 'LayoutDashboard', exact: true },
    { label: 'Students', href: '/registrar/students', permissions: ['student.manage'], icon: 'Users' },
    { label: 'Enrollment', href: '/registrar/enrollment', permissions: ['enrollment.review'], icon: 'ClipboardCheck' },
    { label: 'Courses', href: '/registrar/courses', permissions: ['course.manage'], icon: 'BookOpen' },
    { label: 'Curricula', href: '/registrar/curricula', permissions: ['curriculum.manage'], icon: 'Network' },
    { label: 'Colleges', href: '/admin/colleges', permissions: ['program.manage'], icon: 'Building2' },
    { label: 'Programs', href: '/admin/programs', permissions: ['program.manage'], icon: 'GraduationCap' },
    { label: 'Academic years', href: '/admin/academic-years', permissions: ['academic_year.manage'], icon: 'CalendarRange' },
    { label: 'Transfer credit', href: '/registrar/transfer-credit', permissions: ['enrollment.review'], icon: 'ArrowLeftRight' },
    { label: 'Sections', href: '/registrar/sections', permissions: ['section.manage'], icon: 'LayoutGrid' },
    { label: 'Schedules', href: '/registrar/schedules', permissions: ['section.manage'], icon: 'CalendarClock' },
    { label: 'Grades', href: '/registrar/grades', permissions: ['grade.publish'], icon: 'GraduationCap' },
    { label: 'Document requests', href: '/registrar/requests', permissions: ['document_request.process'], icon: 'FileStack' },
    { label: 'Clearance', href: '/registrar/clearance', permissions: ['clearance.manage'], icon: 'BadgeCheck' },
  ],
};

const CASHIER_NAV: NavSection = {
  label: 'Cashier',
  items: [
    { label: 'Dashboard', href: '/cashier/dashboard', permissions: CONSOLE_PERMISSIONS.cashier, icon: 'LayoutDashboard', exact: true },
    { label: 'Assessments', href: '/cashier/assessments', permissions: ['assessment.read'], icon: 'Receipt' },
    { label: 'Post payment', href: '/cashier/payments', permissions: ['payment.create'], icon: 'Banknote' },
    { label: 'Transactions', href: '/cashier/transactions', permissions: ['payment.read'], icon: 'ArrowLeftRight' },
  ],
};

const FACULTY_NAV: NavSection = {
  label: 'Teaching',
  items: [
    { label: 'Dashboard', href: '/faculty/dashboard', permissions: CONSOLE_PERMISSIONS.faculty, icon: 'LayoutDashboard', exact: true },
    { label: 'My load', href: '/faculty/load', permissions: ['faculty_load.read'], icon: 'CalendarClock' },
    { label: 'My classes', href: '/faculty/classes', permissions: ['section.read'], icon: 'Users' },
    { label: 'Grades', href: '/faculty/grades', permissions: ['grade.encode'], icon: 'GraduationCap' },
  ],
};

const STUDENT_NAV: NavSection = {
  label: 'My records',
  items: [
    { label: 'Dashboard', href: '/student/dashboard', permissions: CONSOLE_PERMISSIONS.student, icon: 'LayoutDashboard', exact: true },
    { label: 'Profile', href: '/student/profile', permissions: ['self.profile.read'], icon: 'UserRound' },
    { label: 'Enrollment', href: '/student/enrollment', permissions: ['self.enrollment.read'], icon: 'ClipboardCheck' },
    { label: 'Schedule', href: '/student/schedule', permissions: ['self.enrollment.read'], icon: 'CalendarClock' },
    { label: 'Grades', href: '/student/grades', permissions: ['self.grade.read'], icon: 'GraduationCap' },
    { label: 'Finance', href: '/student/finance', permissions: ['self.finance.read'], icon: 'Receipt' },
    { label: 'Requests', href: '/student/requests', permissions: ['document_request.create'], icon: 'FileStack' },
    { label: 'Clearance', href: '/student/clearance', permissions: ['clearance.read'], icon: 'BadgeCheck' },
    { label: 'Notifications', href: '/student/notifications', permissions: ['notification.read'], icon: 'Bell' },
  ],
};

/**
 * Sections in the order a user should see them, each with the condition that
 * makes the section relevant at all.
 *
 * Permission alone is not sufficient for the two self-service sections. A
 * Registrar legitimately holds `clearance.read` and `notification.read`, which
 * would otherwise give them a "My records" section pointing at student pages
 * they have no record behind. Self-service belongs to people who actually *are*
 * that thing, so those sections are gated on the corresponding scope.
 */
/**
 * Every section, regardless of who may see it. Exported so a test can assert
 * that each declared link actually leads to a page — a menu item that 404s
 * reads as a broken system rather than an unfinished one.
 */
export const ALL_NAV_SECTIONS: readonly NavSection[] = [
  ADMISSIONS_NAV,
  DEAN_NAV,
  REGISTRAR_NAV,
  CASHIER_NAV,
  FACULTY_NAV,
  STUDENT_NAV,
  ADMIN_NAV,
];

const SECTIONS: ReadonlyArray<{
  section: NavSection;
  /** Extra condition beyond holding one of the item permissions. */
  applies: (ctx: SecurityContext) => boolean;
}> = [
  { section: ADMISSIONS_NAV, applies: () => true },
  { section: DEAN_NAV, applies: (ctx) => ctx.scope.collegeIds.length > 0 || ctx.isSuperAdmin },
  { section: REGISTRAR_NAV, applies: () => true },
  { section: CASHIER_NAV, applies: () => true },
  { section: FACULTY_NAV, applies: (ctx) => ctx.scope.facultyProfileId !== null },
  { section: STUDENT_NAV, applies: (ctx) => ctx.scope.studentId !== null },
  { section: ADMIN_NAV, applies: () => true },
];

/**
 * The sections and items this user can reach.
 *
 * A user with several roles sees several sections, which is the correct
 * behaviour for a Dean who also teaches. Empty sections are dropped.
 */
export function navigationFor(ctx: SecurityContext): NavSection[] {
  return SECTIONS.filter((entry) => entry.applies(ctx))
    .map((entry) => ({
      label: entry.section.label,
      items: entry.section.items.filter((item) => hasAnyPermission(ctx, item.permissions)),
    }))
    .filter((section) => section.items.length > 0);
}

/**
 * Where to send a user after sign-in.
 *
 * Resolved from the console the account actually owns, in order of how specific
 * that identity is — a student lands on their own dashboard even if they
 * somehow also hold a staff permission, and a Dean who teaches lands on their
 * college rather than their class list.
 *
 * Deliberately *not* "the first navigation item": that made a Registrar land on
 * a student page, because they hold `clearance.read` for a completely
 * legitimate reason.
 */
const LANDING_PRIORITY: ReadonlyArray<{
  path: string;
  permissions: readonly Permission[];
  applies?: (ctx: SecurityContext) => boolean;
}> = [
  { path: '/student/dashboard', permissions: CONSOLE_PERMISSIONS.student, applies: (ctx) => ctx.scope.studentId !== null },
  { path: '/dean/dashboard', permissions: CONSOLE_PERMISSIONS.dean, applies: (ctx) => ctx.scope.collegeIds.length > 0 },
  { path: '/faculty/dashboard', permissions: CONSOLE_PERMISSIONS.faculty, applies: (ctx) => ctx.scope.facultyProfileId !== null },
  { path: '/registrar/dashboard', permissions: CONSOLE_PERMISSIONS.registrar },
  { path: '/admissions/dashboard', permissions: CONSOLE_PERMISSIONS.admissions },
  { path: '/cashier/dashboard', permissions: CONSOLE_PERMISSIONS.cashier },
  { path: '/admin/dashboard', permissions: CONSOLE_PERMISSIONS.admin },
];

export function landingPathFor(ctx: SecurityContext): string {
  // A superadmin matches every permission check, so the priority list would
  // otherwise drop them on whichever console happens to sort first. Their home
  // is institutional configuration.
  if (ctx.isSuperAdmin) return '/admin/dashboard';

  for (const candidate of LANDING_PRIORITY) {
    if (candidate.applies && !candidate.applies(ctx)) continue;
    if (hasAnyPermission(ctx, candidate.permissions)) return candidate.path;
  }

  // A signed-in account with no console at all — for example a Dean whose
  // college assignment has been removed. The landing page explains rather than
  // dead-ending on a 404.
  return '/';
}

/**
 * Whether a nav item should render as current.
 *
 * Section landing pages match exactly; everything else matches by prefix so a
 * detail page keeps its parent highlighted.
 */
export function isNavItemActive(item: NavItem, pathname: string): boolean {
  if (item.exact) return pathname === item.href;
  return pathname === item.href || pathname.startsWith(`${item.href}/`);
}
