import * as DM from '@radix-ui/react-dropdown-menu';
import { Head, Link, router, usePage } from '@inertiajs/react';
import {
    AlignLeft, Building2, ChevronRight, ClipboardList, FileText, LayoutDashboard, LayoutTemplate, LogOut,
    Inbox, Maximize, Minimize, Package, Search, ShieldCheck, Star, User, UserCog, Users, type LucideIcon,
} from 'lucide-react';
import { useEffect, useState } from 'react';
import { AppBrand, useAppTheme } from '@/components/AppBrand';
import { CompanyLogo, CompanySwitcher } from '@/components/CompanySwitcher';
import { Flash } from '@/components/Flash';
import { NotificationBell } from '@/components/NotificationBell';
import { FeedbackButton } from '@/components/FeedbackButton';
import { cn } from '@/lib/utils';
import type { SharedProps } from '@/types';

type NavItem = { href: string; label: string; icon: LucideIcon; show: boolean; match?: string };

const STORE_KEY = 'sgq.sidebar.collapsed';
const readCollapsed = () => { try { return localStorage.getItem(STORE_KEY) === '1'; } catch { return false; } };

const itemClass = 'flex cursor-pointer items-center gap-2.5 rounded-[5px] px-2.5 py-2 text-sm text-ink outline-none data-[highlighted]:bg-accent-soft data-[highlighted]:text-link';

