import { Head, Link, router, usePage } from "@inertiajs/react";
import { useEffect, useRef, useState, type ReactNode } from "react";
import type { Shared } from "../types";
import { Alert, Button, Errors, Icon } from "./ui";
export default function Shell({
    title,
    children,
    context,
}: {
    title: string;
    children: ReactNode;
    context?: string;
}) {
    const { auth, permissions, school, roles, flash } = usePage<Shared>().props;
    const current = usePage().url;
    const path = current.split("?")[0];
    const isActive = (url: string) =>
        url.includes("?")
            ? current === url
            : (path === url ||
                  (url === "/students" && path.startsWith("/students/"))) &&
              (!url.startsWith("/classes") ||
                  !new URLSearchParams(current.split("?")[1]).has("view"));
    const [menu, setMenu] = useState(false);
    const [busy, setBusy] = useState(false);
    const drawer = useRef<HTMLDialogElement>(null);
    const has = (p: string) => permissions.includes(p);
    const student = auth?.user_type === "student";
    useEffect(() => {
        const start = router.on("start", () => setBusy(true));
        const finish = router.on("finish", () => setBusy(false));
        return () => {
            start();
            finish();
        };
    }, []);
    useEffect(() => {
        if (menu) drawer.current?.showModal();
        else drawer.current?.close();
    }, [menu]);
    const role = student
        ? "Student"
        : (roles[auth?.assignments[0]?.role ?? ""]?.label ?? "Staff");
    const initials = auth?.name
        .split(" ")
        .slice(0, 2)
        .map((s) => s[0])
        .join("");
    const links = [
        { url: "/", label: "Overview", icon: "dashboard", show: true },
        {
            url: "/setup",
            label: "School setup",
            icon: "settings",
            show: has("setup.manage"),
        },
        {
            url: "/enrollments",
            label: student ? "My COR" : "Enrollments",
            icon: "clipboard",
            show:
                student ||
                has("enrollment.manage") ||
                has("enrollment.batch.manage"),
        },
        {
            url: "/students",
            label: "Students",
            icon: "users",
            show: has("student.view"),
        },
        {
            url: "/credits",
            label: "Transfer credits",
            icon: "graduation",
            show: has("enrollment.manage"),
        },
        {
            url: "/finance",
            label: "Financial clearance",
            icon: "calculator",
            show: has("finance.record"),
        },
        {
            url: "/classes",
            label: student
                ? "My subjects"
                : has("class.teach")
                  ? "My classes"
                  : "Subject Classes",
            icon: "book",
            show: student || has("class.teach") || has("class.read"),
        },
        {
            url: "/classes?view=final-grades",
            label: "Final grades",
            icon: "clipboard",
            show: has("class.teach"),
        },
        {
            url: "/schedule",
            label: student ? "My schedule" : "Schedules",
            icon: "folder",
            show:
                student ||
                has("class.teach") ||
                has("class.read") ||
                has("setup.manage"),
        },
        {
            url: "/sections",
            label: "Sections",
            icon: "users",
            show:
                has("setup.manage") || has("section.end") || has("class.read"),
        },
        {
            url: "/capacity",
            label: "Capacity exceptions",
            icon: "clipboard",
            show: has("capacity.approve"),
        },
        {
            url: "/users",
            label: "Users and access",
            icon: "users",
            show: has("users.manage"),
        },
        {
            url: "/reports",
            label: "Reports",
            icon: "chart",
            show: permissions.some((p) => p.startsWith("report.")),
        },
    ].filter((l) => l.show);
    const sidebar = (
        <>
            <Link href="/" className="brand">
                <Icon name="book" />
                {school}
            </Link>
            <span className="small strong muted">{role} workspace</span>
            <span className="small muted">
                {auth?.assignments[0]?.branch?.name ?? "School workspace"}
            </span>
            <nav aria-label="Main navigation">
                {links.map((l) => (
                    <Link
                        key={l.url}
                        href={l.url}
                        onClick={() => setMenu(false)}
                        aria-current={isActive(l.url) ? "page" : undefined}
                        className={`nav-item ${isActive(l.url) ? "active" : ""}`}
                    >
                        <Icon name={l.icon} />
                        {l.label}
                    </Link>
                ))}
            </nav>
            <div className="account">
                <div className="person">
                    <span className="avatar">{initials}</span>
                    <div>
                        {auth?.name}
                        <small>{role}</small>
                    </div>
                </div>
                <Link href="/password" className="account-link">
                    Change password
                </Link>
                <Link
                    href="/logout"
                    method="post"
                    as="button"
                    className="nav-item"
                >
                    <Icon name="logout" />
                    Sign out
                </Link>
            </div>
        </>
    );
    return (
        <>
            <Head title={title} />
            <a className="skip-link" href="#main">
                Skip to content
            </a>
            <div className="app-shell">
                <aside className="sidebar">{sidebar}</aside>
                <dialog
                    className="mobile-drawer"
                    ref={drawer}
                    onCancel={() => setMenu(false)}
                >
                    <Button
                        type="button"
                        variant="ghost"
                        onClick={() => setMenu(false)}
                    >
                        Close menu
                    </Button>
                    {sidebar}
                </dialog>
                <div className="app-body">
                    <header className="topbar">
                        <Button
                            variant="ghost"
                            className="mobile-only"
                            aria-label="Open menu"
                            onClick={() => setMenu(true)}
                        >
                            <Icon name="menu" />
                        </Button>
                        <div>
                            <strong>{context ?? school}</strong>
                            <small>
                                {student ? "Student workspace" : role} ·{" "}
                                {auth?.assignments[0]?.branch?.name ??
                                    "School-wide access"}
                            </small>
                        </div>
                        <span className="avatar" title={auth?.name}>
                            {initials}
                        </span>
                    </header>
                    <main
                        id="main"
                        className="main"
                        tabIndex={-1}
                        aria-busy={busy}
                    >
                        {flash.success && (
                            <Alert title={flash.success} tone="success" />
                        )}
                        <Errors />
                        {children}
                    </main>
                </div>
            </div>
            {busy && (
                <div className="navigation-status" role="status">
                    <span className="spinner" /> Loading…
                </div>
            )}
        </>
    );
}
