import { useCallback, useEffect } from "react";
import { Link, NavLink, Outlet, useLocation } from "react-router-dom";

import { getUserSessions } from "../api/sessions";
import type { Session } from "../api/sessions";
import { useTheme } from "../hooks/use-theme";
import { useAuth } from "../state/auth";
import { useSessions } from "../state/sessions";
import { useMobileViewport } from "../hooks/use-mobile-viewport";
import { EventProvider } from "../state/events";
import { ToastProvider } from "../state/toast";
import { NotificationProvider } from "../state/notifications";
import { EventToastBridge } from "./features/notification/event-toast-bridge";
import { NotificationCenter } from "./features/notification/notification-center";
import { Icon } from "./icon";
import { MobileNav } from "./features/mobile/mobile-nav";
import { StartToolFAB } from "./features/tool/start-tool-fab";
import type { IconName } from "../utils/icons";

const NAV_ITEMS: {
	to: string;
	label: string;
	icon: IconName;
	badge?: "sessions";
}[] = [
	{ to: "/", label: "Home", icon: "dashboard" },
	{ to: "/sessions", label: "Sessions", icon: "terminal", badge: "sessions" },
	{ to: "/workspaces", label: "Workspaces", icon: "folder" },
	{ to: "/projects", label: "Projects", icon: "projects" },
	{ to: "/tool-workshop", label: "Tool Workshop", icon: "settings" },
	{ to: "/config-profiles", label: "Config Profiles", icon: "folder" },
	{ to: "/settings", label: "Settings", icon: "settings" },
];

const SessionItem = ({ session }: { session: Session }) => {
	const isRunning = session.status === "running";

	// Determine the link target:
	// - Web tools open their tunnel URL
	// - Terminal tools open the terminal page
	// - Everything else falls back to the project page
	const hasTerminal = session.tool_type_interfaces.includes("terminal");
	const hasWeb = session.tool_type_interfaces.includes("web");
	const href =
		session.url && hasWeb
			? session.url
			: hasTerminal
				? `/instances/${session.id}/terminal`
				: `/projects/${session.project_id}`;

	const tooltipParts = [session.display_name, session.project_name];
	if (session.workspace_name) tooltipParts.push(session.workspace_name);
	else if (session.repository_name) tooltipParts.push(session.repository_name);
	tooltipParts.push(`(${session.status})`);

	return (
		<a
			href={href}
			target={`session-${session.id}`}
			rel="noreferrer"
			className="nav-item session-item"
			title={tooltipParts.join(" ")}
		>
			<span className={`session-status ${isRunning ? "running" : ""}`} />
			<Icon name={session.tool_icon as IconName} size="sm" />
			<span className="session-name">
				{session.display_name}
				<span className="session-tool">{session.tool_type_name}</span>
			</span>
		</a>
	);
};

export const AppShell = () => {
	useTheme();
	const { user, logout } = useAuth();
	const { sessions, setAllSessions } = useSessions();
	const location = useLocation();
	const isMobile = useMobileViewport();
	const isMobileTerminal =
		isMobile &&
		location.pathname.includes("/instances/") &&
		location.pathname.includes("/terminal");

	const loadSessions = useCallback(async () => {
		try {
			const data = await getUserSessions();
			setAllSessions(data);
		} catch {
			// Silently fail - sessions are optional
		}
	}, [setAllSessions]);

	useEffect(() => {
		void loadSessions();
		// Poll every 30 seconds (reduced from 10s to avoid ERR_NETWORK_CHANGED from Docker network changes)
		const interval = setInterval(() => {
			void loadSessions();
		}, 30000);
		return () => clearInterval(interval);
	}, [loadSessions]);

	if (isMobileTerminal) {
		return (
			<EventProvider>
				<ToastProvider>
					<NotificationProvider>
						<EventToastBridge />
						<div className="shell mobile-terminal-shell">
							<Outlet />
						</div>
					</NotificationProvider>
				</ToastProvider>
			</EventProvider>
		);
	}

	return (
		<EventProvider>
			<ToastProvider>
				<NotificationProvider>
					<EventToastBridge />
					<div className="shell">
						<header className="shell-header">
							<Link className="brand" to="/">
								Headquarter
							</Link>
							<div className="header-actions">
								<NotificationCenter isMobileTerminal={isMobileTerminal} />
								<Link className="user-chip" to="/profile">
									{user?.name ?? "User"}
								</Link>
								<button
									className="ghost-button"
									onClick={() => {
										void logout();
									}}
									type="button"
								>
									<Icon name="logout" size="sm" />
									Logout
								</button>
							</div>
						</header>

						<div className="shell-body">
							{!isMobile && (
								<aside className="shell-nav" aria-label="Primary navigation">
									{NAV_ITEMS.map((item) => {
										const activeCount = sessions.filter(
											(s) => s.status === "running",
										).length;
										return (
											<NavLink
												key={item.to}
												to={item.to}
												className={({ isActive }) =>
													isActive ? "nav-item nav-item-active" : "nav-item"
												}
												end={item.to === "/"}
											>
												<Icon name={item.icon} size="sm" />
												{item.label}
												{item.badge === "sessions" && activeCount > 0 && (
													<span className="nav-badge">{activeCount}</span>
												)}
											</NavLink>
										);
									})}

									{sessions.length > 0 && (
										<>
											<div className="nav-divider" />
											<div className="nav-section-title">Live sessions</div>
											{sessions.map((session) => (
												<SessionItem key={session.id} session={session} />
											))}
										</>
									)}
								</aside>
							)}

							<main className={`shell-content ${isMobile ? "mobile" : ""}`}>
								<Outlet />
							</main>
						</div>

						{isMobile && (
							<MobileNav
								sessionCount={
									sessions.filter((s) => s.status === "running").length
								}
							/>
						)}
						<StartToolFAB />
					</div>
				</NotificationProvider>
			</ToastProvider>
		</EventProvider>
	);
};