export default function AppLayout({ title, children }: { title: string; children: React.ReactNode }) {
    const { auth } = usePage<SharedProps>().props;
    const url = usePage().url;
    const [mobileOpen, setMobileOpen] = useState(false);
    const [collapsed, setCollapsed] = useState(readCollapsed);
    const [fullscreen, setFullscreen] = useState(false);
    const [q, setQ] = useState('');
    useAppTheme();

    useEffect(() => { setMobileOpen(false); }, [url]);
    useEffect(() => {
        if (!mobileOpen) return;
        const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') setMobileOpen(false); };
        window.addEventListener('keydown', onKey);
        return () => window.removeEventListener('keydown', onKey);
    }, [mobileOpen]);
    useEffect(() => {
        const on = () => setFullscreen(!!document.fullscreenElement);
        document.addEventListener('fullscreenchange', on);
        return () => document.removeEventListener('fullscreenchange', on);
    }, []);

    if (!auth || !auth.activeCompany) return <>{children}</>;
    const { can } = auth;

    const groups: { label: string; items: NavItem[] }[] = [
        { label: 'Main', items: [{ href: '/dashboard', label: 'Dashboard', icon: LayoutDashboard, show: true }] },
        { label: 'Sales', items: [
            { href: '/quotes', label: 'Quotes', icon: FileText, show: true },
            { href: '/leads', label: 'Leads', icon: Inbox, show: true },
            { href: '/reviews', label: 'Reviews', icon: Star, show: true },
            { href: '/contacts', label: 'Contacts', icon: Users, show: true },
            { href: '/items', label: 'Item library', icon: Package, show: true },
            { href: '/templates', label: 'Templates', icon: LayoutTemplate, show: true },
        ] },
        { label: 'Administration', items: [
            { href: '/team', label: 'Team', icon: UserCog, show: can['users.manage'] },
            { href: '/audit-log', label: 'Audit log', icon: ClipboardList, show: can['audit.view'] },
            { href: '/settings/company', label: 'Company settings', icon: Building2, show: true, match: '/settings' },
        ] },
    ].map((g) => ({ ...g, items: g.items.filter((i) => i.show) })).filter((g) => g.items.length);

    const isActive = (href: string) => url === href || url.startsWith(href + '/') || url.startsWith(href + '?');

    const toggleSidebar = () => {
        if (window.matchMedia('(min-width: 1024px)').matches) {
            const next = !collapsed;
            setCollapsed(next);
            try { localStorage.setItem(STORE_KEY, next ? '1' : '0'); } catch { /* storage unavailable */ }
        } else {
            setMobileOpen((o) => !o);
        }
    };
    const toggleFullscreen = () => {
        if (document.fullscreenElement) void document.exitFullscreen?.();
        else void document.documentElement.requestFullscreen?.().catch(() => {});
    };
    const search = (e: React.FormEvent) => {
        e.preventDefault();
        router.get('/quotes', q.trim() ? { q: q.trim() } : {});
    };

    const initials = auth.user.name.split(' ').map((p) => p[0]).slice(0, 2).join('').toUpperCase();
    const narrow = collapsed && !mobileOpen; // icon-only rail (desktop only)

    return (
        <div className="min-h-screen">
            <Head title={title} />

            {/* Mobile overlay */}
            <div
                aria-hidden
                onClick={() => setMobileOpen(false)}
                className={cn('fixed inset-0 z-40 bg-stone-900/40 transition-opacity duration-200 lg:hidden', mobileOpen ? 'opacity-100' : 'pointer-events-none opacity-0')}
            />

            {/* Sidebar */}
            <aside
                className={cn(
                    'fixed inset-y-0 left-0 z-50 flex w-[260px] flex-col border-r border-line bg-surface shadow-card transition-[width,transform] duration-200 ease-out',
                    mobileOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0',
                    narrow && 'lg:w-[76px]',
                )}
                aria-label="Sidebar"
            >
                <div className={cn('flex h-[70px] shrink-0 items-center border-b border-line px-5', narrow && 'lg:justify-center lg:px-0')}>
                    <Link href="/dashboard" aria-label="Dashboard" className="flex min-w-0 items-center">
                        {narrow
                            ? <><span className="hidden h-7 w-7 rounded-full bg-accent lg:inline-block" aria-hidden /><span className="lg:hidden"><AppBrand large /></span></>
                            : <AppBrand large />}
                    </Link>
                </div>

                <nav className="flex-1 overflow-y-auto px-3 py-4" aria-label="Main">
                    {groups.map((g) => (
                        <div key={g.label} className="mb-3">
                            <div className={cn('px-3 pb-2 pt-3 text-[11px] font-semibold uppercase tracking-[0.08em] text-ink-muted', narrow && 'lg:sr-only')}>
                                {g.label}
                            </div>
                            <ul className="space-y-0.5">
                                {g.items.map((n) => {
                                    const active = isActive(n.match ?? n.href);
                                    const Icon = n.icon;
                                    return (
                                        <li key={n.href}>
                                            <Link
                                                href={n.href}
                                                title={narrow ? n.label : undefined}
                                                aria-current={active ? 'page' : undefined}
                                                className={cn(
                                                    'group relative flex items-center gap-3 rounded-[5px] px-3 py-2.5 text-sm font-medium transition-colors duration-150',
                                                    active ? 'bg-accent-soft text-link' : 'text-ink hover:bg-stone-50 hover:text-link',
                                                    narrow && 'lg:justify-center lg:px-0',
                                                )}
                                            >
                                                {active && <span className="absolute inset-y-1.5 left-0 w-[3px] rounded-r bg-accent" aria-hidden />}
                                                <Icon className={cn('h-[18px] w-[18px] shrink-0', active ? 'text-link' : 'text-accent')} strokeWidth={1.75} aria-hidden />
                                                <span className={cn('truncate', narrow && 'lg:sr-only')}>{n.label}</span>
                                                {!narrow && active && <ChevronRight className="ml-auto h-4 w-4 opacity-60" aria-hidden />}
                                            </Link>
                                        </li>
                                    );
                                })}
                            </ul>
                        </div>
                    ))}
                </nav>

                <div className={cn('flex shrink-0 items-center gap-3 border-t border-line px-5 py-4', narrow && 'lg:justify-center lg:px-0')}>
                    <CompanyLogo company={auth.activeCompany} size={30} />
                    <div className={cn('min-w-0', narrow && 'lg:hidden')}>
                        <div className="truncate text-sm font-medium text-ink">{auth.activeCompany.name}</div>
                        <div className="text-xs text-ink-muted">{auth.activeCompany.role}</div>
                    </div>
                </div>
            </aside>

            {/* Content column */}
            <div className={cn('transition-[padding] duration-200 ease-out', narrow ? 'lg:pl-[76px]' : 'lg:pl-[260px]')}>
                <header className="sticky top-0 z-30 border-b border-line bg-surface">
                    <div className="flex h-[70px] items-center gap-2 px-4 sm:gap-3 sm:px-6">
                        <button
                            onClick={toggleSidebar}
                            className="rounded-[5px] p-2 text-ink hover:bg-accent-soft hover:text-link"
                            aria-label="Toggle navigation"
                            aria-expanded={mobileOpen || !collapsed}
                            data-testid="sidebar-toggle"
                        >
                            <AlignLeft className="h-5 w-5" strokeWidth={1.75} />
                        </button>

                        <form onSubmit={search} role="search" className="relative hidden w-full max-w-xs md:block">
                            <input
                                value={q}
                                onChange={(e) => setQ(e.target.value)}
                                placeholder="Search quotes…"
                                aria-label="Search quotes"
                                className="h-[38px] w-full rounded-[5px] border border-line bg-stone-50 pl-3 pr-10 text-sm text-ink placeholder:text-ink-muted focus:border-accent focus:bg-surface focus:outline-none focus:ring-3 focus:ring-accent-ring"
                            />
                            <button type="submit" className="absolute inset-y-0 right-0 flex w-10 items-center justify-center text-ink-muted hover:text-link" aria-label="Search">
                                <Search className="h-4 w-4" strokeWidth={1.75} />
                            </button>
                        </form>

                        <div className="ml-auto flex items-center gap-1 sm:gap-2">
                            <CompanySwitcher companies={auth.companies} active={auth.activeCompany} />
                            <FeedbackButton />
                            <NotificationBell activeCompanyId={auth.activeCompany.id} />
                            <button
                                onClick={toggleFullscreen}
                                className="hidden rounded-[5px] p-2 text-ink hover:bg-accent-soft hover:text-link sm:inline-flex"
                                aria-label={fullscreen ? 'Exit full screen' : 'Full screen'}
                            >
                                {fullscreen ? <Minimize className="h-5 w-5" strokeWidth={1.75} /> : <Maximize className="h-5 w-5" strokeWidth={1.75} />}
                            </button>
                            <span className="mx-1 hidden h-8 w-px bg-line sm:block" aria-hidden />
                            <DM.Root>
                                <DM.Trigger className="flex items-center gap-2.5 rounded-[5px] p-1 pr-2 outline-none hover:bg-stone-50 focus-visible:ring-3 focus-visible:ring-accent-ring" aria-label="Account menu" data-testid="user-menu">
                                    {auth.user.photo_url
                                        ? <img src={auth.user.photo_url} alt="" className="h-9 w-9 rounded-full object-cover" />
                                        : <span className="flex h-9 w-9 items-center justify-center rounded-full bg-accent-soft text-xs font-semibold text-link">{initials}</span>}
                                    <span className="hidden text-left leading-tight xl:block">
                                        <span className="block text-sm font-medium text-ink">{auth.user.name}</span>
                                        <span className="block text-xs text-ink-muted">{auth.activeCompany.role}</span>
                                    </span>
                                </DM.Trigger>
                                <DM.Portal>
                                    <DM.Content align="end" sideOffset={8} className="motion-pop z-50 min-w-60 rounded-[var(--radius-card)] border border-line bg-surface p-1.5 shadow-pop">
                                        <div className="border-b border-line px-2.5 pb-2.5 pt-1.5 text-center">
                                            <div className="text-sm font-semibold text-ink">{auth.user.name}</div>
                                            <div className="text-xs text-ink-muted">{auth.user.email}</div>
                                            <div className="mt-1 text-xs text-ink-muted">{auth.activeCompany.role} · {auth.activeCompany.name}</div>
                                        </div>
                                        <div className="pt-1.5">
                                            <DM.Item className={itemClass} onSelect={() => router.visit('/settings/profile')}><User className="h-4 w-4" strokeWidth={1.75} />Profile</DM.Item>
                                            <DM.Item className={itemClass} onSelect={() => router.visit('/settings/security')}><ShieldCheck className="h-4 w-4" strokeWidth={1.75} />Security &amp; 2FA</DM.Item>
                                            <DM.Separator className="my-1 h-px bg-line" />
                                            <DM.Item className={itemClass} onSelect={() => router.post('/logout')}><LogOut className="h-4 w-4" strokeWidth={1.75} />Sign out</DM.Item>
                                        </div>
                                    </DM.Content>
                                </DM.Portal>
                            </DM.Root>
                        </div>
                    </div>
                    {/* Thin bar in the active company's colour — a constant reminder of which company you're in. */}
                    <div className="h-[3px]" style={{ background: auth.activeCompany.primary }} aria-hidden />
                </header>

                {/* Fades / lifts in each time a page opens (the layout mounts once per page). */}
                <main className="motion-page mx-auto max-w-[1600px] px-4 py-6 sm:px-6">
                    <Flash />
                    {children}
                </main>
            </div>
        </div>
    );
}
