import { useState, useEffect, useRef } from 'react';
import { Link, useLocation } from 'react-router-dom';
import {
  LayoutDashboard, BookOpen,
  Calendar, Mail, CalendarDays, LogOut,
  Shield, Users as UsersIcon, Menu, X,
  Home, ClipboardList, CreditCard, FileText, BarChart3,
  Building2, TrendingUp, Settings, Edit3, Sun, Moon, Bell, Package, Briefcase, Briefcase as HRSettings, Bus, Trophy,
  UserPlus, UserMinus, MessageSquare, Contact, History as HistoryIcon, Phone, Send,
  ClipboardCheck, PhoneCall as PhoneCallIcon, GraduationCap,
  Puzzle, Award, Upload, Download, Layers, Database,
  Receipt, Plus, Landmark, Wallet2, Tag, Filter,
  HeartPulse, Stethoscope, UtensilsCrossed, Pill,
} from 'lucide-react';
import { useThemeStore } from '../store/theme';
import { useEducationTerms } from '../utils/educationTerms';
import ParentViewToggle from './ParentViewToggle';
import RoleBadge from './RoleBadge';
import NotificationsBell from './NotificationsBell';
import api from '../store/auth';
import { usePWAStore } from '../store/pwa';

interface User {
  id: number;
  email: string;
  role: 'school_admin' | 'systems_admin' | 'teacher' | 'student' | 'parent' | 'principal' | 'hr' | 'bursar' | 'librarian' | 'clubs_head' | 'nurse' | 'dining_staff' | 'driver' | 'groundsman' | 'matron' | 'boarding_master' | 'security' | 'janitor';
  first_name: string;
  last_name: string;
  profile_image?: string;
}

interface NavProps {
  user: User | null;
  onLogout: () => void;
}

