import "@xyflow/react/dist/style.css";
import {
	ReactFlow,
	Background,
	Controls,
	Connection,
	BackgroundVariant,
	Edge,
	useReactFlow,
	Panel,
	useStoreApi,
} from "@xyflow/react";
import { useStateStore, AppState, AppNode } 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();
	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]);
	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;
