import { Link } from '@inertiajs/react';
import { ExternalLink, Menu } from 'lucide-react';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { DocsContent } from '@/components/docs/docs-content';
import { DocsPageHeader } from '@/components/docs/docs-page-header';
import { DocsSidebarNav } from '@/components/docs/docs-sidebar';
import { DocsToc } from '@/components/docs/docs-toc';
import { Button } from '@/components/ui/button';
import {
    Sheet,
    SheetContent,
    SheetHeader,
    SheetTitle,
    SheetTrigger,
} from '@/components/ui/sheet';
import { getTopLevelSectionCards } from '@/docs/navigation';
import { docsUrl } from '@/docs/urls';
import type { DocPage } from '@/docs/types';
import { useDocsScrollSpy } from '@/hooks/use-docs-scroll-spy';
import type { UserRole } from '@/types/auth';
import { DocsCard } from '@/components/docs/docs-card';

type Props = {
    page: DocPage | null;
    role?: UserRole;
};

function DocsHome({ role }: { role?: UserRole }) {
    const cards = getTopLevelSectionCards(role);

    return (
        <div>
            <header className="mb-10 space-y-3 border-b border-border pb-8">
                <h1 className="text-3xl font-semibold tracking-tight text-foreground">
                    Staff documentation
                </h1>
                <p className="max-w-2xl text-base leading-relaxed text-muted-foreground">
                    Learn what each part of the app does and when to use it.
                    Pick a topic below or use the sidebar to browse.
                </p>
            </header>
            <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
                {cards.map((card) => (
                    <DocsCard
                        key={card.slug}
                        title={card.title}
                        description={card.description}
                        slug={card.slug}
                    />
                ))}
            </div>
        </div>
    );
}

export function DocsLayout({ page, role }: Props) {
    const [mobileOpen, setMobileOpen] = useState(false);
    const sidebarScrollRef = useRef<HTMLDivElement>(null);
    const mobileSidebarScrollRef = useRef<HTMLDivElement>(null);
    const currentSlug = page?.slug ?? '';
    const sectionIds = useMemo(
        () => page?.sections.map((section) => section.id) ?? [],
        [page?.sections],
    );
    const activeSectionId = useDocsScrollSpy(sectionIds);

    const resetSidebarScroll = useCallback(() => {
        sidebarScrollRef.current?.scrollTo({ top: 0, behavior: 'smooth' });
        mobileSidebarScrollRef.current?.scrollTo({ top: 0, behavior: 'smooth' });
    }, []);

    useEffect(() => {
        resetSidebarScroll();
        window.scrollTo({ top: 0, behavior: 'smooth' });
    }, [currentSlug, resetSidebarScroll]);

    const handleSidebarNavigate = useCallback(() => {
        resetSidebarScroll();
        setMobileOpen(false);
    }, [resetSidebarScroll]);

    return (
        <div className="flex min-h-[calc(100vh-12rem)] flex-col gap-6 lg:flex-row lg:items-start lg:gap-10">
            <div className="lg:hidden">
                <Sheet open={mobileOpen} onOpenChange={setMobileOpen}>
                    <SheetTrigger asChild>
                        <Button variant="outline" size="sm" className="gap-2">
                            <Menu className="size-4" />
                            Browse docs
                        </Button>
                    </SheetTrigger>
                    <SheetContent side="left" className="w-[min(100%,20rem)] p-0">
                        <SheetHeader className="border-b border-border p-4">
                            <SheetTitle>Documentation</SheetTitle>
                        </SheetHeader>
                        <div
                            ref={mobileSidebarScrollRef}
                            className="max-h-[calc(100vh-8rem)] overflow-y-auto overscroll-contain p-4"
                        >
                            <DocsSidebarNav
                                currentSlug={currentSlug}
                                onNavigate={handleSidebarNavigate}
                            />
                        </div>
                    </SheetContent>
                </Sheet>
            </div>

            <aside className="hidden w-60 shrink-0 self-start lg:block">
                <div
                    ref={sidebarScrollRef}
                    className="sticky top-20 max-h-[calc(100vh-6rem)] overflow-y-auto overscroll-contain"
                >
                    <DocsSidebarNav
                        currentSlug={currentSlug}
                        onNavigate={resetSidebarScroll}
                    />
                </div>
            </aside>

            <main className="min-w-0 flex-1">
                {page ? (
                    <>
                        <div className="mb-4 flex flex-wrap items-center justify-end gap-2">
                            {page.relatedAppRoute ? (
                                <Button variant="outline" size="sm" asChild>
                                    <Link
                                        href={page.relatedAppRoute}
                                        className="gap-2"
                                    >
                                        Open in app
                                        <ExternalLink className="size-3.5" />
                                    </Link>
                                </Button>
                            ) : null}
                        </div>
                        <DocsPageHeader
                            title={page.title}
                            description={page.description}
                            roles={page.roles}
                        />
                        <DocsContent sections={page.sections} />
                    </>
                ) : (
                    <DocsHome role={role} />
                )}
            </main>

            {page ? (
                <DocsToc
                    sections={page.sections}
                    activeId={activeSectionId}
                />
            ) : null}
        </div>
    );
}
