import { ReactNode, useEffect, useRef, useState } from "react";
import { Link, NavLink, useNavigate } from "react-router-dom";
import { useAuth } from "../context/AuthContext";
import { useNotifications } from "../context/NotificationsContext";
import { NotificationBell } from "./NotificationBell";
import { Sheet } from "./Sheet";
import {
	AgentsIcon,
	BellIcon,
	HomeIcon,
	LogOutIcon,
	RequestsIcon,
	SettingsIcon,
	ShieldIcon,
} from "./icons";

const navItems = [
	{ to: "/", label: "Dashboard", end: true },
	{ to: "/requests", label: "Requests" },
	{ to: "/agents", label: "Agents" },
	{ to: "/settings", label: "Settings" },
];

const tabs = [
	{ to: "/", label: "Home", Icon: HomeIcon, end: true },
	{ to: "/requests", label: "Requests", Icon: RequestsIcon },
	{ to: "/agents", label: "Agents", Icon: AgentsIcon },
	{ to: "/notifications", label: "Alerts", Icon: BellIcon, badge: true },
	{ to: "/settings", label: "Settings", Icon: SettingsIcon },
];

export function Layout({ children }: { children: ReactNode }) {
	const { user } = useAuth();

	return (
		<div className="flex min-h-[100dvh] flex-col">
			<header
				data-chrome
				className="pt-safe px-safe sticky top-0 z-30 border-b border-border bg-bg/85 backdrop-blur-xl"
			>
				<div className="mx-auto flex h-14 max-w-6xl items-center justify-between gap-2 px-3 sm:h-16 sm:px-4">
					<div className="flex min-w-0 items-center gap-3 sm:gap-6">
						<Link to="/" className="tap-sm flex items-center gap-2">
							<img src="/icon.svg" alt="" className="h-7 w-7 rounded-lg" />
							<span className="text-base font-bold tracking-tight sm:text-lg">
								Patch<span className="text-primary">Pass</span>
							</span>
						</Link>
						<nav className="hidden items-center gap-1 md:flex">
							{navItems.map((item) => (
								<NavLink
									key={item.to}
									to={item.to}
									end={item.end}
									className={({ isActive }) =>
										`rounded-lg px-3 py-1.5 text-sm font-medium transition ${
											isActive ? "bg-surface-raised text-text" : "text-muted hover:text-text"
										}`
									}
								>
									{item.label}
								</NavLink>
							))}
							{user?.role === "ADMIN" && (
								<NavLink
									to="/admin"
									className={({ isActive }) =>
										`rounded-lg px-3 py-1.5 text-sm font-medium transition ${
											isActive ? "bg-surface-raised text-accent" : "text-accent/70 hover:text-accent"
										}`
									}
								>
									Admin
								</NavLink>
							)}
						</nav>
					</div>

					<div className="flex shrink-0 items-center gap-1 sm:gap-2">
						{/* Below md the bell is replaced by the Alerts tab. */}
						<div className="hidden md:block">
							<NotificationBell />
						</div>
						<AccountMenu />
					</div>
				</div>
			</header>

			<main className="mx-auto w-full max-w-6xl flex-1 px-3 py-5 sm:px-4 sm:py-8">{children}</main>

			<footer className="mx-auto max-w-6xl px-4 py-8 text-center text-xs text-faint">
				<div className="flex flex-wrap items-center justify-center gap-x-3">
					<Link to="/privacy" className="inline-flex min-h-11 items-center hover:text-muted sm:min-h-0">
						Privacy Policy
					</Link>
					<span aria-hidden>·</span>
					<Link to="/terms" className="inline-flex min-h-11 items-center hover:text-muted sm:min-h-0">
						Terms of Service
					</Link>
					<span className="hidden sm:inline" aria-hidden>
						·
					</span>
					<span className="w-full sm:w-auto">
						PatchPass — review changes, approve intent, let agents proceed.
					</span>
				</div>
			</footer>

			{/* Keeps the last of the page clear of the fixed tab bar. */}
			<div
				className="h-[calc(var(--bottom-nav-h)_+_var(--safe-bottom))] shrink-0 md:hidden"
				aria-hidden
			/>

			<BottomTabs />
		</div>
	);
}

function BottomTabs() {
	const { unreadCount } = useNotifications();

	return (
		<nav
			data-chrome
			className="pb-safe px-safe fixed inset-x-0 bottom-0 z-40 border-t border-border bg-bg/90 backdrop-blur-xl md:hidden"
		>
			<div className="mx-auto flex h-[var(--bottom-nav-h)] max-w-md items-stretch">
				{tabs.map(({ to, label, Icon, end, badge }) => (
					<NavLink key={to} to={to} end={end} className="flex flex-1 items-stretch">
						{({ isActive }) => (
							<span
								className={`tap-sm flex w-full flex-col items-center justify-center gap-1 ${
									isActive ? "text-primary" : "text-faint"
								}`}
							>
								<span className="relative">
									<Icon
										className="h-[22px] w-[22px] transition-transform"
										strokeWidth={isActive ? 2.2 : 1.7}
									/>
									{badge && unreadCount > 0 && (
										<span className="absolute -right-2.5 -top-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-rejected px-1 text-[10px] font-bold text-white">
											{unreadCount > 9 ? "9+" : unreadCount}
										</span>
									)}
								</span>
								<span className="text-[10px] font-medium leading-none">{label}</span>
							</span>
						)}
					</NavLink>
				))}
			</div>
		</nav>
	);
}

