import Avatar from '@/Components/shared/Avatar';
import Logo from '@/Components/shared/Logo';
import { NoIndex } from '@/Components/shared/Seo';
import ThemeToggle from '@/Components/shared/ThemeToggle';
import { useFlash } from '@/hooks/useFlash';
import { cn } from '@/lib/utils';
import { PageProps } from '@/types';
import { Dialog, DialogPanel, Transition, TransitionChild } from '@headlessui/react';
import { Link, usePage } from '@inertiajs/react';
import { motion } from 'framer-motion';
import { Building2, ExternalLink, Gamepad2, Layers, LayoutDashboard, LogOut, Menu, MessageSquare, Monitor, Tag, Users, X } from 'lucide-react';
import { PropsWithChildren, ReactNode, useState } from 'react';

const buildNav = (): { title?: string; items: { label: string; icon: typeof Tag; href: string; match: string }[] }[] => [
    { items: [{ label: 'Dashboard', icon: LayoutDashboard, href: route('admin.dashboard'), match: 'admin.dashboard' }] },
    { title: 'Content', items: [
        { label: 'Games', icon: Gamepad2, href: route('admin.games.index'), match: 'admin.games.*' },
        { label: 'Reviews', icon: MessageSquare, href: route('admin.reviews.index'), match: 'admin.reviews.*' },
    ] },
    { title: 'People', items: [{ label: 'Users', icon: Users, href: route('admin.users.index'), match: 'admin.users.*' }] },
    { title: 'Catalog data', items: [
        { label: 'Genres', icon: Layers, href: route('admin.terms.index', 'genres'), match: 'admin.terms.*:genres' },
        { label: 'Platforms', icon: Monitor, href: route('admin.terms.index', 'platforms'), match: 'admin.terms.*:platforms' },
        { label: 'Developers & publishers', icon: Building2, href: route('admin.terms.index', 'companies'), match: 'admin.terms.*:companies' },
        { label: 'Tags', icon: Tag, href: route('admin.terms.index', 'tags'), match: 'admin.terms.*:tags' },
    ] },
];

function isActive(match: string, url: string) {
    const [name, term] = match.split(':');
    if (!route().current(name)) return false;
    return term ? url.includes(`/terms/${term}`) : true;
}

function SidebarContent({ onNavigate }: { onNavigate?: () => void }) {
    const page = usePage<PageProps>();
    const user = page.props.auth.user!;
    const NAV = buildNav();
    return (
        <div className="flex h-full flex-col">
            <div className="flex h-14 items-center gap-2 border-b border-border px-4">
                <Link href={route('admin.dashboard')} onClick={onNavigate}><Logo /></Link>
                <span className="rounded-md border border-border px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wider text-muted-foreground">Admin</span>
            </div>
            <nav className="flex-1 space-y-5 overflow-y-auto p-3" aria-label="Admin">
                {NAV.map((g, i) => (
                    <div key={i} className="space-y-0.5">
                        {g.title && <p className="text-overline px-2.5 pb-1.5">{g.title}</p>}
                        {g.items.map((it) => {
                            const active = isActive(it.match, page.url);
                            return (
                                <Link key={it.label} href={it.href} onClick={onNavigate} aria-current={active ? 'page' : undefined} className={cn('group relative flex items-center gap-2.5 rounded-lg px-2.5 py-2 text-sm transition', active ? 'bg-accent text-foreground' : 'text-muted-foreground hover:bg-accent/60 hover:text-foreground')}>
                                    {active && <motion.span layoutId="admin-nav-active" className="absolute inset-y-1.5 left-0 w-0.5 rounded-full bg-primary" />}
                                    <it.icon className="size-4" />{it.label}
                                </Link>
                            );
                        })}
                    </div>
                ))}
            </nav>
            <div className="space-y-1 border-t border-border p-3">
                <Link href={route('home')} className="flex items-center gap-2.5 rounded-lg px-2.5 py-2 text-sm text-muted-foreground transition hover:bg-accent/60 hover:text-foreground"><ExternalLink className="size-4" />View site</Link>
                <div className="flex items-center gap-2.5 px-2.5 py-2">
                    <Avatar name={user.name} src={user.avatar} className="size-7" />
                    <div className="min-w-0 flex-1"><p className="truncate text-sm font-medium">{user.name}</p></div>
                    <ThemeToggle />
                    <Link href={route('logout')} method="post" as="button" aria-label="Log out" className="rounded-lg p-2 text-muted-foreground transition hover:bg-accent hover:text-foreground"><LogOut className="size-4" /></Link>
                </div>
            </div>
        </div>
    );
}

export default function AdminLayout({ title, children }: PropsWithChildren<{ title?: ReactNode }>) {
    const [open, setOpen] = useState(false);
    const page = usePage();
    useFlash();

    return (
        <div className="min-h-screen">
            <NoIndex />
            <aside className="glass fixed inset-y-0 left-0 z-30 hidden w-60 border-r border-border lg:block"><SidebarContent /></aside>

            <Transition show={open}>
                <Dialog onClose={() => setOpen(false)} className="relative z-50 lg:hidden">
                    <TransitionChild enter="duration-200" enterFrom="opacity-0" enterTo="opacity-100" leave="duration-150" leaveFrom="opacity-100" leaveTo="opacity-0"><div className="fixed inset-0 bg-black/60 backdrop-blur-sm" aria-hidden /></TransitionChild>
                    <TransitionChild enter="duration-250 ease-out" enterFrom="-translate-x-full" enterTo="translate-x-0" leave="duration-150 ease-in" leaveFrom="translate-x-0" leaveTo="-translate-x-full">
                        <DialogPanel className="fixed inset-y-0 left-0 w-72 border-r border-border bg-popover shadow-lift">
                            <button onClick={() => setOpen(false)} aria-label="Close menu" className="absolute right-3 top-3 z-10 rounded-lg p-2 text-muted-foreground hover:bg-accent"><X className="size-4" /></button>
                            <SidebarContent onNavigate={() => setOpen(false)} />
                        </DialogPanel>
                    </TransitionChild>
                </Dialog>
            </Transition>

            <div className="lg:pl-60">
                <div className="glass sticky top-0 z-20 flex h-14 items-center gap-3 border-b border-border px-4 lg:hidden">
                    <button onClick={() => setOpen(true)} aria-label="Open menu" className="rounded-lg p-2 text-muted-foreground hover:bg-accent hover:text-foreground"><Menu className="size-5" /></button>
                    <Logo />
                </div>
                <motion.main key={page.url.split('?')[0]} initial={{ opacity: 0, y: 6 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.25 }} className="mx-auto max-w-6xl px-4 py-8 pb-28 sm:px-8">
                    {children}
                </motion.main>
            </div>
        </div>
    );
}
