import "@xyflow/react/dist/style.css";
import {
	ReactFlow,
	Background,
	Controls,
	Connection,
	BackgroundVariant,
	Edge,
	useReactFlow,
	Panel,
} from "@xyflow/react";
import { useStateStore, AppState, AppNode, useEnv } from "@/lib/state";
import { useShallow } from "zustand/react/shallow";
import { useCallback, useEffect, useMemo } from "react";
import { NodeGatewayHttps } from "@/components/node-gateway-https";
import { NodeApp } from "@/components/node-app";
import { NodeVolume } from "./node-volume";
import { NodePostgreSQL } from "./node-postgresql";
import { NodeMongoDB } from "./node-mongodb";
import { NodeGithub } from "./node-github";
import { Actions } from "./actions";
import { NodeGatewayTCP } from "./node-gateway-tcp";
import { NodeNetwork } from "./node-network";

const selector = (state: AppState) => ({
	nodes: state.nodes,
	edges: state.edges,
	onNodesChange: state.onNodesChange,
	onEdgesChange: state.onEdgesChange,
	onConnect: state.onConnect,
});

export function Canvas() {
	const { nodes, edges, onNodesChange, onEdgesChange, onConnect } = useStateStore(useShallow(selector));
	const store = useStateStore();
	const flow = useReactFlow();
	const nodeTypes = useMemo(
		() => ({
			network: NodeNetwork,
			app: NodeApp,
			"gateway-https": NodeGatewayHttps,
			"gateway-tcp": NodeGatewayTCP,
			volume: NodeVolume,
			postgresql: NodePostgreSQL,
			mongodb: NodeMongoDB,
			github: NodeGithub,
		}),
		[],
	);
	const isValidConnection = useCallback(
		(c: Edge | Connection) => {
			if (c.source === c.target) {
				return false;
			}
			const sn = flow.getNode(c.source)! as AppNode;
			const tn = flow.getNode(c.target)! as AppNode;
			if (sn.type === "github") {
				return c.targetHandle === "repository";
			}
			if (sn.type === "app") {
				if (c.sourceHandle === "ports" && (!sn.data.ports || sn.data.ports.length === 0)) {
					return false;
				}
			}
			if (tn.type === "gateway-https") {
				if (c.targetHandle === "https" && tn.data.https !== undefined) {
					return false;
				}
			}
			if (sn.type === "volume") {
				if (c.targetHandle !== "volume") {
					return false;
				}
				return true;
			}
			if (tn.type === "network") {
				if (c.sourceHandle !== "subdomain") {
					return false;
				}
				if (sn.type !== "gateway-https" && sn.type !== "gateway-tcp") {
					return false;
				}
			}
			return true;
		},
		[flow],
	);
	const env = useEnv();
	useEffect(() => {
		const networkNodes: AppNode[] = env.networks.map((n) => ({
			id: n.domain,
			type: "network",
			position: {
				x: 0,
				y: 0,
			},
			isConnectable: true,
			data: {
				domain: n.domain,
				label: n.domain,
				envVars: [],
				ports: [],
				state: "success", // TODO(gio): monitor network health
			},
		}));
		const prevNodes = store.nodes;
		const newNodes = networkNodes.concat(prevNodes.filter((n) => n.type !== "network"));
		// TODO(gio): actually compare
		if (prevNodes.length !== newNodes.length) {
			store.setNodes(newNodes);
		}
	}, [env, store]);
	return (
		<div style={{ width: "100%", height: "100%" }}>
			<ReactFlow
				nodeTypes={nodeTypes}
				nodes={nodes}
				edges={edges}
				onNodesChange={onNodesChange}
				onEdgesChange={onEdgesChange}
				onConnect={onConnect}
				isValidConnection={isValidConnection}
				fitView
				proOptions={{ hideAttribution: true }}
			>
				<Controls />
				<Background variant={BackgroundVariant.Dots} gap={12} size={1} />
				<Panel position="bottom-right">
					<Actions />
				</Panel>
			</ReactFlow>
		</div>
	);
}

export default Canvas;