function AccountMenu() {
	const { user, logout } = useAuth();
	const navigate = useNavigate();
	const [open, setOpen] = useState(false);
	const ref = useRef<HTMLDivElement>(null);

	useEffect(() => {
		if (!open) return;
		const onDown = (e: MouseEvent) => {
			if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);
		};
		document.addEventListener("mousedown", onDown);
		return () => document.removeEventListener("mousedown", onDown);
	}, [open]);

	const signOut = async () => {
		setOpen(false);
		await logout();
		navigate("/login");
	};

	const initial = user?.display_name?.[0]?.toUpperCase() ?? "?";

	return (
		<div className="relative" ref={ref}>
			<button
				onClick={() => setOpen((o) => !o)}
				className="tap-sm flex min-h-11 items-center gap-2 rounded-lg px-2 py-1.5 text-sm hover:bg-surface-raised"
				aria-label="Account menu"
				aria-expanded={open}
			>
				<span className="flex h-8 w-8 items-center justify-center rounded-full bg-primary-dim/50 text-xs font-semibold text-primary">
					{initial}
				</span>
				<span className="hidden text-text sm:inline">{user?.display_name}</span>
			</button>

			{/* Desktop: dropdown. */}
			{open && (
				<div className="animate-fade-in absolute right-0 mt-2 hidden w-48 rounded-xl border border-border-strong bg-surface py-1 shadow-2xl sm:block">
					<MenuLink to="/settings" onClick={() => setOpen(false)}>
						Settings
					</MenuLink>
					{user?.role === "ADMIN" && (
						<MenuLink to="/admin" onClick={() => setOpen(false)} accent>
							Admin
						</MenuLink>
					)}
					<button
						onClick={signOut}
						className="block w-full px-4 py-2 text-left text-sm text-rejected hover:bg-surface-raised"
					>
						Log out
					</button>
				</div>
			)}

			{/* Mobile: bottom sheet, which is reachable one-handed. */}
			<div className="sm:hidden">
				<Sheet open={open} onClose={() => setOpen(false)} padded={false}>
					<div className="flex items-center gap-3 px-5 pb-4 pt-3">
						<span className="flex h-11 w-11 items-center justify-center rounded-full bg-primary-dim/50 text-base font-semibold text-primary">
							{initial}
						</span>
						<div className="min-w-0">
							<p className="truncate font-semibold text-text">{user?.display_name}</p>
							<p className="truncate text-xs text-muted">@{user?.username}</p>
						</div>
					</div>
					<div className="border-t border-border">
						<SheetRow
							icon={<SettingsIcon className="h-5 w-5" />}
							label="Settings"
							onClick={() => {
								setOpen(false);
								navigate("/settings");
							}}
						/>
						{user?.role === "ADMIN" && (
							<SheetRow
								icon={<ShieldIcon className="h-5 w-5" />}
								label="Admin"
								accent
								onClick={() => {
									setOpen(false);
									navigate("/admin");
								}}
							/>
						)}
						<SheetRow
							icon={<LogOutIcon className="h-5 w-5" />}
							label="Log out"
							danger
							onClick={signOut}
						/>
					</div>
				</Sheet>
			</div>
		</div>
	);
}

function MenuLink({
	to,
	onClick,
	accent,
	children,
}: {
	to: string;
	onClick: () => void;
	accent?: boolean;
	children: ReactNode;
}) {
	return (
		<Link
			to={to}
			onClick={onClick}
			className={`block px-4 py-2 text-sm hover:bg-surface-raised ${
				accent ? "text-accent" : "text-muted hover:text-text"
			}`}
		>
			{children}
		</Link>
	);
}

function SheetRow({
	icon,
	label,
	onClick,
	accent,
	danger,
}: {
	icon: ReactNode;
	label: string;
	onClick: () => void;
	accent?: boolean;
	danger?: boolean;
}) {
	return (
		<button
			onClick={onClick}
			className={`flex min-h-14 w-full items-center gap-3.5 border-b border-border/60 px-5 text-left text-[15px] font-medium transition active:bg-surface-raised ${
				danger ? "text-rejected" : accent ? "text-accent" : "text-text"
			}`}
		>
			<span className={danger ? "" : accent ? "" : "text-muted"}>{icon}</span>
			{label}
		</button>
	);
}