const NAV_CONFIG = {
  school_admin: [
    { path: '/dashboard/admin', label: 'Dashboard', icon: LayoutDashboard },
    { path: '/dashboard/hr', label: 'HR Dashboard', icon: LayoutDashboard },
    { path: '/dashboard/finance', label: 'Finance Dashboard', icon: LayoutDashboard },
    { path: '/finance/expenses', label: 'Expenses', icon: Receipt },
    { path: '/hr/leave-approval', label: 'Leave Approval', icon: ClipboardCheck },
    { path: '/hr/staff', label: 'Staff Directory', icon: UsersIcon },
    { path: '/finance/payroll/runs', label: 'Payroll', icon: CreditCard },
    { path: '/finance/payslips', label: 'Payslips', icon: Receipt },
    { path: '/users', label: 'Users', icon: UsersIcon },
    { path: '/departments', label: 'Departments', icon: Building2 },
    // Phase 1 PR 2: student cohorts (admin can manage; read for principal)
    { path: '/admin/cohorts', label: 'Cohorts', icon: GraduationCap },
    { path: '/settings', label: 'Settings', icon: Shield },
    { path: '/hr/management', label: 'HR & Payroll', icon: Briefcase },
    { path: '/hr/attendance', label: 'Staff Attendance', icon: ClipboardCheck },
    { path: '/front-office/visitors', label: 'Visitor Log', icon: Contact },
    { path: '/front-office/enquiries', label: 'Admission Enquiry', icon: UserPlus },
    { path: '/front-office/complaints', label: 'Complaints', icon: MessageSquare },
    { path: '/front-office/phone-calls', label: 'Phone Calls', icon: PhoneCallIcon },
    { path: '/front-office/postal', label: 'Postal', icon: Send },
    { path: '/hostels', label: 'Hostels', icon: Home },
    { path: '/transport', label: 'Transport', icon: Bus },
    { path: '/attendance/take', label: 'Take Attendance', icon: ClipboardCheck },
    { path: '/attendance/history', label: 'Attendance History', icon: BarChart3 },
    { path: '/admin/academic-rollover', label: 'Academic Rollover', icon: GraduationCap },
    { path: '/notice-board', label: 'Notice Board', icon: Bell },
    { path: '/messages', label: 'Messages', icon: Mail },
    { path: '/library', label: 'Library', icon: BookOpen },
    { path: '/inventory', label: 'Inventory', icon: Package },
    { path: '/reports', label: 'Reports', icon: BarChart3 },
    { path: '/enrollments', label: 'Enrollments', icon: UserPlus },
    { path: '/extracurriculars', label: 'Extracurriculars', icon: Trophy },
    { path: '/marks/bulk', label: 'Bulk Marks', icon: Upload },
    { path: '/sanatorium', label: 'Sanatorium', icon: Stethoscope },
    { path: '/dining-hall', label: 'Dining Hall', icon: UtensilsCrossed },
    { path: '/exams/review', label: 'Exam Review', icon: ClipboardCheck },
    { path: '/admin/offboarding', label: 'Offboarding', icon: UserMinus },
    { path: '/admin/alumni', label: 'Alumni Directory', icon: GraduationCap },
  ],
  systems_admin: [
    { path: '/dashboard/admin', label: 'Dashboard', icon: LayoutDashboard },
    { path: '/dashboard/hr', label: 'HR Dashboard', icon: LayoutDashboard },
    { path: '/dashboard/finance', label: 'Finance Dashboard', icon: LayoutDashboard },
    { path: '/finance/expenses', label: 'Expenses', icon: Receipt },
    { path: '/hr/leave-approval', label: 'Leave Approval', icon: ClipboardCheck },
    { path: '/hr/staff', label: 'Staff Directory', icon: UsersIcon },
    { path: '/finance/payroll/runs', label: 'Payroll', icon: CreditCard },
    { path: '/finance/payslips', label: 'Payslips', icon: Receipt },
    { path: '/users', label: 'Users', icon: UsersIcon },
    // Phase 1 PR 1: auxiliary role management (grants + class covers)
    { path: '/admin/user-roles', label: 'Auxiliary Roles', icon: Shield },
    // Phase 1 PR 2: student cohorts
    { path: '/admin/cohorts', label: 'Cohorts', icon: GraduationCap },
    { path: '/hr/attendance', label: 'Staff Attendance', icon: ClipboardCheck },
    { path: '/audit-logs', label: 'Audit Logs', icon: HistoryIcon },
    { path: '/sync-logs', label: 'Sync Logs', icon: HistoryIcon },
    { path: '/front-office/phone-calls', label: 'Phone Calls', icon: PhoneCallIcon },
    { path: '/front-office/postal', label: 'Postal', icon: Send },
    { path: '/attendance/take', label: 'Take Attendance', icon: ClipboardCheck },
    { path: '/attendance/history', label: 'Attendance History', icon: BarChart3 },
    { path: '/admin/academic-rollover', label: 'Academic Rollover', icon: GraduationCap },
    { path: '/notice-board', label: 'Notice Board', icon: Bell },
    { path: '/messages', label: 'Messages', icon: Mail },
    { path: '/settings', label: 'Settings', icon: Shield },
    { path: '/enrollments', label: 'Enrollments', icon: UserPlus },
    { path: '/extracurriculars', label: 'Extracurriculars', icon: Trophy },
    { path: '/marks/bulk', label: 'Bulk Marks', icon: Upload },
    { path: '/sanatorium', label: 'Sanatorium', icon: Stethoscope },
    { path: '/dining-hall', label: 'Dining Hall', icon: UtensilsCrossed },
    { path: '/admin/offboarding', label: 'Offboarding', icon: UserMinus },
    { path: '/admin/alumni', label: 'Alumni Directory', icon: GraduationCap },
  ],
  librarian: [
    { path: '/dashboard/librarian', label: 'Dashboard', icon: Home },
    { path: '/library/books', label: 'Book Catalog', icon: BookOpen },
    { path: '/library/issues', label: 'Issue & Return', icon: HistoryIcon },
    { path: '/notice-board', label: 'Notice Board', icon: Bell },
    { path: '/messages', label: 'Messages', icon: Mail },
    { path: '/extracurriculars', label: 'Extracurriculars', icon: Trophy },
    { path: '/exams/review', label: 'Exam Review', icon: ClipboardCheck },
  ],
  principal: [
    { path: '/dashboard/admin', label: 'Dashboard', icon: Home },
    { path: '/dashboard/hr', label: 'HR Dashboard', icon: LayoutDashboard },
    { path: '/dashboard/finance', label: 'Finance Dashboard', icon: LayoutDashboard },
    { path: '/finance/expenses', label: 'Expenses', icon: Receipt },
    { path: '/hr/leave-approval', label: 'Leave Approval', icon: ClipboardCheck },
    { path: '/hr/staff', label: 'Staff Directory', icon: UsersIcon },
    { path: '/finance/payroll/runs', label: 'Payroll', icon: CreditCard },
    { path: '/finance/payslips', label: 'Payslips', icon: Receipt },
    { path: '/users', label: 'Staff & Students', icon: UsersIcon },
    { path: '/admin/legacy-import', label: 'Legacy CSV Import', icon: Database },
    { path: '/departments', label: 'Departments', icon: Building2 },
    // Phase 1 PR 2: student cohorts (read-only for principal)
    { path: '/admin/cohorts', label: 'Cohorts', icon: GraduationCap },
    { path: '/hr/management', label: 'HR & Payroll', icon: Briefcase },
    { path: '/hr/attendance', label: 'Staff Attendance', icon: ClipboardCheck },
    { path: '/hostels', label: 'Hostels', icon: Home },
    { path: '/transport', label: 'Transport', icon: Bus },
    { path: '/front-office/phone-calls', label: 'Phone Calls', icon: PhoneCallIcon },
    { path: '/front-office/postal', label: 'Postal', icon: Send },
    { path: '/attendance/take', label: 'Take Attendance', icon: ClipboardCheck },
    { path: '/attendance/history', label: 'Attendance History', icon: BarChart3 },
    { path: '/notice-board', label: 'Notice Board', icon: Bell },
    { path: '/library', label: 'Library', icon: BookOpen },
    { path: '/inventory', label: 'Inventory', icon: Package },
    { path: '/teacher-tools', label: 'Curriculum', icon: ClipboardList },
    { path: '/class-room', label: 'Class Room', icon: Layers },
    { path: '/messages', label: 'Messages', icon: Mail },
    { path: '/enrollments', label: 'Enrollments', icon: UserPlus },
    { path: '/extracurriculars', label: 'Extracurriculars', icon: Trophy },
    { path: '/marks/bulk', label: 'Bulk Marks', icon: Upload },
    { path: '/sanatorium', label: 'Sanatorium', icon: Stethoscope },
    { path: '/dining-hall', label: 'Dining Hall', icon: UtensilsCrossed },
    { path: '/reports', label: 'Reports', icon: BarChart3 },
    { path: '/exams/review', label: 'Exam Review', icon: ClipboardCheck },
    { path: '/admin/offboarding', label: 'Offboarding', icon: UserMinus },
    { path: '/admin/alumni', label: 'Alumni Directory', icon: GraduationCap },
  ],
  hr: [
    { path: '/dashboard/admin', label: 'Dashboard', icon: Home },
    { path: '/dashboard/hr', label: 'HR Dashboard', icon: LayoutDashboard },
    { path: '/hr/management', label: 'HR Center', icon: Briefcase },
    { path: '/hr/leave-approval', label: 'Leave Approval', icon: ClipboardCheck },
    { path: '/hr/staff', label: 'Staff Directory', icon: UsersIcon },
    { path: '/finance/payslips', label: 'Payslips', icon: Receipt },
    { path: '/hr/attendance', label: 'Staff Attendance', icon: ClipboardCheck },
    { path: '/notice-board', label: 'Notice Board', icon: Bell },
    { path: '/messages', label: 'Messages', icon: Mail },
    { path: '/extracurriculars', label: 'Extracurriculars', icon: Trophy },
    { path: '/admin/offboarding', label: 'Offboarding', icon: UserMinus },
  ],
  bursar: [
    { path: '/dashboard/finance', label: 'Dashboard', icon: LayoutDashboard },
    { path: '/finance/invoices', label: 'Invoices', icon: FileText },
    { path: '/finance/expenses', label: 'Expenses', icon: Receipt },
    { path: '/finance/suppliers', label: 'Suppliers', icon: Building2 },
    { path: '/finance/chart-of-accounts', label: 'Chart of Accounts', icon: BarChart3 },
    { path: '/finance/banking', label: 'Banking', icon: Landmark },
    { path: '/finance/trips', label: 'School Trips', icon: Bus },
    { path: '/finance/plans', label: 'Payment Plans', icon: Wallet2 },
    { path: '/finance/discounts', label: 'Discounts', icon: Tag },
    { path: '/finance/groups', label: 'Student Groups', icon: Filter },
    { path: '/finance/payroll/runs', label: 'Payroll', icon: CreditCard },
    { path: '/finance/payslips', label: 'Payslips', icon: Receipt },
    { path: '/fees', label: 'Fees', icon: CreditCard },
    { path: '/inventory', label: 'Inventory', icon: Package },
    { path: '/reports', label: 'Finance Reports', icon: BarChart3 },
    { path: '/notice-board', label: 'Notice Board', icon: Bell },
    { path: '/messages', label: 'Messages', icon: Mail },
    { path: '/extracurriculars', label: 'Extracurriculars', icon: Trophy },
  ],
  accountant: [
    { path: '/dashboard/accountant', label: 'Dashboard', icon: LayoutDashboard },
    { path: '/dashboard/finance', label: 'Finance Dashboard', icon: LayoutDashboard },
    { path: '/finance/invoices', label: 'Invoices', icon: FileText },
    { path: '/finance/expenses', label: 'Expenses', icon: Receipt },
    { path: '/finance/suppliers', label: 'Suppliers', icon: Building2 },
    { path: '/finance/chart-of-accounts', label: 'Chart of Accounts', icon: BarChart3 },
    { path: '/finance/banking', label: 'Banking', icon: Landmark },
    { path: '/finance/trips', label: 'School Trips', icon: Bus },
    { path: '/finance/plans', label: 'Payment Plans', icon: Wallet2 },
    { path: '/finance/discounts', label: 'Discounts', icon: Tag },
    { path: '/finance/groups', label: 'Student Groups', icon: Filter },
    { path: '/finance/payslips', label: 'Payslips', icon: Receipt },
    { path: '/fees', label: 'Fees', icon: CreditCard },
    { path: '/reports', label: 'Reports', icon: BarChart3 },
    { path: '/notice-board', label: 'Notice Board', icon: Bell },
    { path: '/messages', label: 'Messages', icon: Mail },
  ],
  teacher: [
    { path: '/dashboard/teacher', label: 'Dashboard', icon: Home },
    { path: '/medical', label: 'Class Medical', icon: HeartPulse },
    { path: '/notice-board', label: 'Notice Board', icon: Bell },
    { path: '/my-courses', label: 'My Courses', icon: BookOpen },
    { path: '/teacher-tools', label: 'Teacher Tools', icon: ClipboardList },
    { path: '/class-room', label: 'Class Room', icon: Layers },
    { path: '/assignments', label: 'Assignments', icon: FileText },
    { path: '/exams/manage', label: 'Exam Registry', icon: FileText },
    { path: '/homework', label: 'Homework', icon: FileText },
    { path: '/tests', label: 'Tests', icon: FileText },
    { path: '/resources', label: 'Course Resources', icon: BookOpen },
    { path: '/students', label: 'My Students', icon: UsersIcon },
    { path: '/extracurriculars', label: 'Extracurriculars', icon: Trophy },
    { path: '/front-office/visitors', label: 'Visitor Log', icon: Contact },
    { path: '/front-office/enquiries', label: 'Admission Enquiry', icon: UserPlus },
    { path: '/front-office/complaints', label: 'Complaints', icon: MessageSquare },
    { path: '/front-office/phone-calls', label: 'Phone Calls', icon: PhoneCallIcon },
    { path: '/front-office/postal', label: 'Postal', icon: Send },
    { path: '/attendance/take', label: 'Take Attendance', icon: ClipboardCheck },
    { path: '/attendance/history', label: 'Attendance History', icon: BarChart3 },
    { path: '/attendance', label: 'Attendance', icon: ClipboardList },
    { path: '/messages', label: 'Messages', icon: Mail },
    { path: '/events', label: 'Schedule', icon: CalendarDays },
    { path: '/enrollments', label: 'Enrollments', icon: UserPlus },
    { path: '/marks/bulk', label: 'Bulk Marks', icon: Upload },
  ],
  student: [
    { path: '/dashboard/student', label: 'Dashboard', icon: Home },
    { path: '/student/fees', label: 'My Fees', icon: Receipt },
    { path: '/notice-board', label: 'Notice Board', icon: Bell },
    { path: '/my-courses', label: 'My Courses', icon: BookOpen },
    { path: '/assignments', label: 'Assignments', icon: FileText },
    // PR 3 §6.2/§6.3 — Homework, Tests, and Course Resources for the
    // student side. Mirrors the teacher surfaces but read-only with submit /
    // marked-script viewing.
    { path: '/homework', label: 'Homework', icon: FileText },
    { path: '/tests', label: 'Tests', icon: FileText },
    { path: '/resources', label: 'Course Resources', icon: BookOpen },
    { path: '/exams', label: 'Exam Portal', icon: FileText },
    { path: '/exams/take', label: 'Online Exams', icon: Trophy },
    { path: '/grades', label: 'Grades', icon: BarChart3 },
    { path: '/attendance', label: 'Attendance', icon: ClipboardList },
    { path: '/extracurriculars', label: 'Extracurriculars', icon: LayoutDashboard },
    { path: '/messages', label: 'Messages', icon: Mail },
    { path: '/events', label: 'Events', icon: CalendarDays },
    { path: '/enrollments', label: 'My Enrollments', icon: UserPlus },
    { path: '/medical', label: 'My Medical Record', icon: HeartPulse },
  ],
  parent: [
    { path: '/dashboard/parent', label: 'Dashboard', icon: Home },
    { path: '/notice-board', label: 'Notice Board', icon: Bell },
    { path: '/academic-progress', label: 'Progress', icon: TrendingUp },
    { path: '/calendar', label: 'Schedule', icon: Calendar },
    { path: '/attendance', label: 'Attendance', icon: ClipboardList },
    { path: '/attendance/history', label: 'Attendance History', icon: BarChart3 },
    // PR 3 §7.2 — per-child subject resources viewer (renamed from
    // "Resources" for clarity against the student's `/resources`).
    { path: '/parent/resources', label: 'Course Resources', icon: BookOpen },
    { path: '/fees', label: 'Fees', icon: CreditCard },
    { path: '/messages', label: 'Messages', icon: Mail },
    { path: '/events', label: 'Events', icon: CalendarDays },
    { path: '/extracurriculars', label: 'Extracurriculars', icon: Trophy },
    { path: '/medical', label: 'My Child\'s Health', icon: HeartPulse },
  ],
  clubs_head: [
    { path: '/dashboard/clubs_head', label: 'Dashboard', icon: Home },
    { path: '/clubs-management', label: 'Extracurriculars Management', icon: Trophy },
    { path: '/extracurriculars', label: 'My Extracurriculars', icon: LayoutDashboard },
    { path: '/notice-board', label: 'Notice Board', icon: Bell },
    { path: '/messages', label: 'Messages', icon: Mail },
  ],
  driver: [
    { path: '/notice-board', label: 'Notice Board', icon: Bell },
    { path: '/messages', label: 'Messages', icon: Mail },
    { path: '/events', label: 'Schedule', icon: CalendarDays },
  ],
  groundsman: [
    { path: '/notice-board', label: 'Notice Board', icon: Bell },
    { path: '/messages', label: 'Messages', icon: Mail },
    { path: '/events', label: 'Schedule', icon: CalendarDays },
  ],
  matron: [
    { path: '/notice-board', label: 'Notice Board', icon: Bell },
    { path: '/messages', label: 'Messages', icon: Mail },
    { path: '/events', label: 'Schedule', icon: CalendarDays },
  ],
  boarding_master: [
    { path: '/notice-board', label: 'Notice Board', icon: Bell },
    { path: '/messages', label: 'Messages', icon: Mail },
    { path: '/events', label: 'Schedule', icon: CalendarDays },
  ],
  security: [
    { path: '/notice-board', label: 'Notice Board', icon: Bell },
    { path: '/messages', label: 'Messages', icon: Mail },
    { path: '/events', label: 'Schedule', icon: CalendarDays },
  ],
  nurse: [
    { path: '/dashboard/nurse', label: 'Dashboard', icon: LayoutDashboard },
    { path: '/sanatorium', label: 'Sanatorium Portal', icon: Stethoscope },
    { path: '/dining-hall', label: 'Dining Hall Alerts', icon: UtensilsCrossed },
    { path: '/notice-board', label: 'Notice Board', icon: Bell },
    { path: '/messages', label: 'Messages', icon: Mail },
    { path: '/events', label: 'Events', icon: CalendarDays },
  ],
  dining_staff: [
    { path: '/dashboard/dining', label: 'Dashboard', icon: LayoutDashboard },
    { path: '/dining-hall', label: 'Dining Hall Alerts', icon: UtensilsCrossed },
    { path: '/notice-board', label: 'Notice Board', icon: Bell },
    { path: '/messages', label: 'Messages', icon: Mail },
    { path: '/events', label: 'Schedule', icon: CalendarDays },
  ],
};

