import { useEnv } from "./lib/state";
import { Copy, Check, ExternalLink } 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]);
	const handleClick = useCallback(() => {
		if (g.type === "https") {
			window.open(content, "_blank");
		} else {
			copy();
		}
	}, [g.type, content, copy]);

	return (
		<TooltipProvider>
			<Tooltip delayDuration={100} open={open} onOpenChange={setOpen}>
				<TooltipTrigger asChild>
					<Button variant="ghost" className="!gap-1 !p-0 !h-fit" onClick={handleClick}>
						<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}
					onClick={copy}
				>
					{g.type === "https" ? (
						<ExternalLink className="w-4 h-4 !bg-transparent" color="black" />
					) : (
						<>
							{!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>
	);
}
