import "@xyflow/react/dist/style.css";
import {
	ReactFlow,
	Background,
	Controls,
	Connection,
	BackgroundVariant,
	Edge,
	useReactFlow,
	Panel,
	useStoreApi,
} from "@xyflow/react";
import { useStateStore, AppState, AppNode, useZoom } 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 instance = useReactFlow();
	const flow = useStoreApi();
	const viewport = useZoom();
	useEffect(() => {
		store.setViewport({
			width: flow.getState().width,
			height: flow.getState().height,
			transformX: flow.getState().transform[0],
			transformY: flow.getState().transform[1],
			transformZoom: flow.getState().transform[2],
		});
	}, [store, flow]);
	useEffect(() => {
		instance.setViewport(viewport);
	}, [viewport, instance]);
	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 = instance.getNode(c.source)! as AppNode;
			const tn = instance.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;
		},
		[instance],
	);
	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 showInteractive={false} />
				<Background
					variant={store.mode === "deploy" ? BackgroundVariant.Dots : BackgroundVariant.Lines}
					gap={12}
					size={1}
				/>
				<Panel position="bottom-right">
					<Actions />
				</Panel>
			</ReactFlow>
		</div>
	);
}

export default Canvas;
