import { useNodes } from "@xyflow/react";
import { AppNode, nodeLabel, ServiceNode } from "./lib/state";
import { useMemo } from "react";
import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from "./components/ui/table";

function ingress(nodes: AppNode[]) {
	const nm = new Map(nodes.map((n) => [n.id, n]));
	return nodes
		.filter((n) => n.type === "gateway-https")
		.map((i) => {
			console.log(i.data);
			if (!i.data || !i.data.network || !i.data.subdomain) {
				return null;
			}
			if (!i.data.https || !i.data.https.serviceId || !i.data.https.portId) {
				return null;
			}
			console.log("1231");
			const svc = nm.get(i.data.https.serviceId)! as ServiceNode;
			const port = svc.data.ports.find((p) => p.id === i.data.https!.portId)!;
			console.log({ svc, port });
			return {
				id: `${i.id} - ${port.id}`,
				service: svc,
				port: port,
				endpoint: `https://${i.data.subdomain}.${i.data.network}`,
			};
		})
		.filter((i) => i != null);
}

export function Deployment() {
	const nodes = useNodes<AppNode>();
	const ing = useMemo(() => ingress(nodes), [nodes]);
	return (
		<>
			<Table>
				<TableCaption>HTTPS Gateways</TableCaption>
				<TableHeader>
					<TableRow>
						<TableHead>Service</TableHead>
						<TableHead>Port</TableHead>
						<TableHead>Endpoint</TableHead>
					</TableRow>
				</TableHeader>
				<TableBody>
					{ing.map((i) => (
						<TableRow>
							<TableCell>{nodeLabel(i.service)}</TableCell>
							<TableCell>{i.port.name}</TableCell>
							<TableCell>
								<a href={i.endpoint} target="_blank">
									{i.endpoint}
								</a>
							</TableCell>
						</TableRow>
					))}
				</TableBody>
			</Table>
		</>
	);
}
