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

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

export function Canvas({ className }: { className?: string }) {
	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%" }} className={className}>
			<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="top-right">
					<Actions />
				</Panel>
			</ReactFlow>
		</div>
	);
}

export default Canvas;