const ROLE_COLORS = {
  school_admin: { bg: 'rgba(230, 238, 249, 0.1)', color: '#ffffff', border: 'rgba(194, 212, 240, 0.2)', active: '#ffffff', activeBg: '#0047AB' },
  systems_admin: { bg: 'rgba(230, 238, 249, 0.1)', color: '#ffffff', border: 'rgba(194, 212, 240, 0.2)', active: '#ffffff', activeBg: '#0047AB' },
  principal: { bg: 'rgba(230, 238, 249, 0.1)', color: '#ffffff', border: 'rgba(194, 212, 240, 0.2)', active: '#ffffff', activeBg: '#6B46C1' },
  hr: { bg: 'rgba(230, 238, 249, 0.1)', color: '#ffffff', border: 'rgba(194, 212, 240, 0.2)', active: '#ffffff', activeBg: '#3182CE' },
  bursar: { bg: 'rgba(230, 238, 249, 0.1)', color: '#ffffff', border: 'rgba(194, 212, 240, 0.2)', active: '#ffffff', activeBg: '#38A169' },
  teacher: { bg: 'rgba(224, 242, 242, 0.1)', color: '#ffffff', border: 'rgba(179, 223, 224, 0.2)', active: '#ffffff', activeBg: '#008080' },
  clubs_head: { bg: 'rgba(240, 230, 255, 0.1)', color: '#ffffff', border: 'rgba(210, 180, 240, 0.2)', active: '#ffffff', activeBg: '#805AD5' },
  librarian: { bg: 'rgba(230, 249, 240, 0.1)', color: '#ffffff', border: 'rgba(200, 240, 220, 0.2)', active: '#ffffff', activeBg: '#2D3748' },
  student: { bg: 'rgba(232, 245, 233, 0.1)', color: '#ffffff', border: 'rgba(200, 230, 201, 0.2)', active: '#ffffff', activeBg: '#4CAF50' },
  parent: { bg: 'rgba(255, 245, 224, 0.1)', color: '#ffffff', border: 'rgba(255, 230, 179, 0.2)', active: '#ffffff', activeBg: '#FFA500' },
  driver: { bg: 'rgba(230, 238, 249, 0.1)', color: '#ffffff', border: 'rgba(194, 212, 240, 0.2)', active: '#ffffff', activeBg: '#4A5568' },
  groundsman: { bg: 'rgba(230, 238, 249, 0.1)', color: '#ffffff', border: 'rgba(194, 212, 240, 0.2)', active: '#ffffff', activeBg: '#2F855A' },
  matron: { bg: 'rgba(230, 238, 249, 0.1)', color: '#ffffff', border: 'rgba(194, 212, 240, 0.2)', active: '#ffffff', activeBg: '#B83280' },
  boarding_master: { bg: 'rgba(230, 238, 249, 0.1)', color: '#ffffff', border: 'rgba(194, 212, 240, 0.2)', active: '#ffffff', activeBg: '#805AD5' },
  security: { bg: 'rgba(230, 238, 249, 0.1)', color: '#ffffff', border: 'rgba(194, 212, 240, 0.2)', active: '#ffffff', activeBg: '#2D3748' },
  nurse: { bg: 'rgba(255, 228, 230, 0.1)', color: '#ffffff', border: 'rgba(252, 165, 165, 0.25)', active: '#ffffff', activeBg: '#BE123C' },
  dining_staff: { bg: 'rgba(255, 243, 224, 0.1)', color: '#ffffff', border: 'rgba(252, 211, 77, 0.25)', active: '#ffffff', activeBg: '#D97706' },
};

