"use client";

import Link from "next/link";
import { usePathname } from "next/navigation";
import { useState, type ReactNode } from "react";
import clsx from "clsx";
import {
  Building2,
  ClipboardList,
  FileSpreadsheet,
  GraduationCap,
  LayoutDashboard,
  ListChecks,
  LogOut,
  Menu,
  Settings,
  ShieldCheck,
  Upload,
  Users,
  X,
} from "lucide-react";
import { signOutAction } from "@/app/actions/auth";
import { ROLE_SHORT_LABELS } from "@/components/status";
import type { Permission } from "@/lib/auth/permissions";
import type { Role } from "@/types";

export interface NavItem {
  href: string;
  label: string;
  icon: keyof typeof ICONS;
  permission: Permission;
}

const ICONS = {
  dashboard: LayoutDashboard,
  students: Users,
  curriculum: ListChecks,
  imports: Upload,
  reports: FileSpreadsheet,
  audit: ClipboardList,
  settings: Settings,
  users: ShieldCheck,
  programs: Building2,
} as const;

export function AppShell({
  children,
  navItems,
  user,
  institution,
  college,
}: {
  children: ReactNode;
  navItems: NavItem[];
  user: { full_name: string; email: string; role: Role; program_code: string | null; program_name: string | null };
  institution: string;
  college: string;
}) {
  const [mobileOpen, setMobileOpen] = useState(false);

  return (
    <div className="min-h-screen lg:grid lg:grid-cols-[15rem_1fr]">
      {/* Mobile top bar */}
      <div className="sticky top-0 z-30 flex items-center justify-between border-b border-ink-200 bg-white px-4 py-3 lg:hidden">
        <Link href="/dashboard" className="flex items-center gap-2">
          <span className="flex h-8 w-8 items-center justify-center rounded-md bg-brand-600 text-white">
            <GraduationCap className="h-4 w-4" aria-hidden />
          </span>
          <span className="text-sm font-semibold text-ink-900">OCCP System</span>
        </Link>
        <button
          type="button"
          onClick={() => setMobileOpen((open) => !open)}
          className="rounded-md p-2 text-ink-600 hover:bg-ink-100"
          aria-expanded={mobileOpen}
          aria-controls="occp-sidebar"
          aria-label={mobileOpen ? "Close navigation" : "Open navigation"}
        >
          {mobileOpen ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />}
        </button>
      </div>

      <Sidebar
        navItems={navItems}
        user={user}
        institution={institution}
        college={college}
        mobileOpen={mobileOpen}
        onNavigate={() => setMobileOpen(false)}
      />

      <div className="min-w-0">
        <main className="mx-auto w-full max-w-[100rem] px-4 py-6 sm:px-6 lg:px-8 lg:py-8">{children}</main>
      </div>
    </div>
  );
}

function Sidebar({
  navItems,
  user,
  institution,
  college,
  mobileOpen,
  onNavigate,
}: {
  navItems: NavItem[];
  user: { full_name: string; email: string; role: Role; program_code: string | null; program_name: string | null };
  institution: string;
  college: string;
  mobileOpen: boolean;
  onNavigate: () => void;
}) {
  const pathname = usePathname();

  return (
    <aside
      id="occp-sidebar"
      className={clsx(
        "z-20 flex-col border-r border-ink-200 bg-white lg:sticky lg:top-0 lg:flex lg:h-screen",
        mobileOpen ? "flex" : "hidden",
      )}
    >
      <div className="hidden items-center gap-3 border-b border-ink-200 px-5 py-4 lg:flex">
        <span className="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-brand-600 text-white">
          <GraduationCap className="h-5 w-5" aria-hidden />
        </span>
        <div className="min-w-0">
          <p className="truncate text-sm font-semibold leading-tight text-ink-900">OCCP System</p>
          <p className="truncate text-[11px] leading-tight text-ink-500" title={`${institution} — ${college}`}>
            {institution}
          </p>
        </div>
      </div>

      <nav className="flex-1 space-y-0.5 overflow-y-auto p-3" aria-label="Main navigation">
        {navItems.map((item) => {
          const Icon = ICONS[item.icon];
          const active = pathname === item.href || pathname.startsWith(`${item.href}/`);
          return (
            <Link
              key={item.href}
              href={item.href}
              onClick={onNavigate}
              aria-current={active ? "page" : undefined}
              className={clsx(
                "flex items-center gap-2.5 rounded-md px-3 py-2 text-[13px] font-medium transition-colors",
                active ? "bg-brand-50 text-brand-700" : "text-ink-600 hover:bg-ink-100 hover:text-ink-900",
              )}
            >
              <Icon className={clsx("h-4 w-4 shrink-0", active ? "text-brand-600" : "text-ink-400")} aria-hidden />
              {item.label}
            </Link>
          );
        })}
      </nav>

      <div className="border-t border-ink-200 p-3">
        <div className="rounded-lg bg-ink-50 px-3 py-2.5">
          <p className="truncate text-[13px] font-medium text-ink-900" title={user.full_name}>
            {user.full_name}
          </p>
          <p className="truncate text-[11px] text-ink-500" title={user.email}>
            {user.email}
          </p>
          <div className="mt-1.5 flex flex-wrap gap-1">
            <span className="inline-flex rounded-full bg-white px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-brand-700 ring-1 ring-inset ring-brand-200">
              {ROLE_SHORT_LABELS[user.role]}
            </span>
            {/* Which program this account can see — blank means all of them. */}
            <span
              title={user.program_name ?? "This account can see every academic program"}
              className="inline-flex rounded-full bg-white px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-ink-600 ring-1 ring-inset ring-ink-200"
            >
              {user.program_code ?? "All programs"}
            </span>
          </div>
        </div>
        <form action={signOutAction} className="mt-2">
          <button
            type="submit"
            className="flex w-full items-center gap-2 rounded-md px-3 py-2 text-[13px] font-medium text-ink-600 transition-colors hover:bg-ink-100 hover:text-ink-900"
          >
            <LogOut className="h-4 w-4 text-ink-400" aria-hidden />
            Sign out
          </button>
        </form>
      </div>
    </aside>
  );
}
