"use client";

import { useQuery } from "@tanstack/react-query";
import {
	type RegisteredRouter,
	useLocation,
	useNavigate,
} from "@tanstack/react-router";
import {
	AlignLeft,
	BadgeInfo,
	CircleAlert,
	List,
	Network,
	Package,
	Settings,
	Store,
	SwatchBook,
} from "lucide-react";
import type React from "react";
import {
	GuiAnimationSwitch,
	GuiCompactSwitch,
} from "@/components/common-setting-parts";
import { MaterialThemeButton } from "@/components/MaterialThemePanel";
import { Button } from "@/components/ui/button";
import {
	Dialog,
	DialogClose,
	DialogContent,
	DialogFooter,
	DialogHeader,
	DialogTrigger,
} from "@/components/ui/dialog";
import {
	Popover,
	PopoverContent,
	PopoverTrigger,
} from "@/components/ui/popover";
import {
	Tooltip,
	TooltipContent,
	TooltipTrigger,
} from "@/components/ui/tooltip";
import { commands } from "@/lib/bindings";
import { tc } from "@/lib/i18n";
import { toastSuccess } from "@/lib/toast";
import vrcalIconUrl from "../icons/vrcal-favicon.svg";

export function SideBar({ className }: { className?: string }) {
	"use client";

	const isBadHostName = useQuery({
		queryKey: ["util_is_bad_hostname"],
		queryFn: commands.utilIsBadHostname,
		refetchOnMount: false,
		refetchOnReconnect: false,
		refetchOnWindowFocus: false,
		refetchInterval: false,
		initialData: false,
	});
	const hideSidebarLinks = useQuery({
		queryKey: ["environmentHideSidebarLinks"],
		queryFn: commands.environmentHideSidebarLinks,
		refetchOnReconnect: false,
		refetchOnWindowFocus: false,
		refetchInterval: false,
		initialData: false,
	});

	const isDev = import.meta.env.DEV;

	return (
		<aside
			className={`${className} flex w-[260px] max-w-[260px] p-3 ml-0 my-3 shrink-0 overflow-auto text-[var(--md-sys-color-on-surface)] compact:w-auto compact:p-1 compact:my-2`}
		>
			<div className="flex flex-col gap-1 min-w-40 grow compact:min-w-0">
				<SideBarItem href={"/projects"} text={tc("projects")} icon={List} />
				<SideBarItem
					href={"/packages/repositories"}
					text={tc("resources")}
					icon={Package}
				/>
				<SideBarItem href={"/settings"} text={tc("settings")} icon={Settings} />
				<SideBarItem href={"/mcp"} text={tc("mcp:title")} icon={Network} />
				<MaterialThemeButton className="w-full compact:size-10" />
				<SideBarItem href={"/log"} text={tc("logs")} icon={AlignLeft} />
				{isDev && <DevRestartSetupButton />}
				{isDev && (
					<SideBarItem
						href={"/dev-palette"}
						text={"UI Palette (dev only)"}
						icon={SwatchBook}
					/>
				)}
				{isDev && <StyleQuickAccess />}
				<div className={"grow"} />
				{!hideSidebarLinks.data && (
					<>
						<SideBarExternalLinkButton
							href="https://booth.pm"
							text={tc("sidebar:booth")}
							icon={Store}
						/>
						<SideBarExternalLinkButton
							href="https://vrcal.cqmhv.com"
							text={tc("sidebar:vrchat avatar learn")}
							icon={VrcalIcon}
						/>
						<VersionCopyButton />
					</>
				)}
				{isBadHostName.data && <BadHostNameDialogButton />}
			</div>
		</aside>
	);
}

function SideBarItem({
	href,
	text,
	icon,
}: {
	href: keyof RegisteredRouter["routeTree"]["types"]["fileRouteTypes"]["fileRoutesByTo"];
	text: React.ReactNode;
	icon: React.ComponentType<{ className?: string }>;
}) {
	const location = useLocation();
	const navigate = useNavigate();
	const getFirstPathSegment = (path: string) => {
		return path.split("/")[1] || "";
	};
	const isActive =
		getFirstPathSegment(location.pathname || "") === getFirstPathSegment(href);
	return (
		<SideBarButton
			icon={icon}
			className={
				isActive
					? "bg-[var(--md-sys-color-surface-container-highest)] text-[var(--md-sys-color-on-surface)]"
					: "bg-transparent text-[var(--md-sys-color-on-surface)]"
			}
			onClick={() => navigate({ to: href })}
		>
			{text}
		</SideBarButton>
	);
}

