import { useEnv } from "./lib/state";
import { Copy, Check } from "lucide-react";
import { Button } from "./components/ui/button";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./components/ui/tooltip";
import { useCallback, useMemo, useState } from "react";
import { AccessType } from "./components/icon";
import { Access } from "config";

export function Gateways() {
	const env = useEnv();
	console.log(env.access);
	const filtered = useMemo(() => {
		return env.access.filter((a) => a.type !== "env_var");
	}, [env.access]);
	const groupedAccess = filtered.reduce((acc, curr) => {
		if (!acc.has(curr.name)) {
			acc.set(curr.name, []);
		}
		acc.get(curr.name)!.push(curr);
		return acc;
	}, new Map<string, typeof env.access>());
	return (
		<ul>
			{Array.from(groupedAccess.entries()).map(([name, access]) => (
				<>
					{access.map((a) => (
						<li key={name}>
							<Gateway g={a} />
						</li>
					))}
				</>
			))}
		</ul>
	);
}

export function Gateway({ g }: { g: Access }) {
	const [hidden, content] = ((): [string, string] => {
		switch (g.type) {
			case "https":
				return [g.address, g.address];
			case "ssh":
			case "tcp":
			case "udp":
				return [`${g.host}:${g.port}`, `${g.host}:${g.port}`];
			case "postgresql":
				return [
					`postgresql://${g.username}:*****@${g.host}:${g.port}/${g.database}`,
					`postgresql://${g.username}:${g.password}@${g.host}:${g.port}/${g.database}`,
				];
			case "mongodb":
				return [
					`mongodb://${g.username}:*****@${g.host}:${g.port}/${g.database}`,
					`mongodb://${g.username}:${g.password}@${g.host}:${g.port}/${g.database}`,
				];
			default:
				throw new Error(`Unknown gateway type: ${g.type}`);
		}
	})();
	const [clicked, setClicked] = useState(false);
	const [open, setOpen] = useState(false);
	const copy = useCallback(() => {
		navigator.clipboard.writeText(content);
		setClicked(true);
		setOpen(true);
		setTimeout(() => {
			setClicked(false);
			setOpen(false);
		}, 1000);
	}, [content, setClicked, setOpen]);
	return (
		<TooltipProvider>
			<Tooltip delayDuration={100} open={open} onOpenChange={setOpen}>
				<TooltipTrigger asChild>
					<Button
						variant="ghost"
						onClick={g.type === "https" ? () => window.open(content, "_blank") : copy}
						className="!gap-1 !p-0 !h-fit"
					>
						<AccessType access={g} className="w-4 h-4" />
						<div className="hover:bg-gray-200 p-x-1">{hidden}</div>
					</Button>
				</TooltipTrigger>
				<TooltipContent side="right" className="!bg-transparent cursor-pointer !p-0" sideOffset={10}>
					{!clicked && <Copy className="w-4 h-4 !bg-transparent" color="black" />}
					{clicked && <Check className="w-4 h-4 !bg-transparent" color="black" />}
				</TooltipContent>
			</Tooltip>
		</TooltipProvider>
	);
}