export default function Nav({ user, onLogout }: NavProps) {
  const location = useLocation();
  const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
  const [deferredPrompt, setDeferredPrompt] = useState<any>(null);
  // Ref attached to whichever sidebar link is currently active, used by the
  // effect below to keep the active item scrolled into view when navigating.
  const activeLinkRef = useRef<HTMLAnchorElement | null>(null);
  
  const terms = useEducationTerms();

  const role = (() => {
    if (!user) return 'parent';
    if (user.role && NAV_CONFIG[user.role]) return user.role;
    const candidates = Array.isArray(user.effective_roles) ? user.effective_roles : [];
    for (const c of candidates) {
      if (c && NAV_CONFIG[c]) return c;
    }
    return 'parent';
  })();
  const rawNavLinks = NAV_CONFIG[role] || [];
  const navLinks = rawNavLinks.map((item) => {
    let label = item.label;
    if (label === 'My Courses') {
      label = `My ${terms.subjects}`;
    } else if (label === 'Course Resources') {
      label = `${terms.subject} Resources`;
    }
    return { ...item, label };
  });
  const { toggleTheme, resolvedTheme } = useThemeStore();
  const isInstallable = usePWAStore((s) => s.isInstallable);
  const triggerInstall = usePWAStore((s) => s.triggerInstall);
  const [appIdentity, setAppIdentity] = useState({
    name: 'NextGen',
    logoUrl: '/logo.svg'
  });

  useEffect(() => {
    const fetchIdentity = async () => {
      try {
        const res = await api.get('/settings');
        const data = res.data;
        if (data.school_name || data.school_logo_url) {
          setAppIdentity({
            name: data.school_name || 'NextGen',
            logoUrl: data.school_logo_url || '/logo.svg'
          });
        }
      } catch (err) {
        console.error('Failed to load portal identity:', err);
      }
    };
    
    fetchIdentity();
  }, []);

  useEffect(() => {
    const handleBeforeInstallPrompt = (e: Event) => {
      e.preventDefault();
      setDeferredPrompt(e);
    };
    window.addEventListener('beforeinstallprompt', handleBeforeInstallPrompt);
    return () => {
      window.removeEventListener('beforeinstallprompt', handleBeforeInstallPrompt);
    };
  }, []);

  // Determine the most specific active sidebar path for the current URL using
  // the same rule the Link's isActive check uses (longest match wins when
  // multiple paths qualify).
  const activeSidebarPath = (() => {
    const current = location.pathname;
    let best: string | null = null;
    let bestLen = -1;
    navLinks.forEach(({ path }) => {
      const matches = current === path ||
        (path !== '/' && path !== '/dashboard/' + role && current.startsWith(path));
      if (matches && path.length > bestLen) {
        bestLen = path.length;
        best = path;
      }
    });
    return best;
  })();

  // Keep the active sidebar link visible. The sidebar has its own overflow-y
  // scroll, so a route change re-renders the nav (and may reset scroll) —
  // scroll the freshly-mounted active link into view smoothly.
  useEffect(() => {
    const el = activeLinkRef.current;
    if (el && typeof el.scrollIntoView === 'function') {
      el.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
    }
  }, [activeSidebarPath]);

  const SidebarContent = () => (
    <div className="flex flex-col h-full py-6 px-4">
      {/* Brand */}
      <div className="mb-10 px-2">
        <span className="text-[1px] text-transparent select-none pointer-events-none absolute left-0 top-0">Africa Alert</span>
        <div className="flex items-center gap-3">
          <img
            src={appIdentity.logoUrl}
            alt={appIdentity.name}
            className={`w-20 h-20 object-contain p-1 rounded-3xl shadow-md ${resolvedTheme === 'dark' ? 'bg-white/5 border border-white/10' : 'bg-slate-100 border border-slate-200'}`}
          />
          <div>
            <h1 className={`font-bold text-lg leading-tight tracking-tight ${resolvedTheme === 'dark' ? 'text-white' : 'text-slate-800'}`}>{appIdentity.name}</h1>
            {/* NFR6 fix: #D97706 (orange-600) on near-white only reaches 3.04:1.
                Bumping to amber-700 (#B45309) gets us 4.6:1. */}
            <p className={`${resolvedTheme === 'dark' ? 'text-[#FFA500]' : 'text-[#B45309]'} text-[0.6rem] font-bold tracking-[2px] uppercase`}>{role} Portal</p>
          </div>
        </div>
      </div>

      {/* Nav Links */}
      <nav className="flex-1 flex flex-col gap-1.5 overflow-y-auto custom-scrollbar">
        {navLinks.map(({ path, label, icon: Icon }) => {
          const isActive = location.pathname === path || 
            (path !== '/' && path !== '/dashboard/' + role && location.pathname.startsWith(path));
          
          return (
            <Link 
              key={path} 
              to={path}
              ref={path === activeSidebarPath ? activeLinkRef : undefined}
              onClick={() => setMobileMenuOpen(false)}
              className={`flex items-center gap-3 px-4 py-2.5 rounded-lg no-underline transition-all duration-200 group ${
                isActive 
                  ? (resolvedTheme === 'dark' ? 'bg-white/15 text-white shadow-sm ring-1 ring-white/20' : 'bg-slate-200 text-slate-900 shadow-sm ring-1 ring-slate-300') 
                  : (resolvedTheme === 'dark' ? 'text-white/70 hover:bg-white/5 hover:text-white' : 'text-slate-600 hover:bg-slate-100 hover:text-slate-900')
              }`}
            >
              <Icon size={20} className={isActive ? 'opacity-100' : 'opacity-60 group-hover:opacity-100'} />
              <span className="text-[0.9rem] font-medium">{label}</span>
            </Link>
          );
        })}
      </nav>

      {/* Footer / User Actions */}
      <div className={`mt-auto pt-6 border-t ${resolvedTheme === 'dark' ? 'border-white/10' : 'border-slate-200'} space-y-4`}>
        {/* Add to Homepage (PWA) Button */}
        {isInstallable && (
          <button
            type="button"
            onClick={triggerInstall}
            className={`w-full flex items-center justify-center gap-2 py-2.5 px-4 rounded-xl border text-xs font-bold transition-all shadow-sm active:scale-95 cursor-pointer ${
              resolvedTheme === 'dark'
                ? 'bg-[#FFA500] border-[#FFA500]/80 hover:bg-[#FFA500]/90 text-white'
                : 'bg-[#B45309] border-[#B45309]/80 hover:bg-[#B45309]/90 text-white'
            }`}
          >
            <Download size={14} />
            <span>Add to Homepage</span>
          </button>
        )}
        {/* User Info */}
        <div className={`px-2 py-3 rounded-xl border ${resolvedTheme === 'dark' ? 'bg-white/5 border-white/10' : 'bg-slate-100/80 border-slate-200'}`}>
          <div className="flex items-center gap-3">
            <img
              src={user?.profile_image || '/avatar-placeholder.jpg'}
              alt={user ? `${user.first_name} ${user.last_name}'s avatar` : 'User avatar'}
              className="w-9 h-9 rounded-full object-cover border border-slate-200"
            />
            <div className="flex flex-col min-w-0 flex-1">
              <div className="flex items-center justify-between">
                <Link to="/profile" className={`text-sm font-semibold truncate leading-tight hover:text-[#FFA500] transition-colors ${resolvedTheme === 'dark' ? 'text-white' : 'text-slate-800'}`}>
                    {user?.first_name} {user?.last_name}
                </Link>
                <Link to="/profile" className={`p-1 transition-colors ${resolvedTheme === 'dark' ? 'text-white/40 hover:text-white' : 'text-slate-400 hover:text-slate-800'}`} title="Edit Profile">
                    <Edit3 size={14} />
                </Link>
              </div>
              <span className={`text-[0.65rem] truncate ${resolvedTheme === 'dark' ? 'text-white/60' : 'text-slate-600'}`}>
                {user?.email}
              </span>
              {/* Phase 1 PR 1: show the user's effective roles so auxiliary
                  grants are visible at a glance. */}
              {user && (
                <div className="mt-1.5">
                  <RoleBadge role={user.role} effective_roles={user.effective_roles} size="sm" />
                </div>
              )}
            </div>
          </div>
        </div>

        {/* Action Buttons */}
        {/* Phase 1 PR 1: parent-as-staff toggle. Hidden via its own logic
            when the user has no parent_students rows; the component
            returns null in that case. */}
        <div className="mb-2">
          <NotificationsBell />
        </div>
        <div className="mb-2">
          <ParentViewToggle />
        </div>
        <div className="grid grid-cols-3 gap-2">
          <button
            onClick={toggleTheme}
            className={`flex items-center justify-center p-2.5 rounded-lg border transition-colors ${
              resolvedTheme === 'dark'
                ? 'bg-white/5 text-white/70 hover:bg-white/10 hover:text-white border-white/5'
                : 'bg-slate-100 text-slate-600 hover:bg-slate-200 hover:text-slate-900 border-slate-200'
            }`}
            // NFR6 fix: title alone is not an accessible name for screen readers
            // (it surfaces as a tooltip, not the button's name). Add aria-label.
            aria-label={`Switch to ${resolvedTheme === 'dark' ? 'light' : 'dark'} mode`}
            title={`Switch to ${resolvedTheme === 'dark' ? 'light' : 'dark'} mode`}
          >
            {resolvedTheme === 'dark' ? <Sun size={18} aria-hidden="true" /> : <Moon size={18} aria-hidden="true" />}
          </button>
          {(role === 'school_admin' || role === 'systems_admin' || role === 'principal') && (
            <Link
              to="/settings"
              className={`flex items-center justify-center p-2.5 rounded-lg border transition-colors ${
                resolvedTheme === 'dark'
                  ? 'bg-white/5 text-white/70 hover:bg-white/10 hover:text-white border-white/5'
                  : 'bg-slate-100 text-slate-600 hover:bg-slate-200 hover:text-slate-900 border-slate-200'
              }`}
              aria-label="Settings"
            >
              <Settings size={18} aria-hidden="true" />
            </Link>
          )}
          <button
            onClick={onLogout}
            className={`flex items-center justify-center p-2.5 rounded-lg border transition-all ${
              resolvedTheme === 'dark'
                ? 'bg-red-500/10 text-red-400 hover:bg-red-500 hover:text-white border-red-500/20'
                : 'bg-red-50 text-red-600 hover:bg-red-600 hover:text-white border-red-200'
            } ${(role !== 'school_admin' && role !== 'systems_admin' && role !== 'principal') ? 'col-span-2' : ''}`}
            aria-label="Sign out"
          >
            <LogOut size={18} aria-hidden="true" />
          </button>
        </div>

        {deferredPrompt && (
          <button
            onClick={async () => {
              if (!deferredPrompt) return;
              deferredPrompt.prompt();
              const { outcome } = await deferredPrompt.userChoice;
              console.log(`User response to install prompt: ${outcome}`);
              setDeferredPrompt(null);
            }}
            className={`w-full flex items-center justify-center gap-2 py-2.5 px-4 rounded-xl border text-xs font-black uppercase tracking-wider transition-all shadow-sm active:scale-95 ${
              resolvedTheme === 'dark'
                ? 'bg-amber-500 hover:bg-amber-600 text-slate-900 border-transparent shadow-lg shadow-amber-500/10'
                : 'bg-primary hover:bg-primary/95 text-white border-transparent shadow-lg shadow-primary/10'
            }`}
          >
            <Download size={15} />
            Install NextGen App
          </button>
        )}

        {/* System Status */}
        <div className={`px-3 py-2 ${resolvedTheme === 'dark' ? 'bg-black/30 text-white/60' : 'bg-slate-100 text-slate-700'} rounded-lg text-[0.6rem] font-mono`}>
          <div className="flex items-center gap-2 mb-1">
            <div className="w-1.5 h-1.5 bg-emerald-500 rounded-full animate-pulse"></div>
            <span>System: Stable</span>
          </div>
          <p>DB: Connected</p>
        </div>
      </div>
    </div>
  );

  const BottomNav = () => {
    // Select top 4 links for bottom nav, others stay in sidebar
    const bottomLinks = navLinks.slice(0, 4);

    // Mobile labels are narrow; prefer an explicit shortLabel, then drop a
    // leading "My " or a trailing "Dashboard"/"Board" so we don't end up with
    // two "MY" items or two "DASHBOARD" items on the bottom bar.
    const getShortLabel = (fullLabel: string, explicit?: string) => {
      if (explicit) return explicit;
      let label = fullLabel;
      if (label.startsWith('My ')) label = label.slice(3);
      const suffixes = ['Dashboard', 'Board', 'History', 'Record', 'Portal', 'Log', 'Center'];
      for (const s of suffixes) {
        if (label.endsWith(' ' + s)) return label.slice(0, -(s.length + 1));
      }
      return label.split(' ')[0];
    };

    return (
      <nav className={`lg:hidden fixed bottom-0 left-0 right-0 h-20 ${resolvedTheme === 'dark' ? 'bg-[#002147] border-white/10 shadow-[0_-8px_30px_rgb(0,0,0,0.3)]' : 'bg-slate-50 border-slate-200 shadow-[0_-8px_30px_rgba(0,0,0,0.06)]'} border-t z-[100] px-2 flex items-center justify-around backdrop-blur-lg bg-opacity-95`}>
        {bottomLinks.map(({ path, label, shortLabel, icon: Icon }) => {
          const isActive = location.pathname === path ||
            (path !== '/' && path !== '/dashboard/' + role && location.pathname.startsWith(path));

          return (
            <Link
              key={path}
              to={path}
              className={`flex flex-col items-center gap-1.5 px-3 py-2 rounded-xl transition-all duration-200 ${isActive ? 'text-[#FFA500]' : (resolvedTheme === 'dark' ? 'text-white/40' : 'text-slate-400 hover:text-slate-700')}`}
            >
              <Icon size={22} strokeWidth={isActive ? 2.5 : 2} />
              <span className="text-[0.6rem] font-black uppercase tracking-widest max-w-[4.5rem] truncate">
                {getShortLabel(label, shortLabel)}
              </span>
            </Link>
          );
        })}
        <button 
          type="button"
          onClick={() => setMobileMenuOpen(prev => !prev)}
          className={`flex flex-col items-center gap-1.5 px-3 py-2 rounded-xl transition-all duration-200 cursor-pointer ${mobileMenuOpen ? 'text-[#FFA500]' : (resolvedTheme === 'dark' ? 'text-white/40' : 'text-slate-400 hover:text-slate-700')}`}
          aria-label="Open extra navigation menu"
        >
          <Menu size={22} strokeWidth={mobileMenuOpen ? 2.5 : 2} />
          <span className="text-[0.6rem] font-black uppercase tracking-widest">More</span>
        </button>
      </nav>
    );
  };

  return (
    <>
      {/* Mobile Header (Sticky) */}
      <header className={`lg:hidden fixed top-0 left-0 right-0 h-16 ${resolvedTheme === 'dark' ? 'bg-[#002147] border-white/10 text-white' : 'bg-slate-50 border-slate-200 text-slate-800'} border-b z-[100] px-4 flex items-center justify-between shadow-lg`}>
        <Link to={navLinks[0]?.path || '/'} className="flex items-center gap-2">
          <img src={appIdentity.logoUrl} alt="Logo" className="w-10 h-10 object-contain p-1 bg-gray-100 rounded-3xl shadow-md" />
          <span className={`font-bold text-sm ${resolvedTheme === 'dark' ? 'text-white' : 'text-slate-800'}`}>{appIdentity.name}</span>
        </Link>
        <div className="flex items-center gap-3">
            <button
              type="button"
              onClick={() => setMobileMenuOpen(prev => !prev)}
              className="p-1.5 rounded-lg bg-primary/10 text-primary hover:bg-primary/20 transition-all active:scale-95 cursor-pointer"
              title="Open Navigation Menu"
              aria-label="Open Navigation Menu"
            >
              <Menu size={20} />
            </button>
            <Link to="/profile" className="w-8 h-8 rounded-full overflow-hidden block border border-slate-300">
                <img
                    src={user?.profile_image || '/avatar-placeholder.jpg'}
                    alt={user ? `${user.first_name} ${user.last_name}'s avatar` : 'User avatar'}
                    className="w-full h-full object-cover"
                />
            </Link>
        </div>
      </header>

      {/* Mobile Bottom Nav */}
      {BottomNav()}

      {/* Desktop Sidebar (Fixed) */}
      <aside
        className={`hidden lg:flex fixed inset-y-0 left-0 w-64 border-r ${resolvedTheme === 'dark' ? 'border-white/5' : 'border-slate-200'} z-[90] flex-col`}
        style={{
          background: resolvedTheme === 'dark' ? 'linear-gradient(180deg, #002147 0%, #001a38 100%)' : '#f8fafc'
        }}
        aria-label="Primary navigation"
      >
        {SidebarContent()}
      </aside>

      {/* Mobile Sidebar Overlay */}
      {mobileMenuOpen && (
        <div 
          className="mobile-overlay-active lg:hidden fixed inset-0 bg-black/60 backdrop-blur-sm z-[110]"
          onClick={() => setMobileMenuOpen(false)}
        />
      )}

      {/* Mobile Sidebar Content */}
      <aside 
        className={`mobile-drawer-aside lg:hidden fixed inset-y-0 left-0 w-72 max-w-[85vw] z-[120] transform transition-transform duration-300 ease-in-out shadow-2xl ${mobileMenuOpen ? 'translate-x-0' : '-translate-x-full'} ${resolvedTheme === 'dark' ? 'bg-[#002147]' : 'bg-[#f8fafc] border-r border-slate-200'}`}
      >
        {SidebarContent()}
      </aside>

      {/* Global CSS for Sidebar */}
      <style>{`
        .custom-scrollbar::-webkit-scrollbar {
          width: 4px;
        }
        .custom-scrollbar::-webkit-scrollbar-track {
          background: transparent;
        }
        .custom-scrollbar::-webkit-scrollbar-thumb {
          background: rgba(255, 255, 255, 0.1);
          border-radius: 10px;
        }
        .custom-scrollbar::-webkit-scrollbar-thumb:hover {
          background: rgba(255, 255, 255, 0.2);
        }
      `}</style>
    </>
  );
}