function SideBarExternalLinkButton({
	href,
	text,
	icon,
}: {
	href: string;
	text: React.ReactNode;
	icon: React.ComponentType<{ className?: string }>;
}) {
	return (
		<SideBarButton icon={icon} onClick={() => void commands.utilOpenUrl(href)}>
			{text}
		</SideBarButton>
	);
}

function VersionCopyButton() {
	const version = useQuery({
		queryKey: ["util_get_version"],
		queryFn: commands.utilGetVersion,
		refetchOnMount: false,
		refetchOnReconnect: false,
		refetchOnWindowFocus: false,
		refetchInterval: false,
	});
	const copyText = version.data ? `v${version.data}` : "";
	const onClick = async () => {
		await navigator.clipboard.writeText(copyText);
		toastSuccess(tc("sidebar:toast:version copied"));
	};
	return (
		<SideBarButton icon={BadgeInfo} onClick={onClick} disabled={!copyText}>
			{copyText ? tc("sidebar:version", { version: copyText }) : "..."}
		</SideBarButton>
	);
}

function VrcalIcon({ className }: { className?: string }) {
	return (
		<img src={vrcalIconUrl} className={className} alt="" aria-hidden="true" />
	);
}

function BadHostNameDialogButton() {
	return (
		<Dialog>
			<DialogTrigger asChild>
				<SideBarButton
					icon={CircleAlert}
					className="text-warning hover:bg-card hover:text-warning"
				>
					{tc("sidebar:bad hostname")}
				</SideBarButton>
			</DialogTrigger>
			<DialogContent className={"max-w-[50vw]"}>
				<DialogHeader>
					<h1 className={"text-warning text-center"}>
						{tc("sidebar:dialog:bad hostname")}
					</h1>
				</DialogHeader>
				<div className={"whitespace-normal"}>
					{tc("sidebar:dialog:bad hostname description")}
				</div>
				<DialogFooter>
					<DialogClose asChild>
						<Button>{tc("general:button:close")}</Button>
					</DialogClose>
				</DialogFooter>
			</DialogContent>
		</Dialog>
	);
}

function DevRestartSetupButton() {
	const navigate = useNavigate();
	const onClick = async () => {
		await commands.environmentClearSetupProcess();
		navigate({ to: "/setup/appearance" });
	};
	return (
		<SideBarButton icon={Settings} onClick={onClick}>
			Restart Setup (dev only)
		</SideBarButton>
	);
}

function SideBarButton({
	icon,
	showIconOnlyWhenCompact,
	className,
	children,
	...props
}: {
	icon: React.ComponentType<{ className?: string }>;
	showIconOnlyWhenCompact?: boolean;
	className?: string;
	children: React.ReactNode;
} & React.ComponentProps<typeof Button>) {
	const IconElement = icon;
	return (
		<Tooltip>
			<TooltipTrigger asChild>
				<Button
					variant="ghost"
					className={`justify-start h-12 px-4 rounded-full text-[var(--md-sys-color-on-surface)] hover:bg-[var(--md-sys-color-surface-container-highest)] hover:text-[var(--md-sys-color-on-surface)] ${className} compact:justify-center compact:px-3 compact:size-10`}
					{...props}
				>
					<div
						className={`mr-4 compact:mr-0 ${showIconOnlyWhenCompact ? "hidden compact:block" : ""}`}
					>
						<IconElement className="h-5 w-5" />
					</div>
					<span className="compact:hidden">{children}</span>
				</Button>
			</TooltipTrigger>
			<TooltipContent side="right">{children}</TooltipContent>
		</Tooltip>
	);
}

export function StyleQuickAccess() {
	return (
		<Popover>
			<PopoverTrigger asChild>
				<SideBarButton icon={SwatchBook}>
					Style Settings (dev only)
				</SideBarButton>
			</PopoverTrigger>
			<PopoverContent>
				<GuiAnimationSwitch />
				<GuiCompactSwitch />
			</PopoverContent>
		</Popover>
	);
}
