import { Category, defaultCategories } from "./categories";
import { CreateValidators, Validator } from "./config";
import { GitHubService, GitHubServiceImpl } from "./github";
import type { Edge, Node, OnConnect, OnEdgesChange, OnNodesChange, Viewport as ReactFlowViewport } from "@xyflow/react";
import {
	addEdge,
	applyEdgeChanges,
	applyNodeChanges,
	Connection,
	EdgeChange,
	useNodes,
	XYPosition,
} from "@xyflow/react";
import type { DeepPartial } from "react-hook-form";
import { v4 as uuidv4 } from "uuid";
import { z } from "zod";
import { create } from "zustand";

export type InitData = {
	label: string;
	envVars: BoundEnvVar[];
	ports: Port[];
};

export type NodeData = InitData & {
	activeField?: string | undefined;
	state?: string | null;
};

export type PortConnectedTo = {
	serviceId: string;
	portId: string;
};

export type NetworkData = NodeData & {
	domain: string;
};

export type NetworkNode = Node<NetworkData> & {
	type: "network";
};

export type GatewayHttpsData = NodeData & {
	readonly?: boolean;
	network?: string;
	subdomain?: string;
	https?: PortConnectedTo;
	auth?: {
		enabled: boolean;
		groups: string[];
		noAuthPathPatterns: string[];
	};
};

export type GatewayHttpsNode = Node<GatewayHttpsData> & {
	type: "gateway-https";
};

export type GatewayTCPData = NodeData & {
	readonly?: boolean;
	network?: string;
	subdomain?: string;
	exposed: PortConnectedTo[];
	selected?: {
		serviceId?: string;
		portId?: string;
	};
};

export type GatewayTCPNode = Node<GatewayTCPData> & {
	type: "gateway-tcp";
};

export type Port = {
	id: string;
	name: string;
	value: number;
};

export const ServiceTypes = [
	"deno:2.2.0",
	"golang:1.20.0",
	"golang:1.22.0",
	"golang:1.24.0",
	"hugo:latest",
	"php:8.2-apache",
	"nextjs:deno-2.0.0",
	"node-23.1.0",
] as const;
export type ServiceType = (typeof ServiceTypes)[number];

export type Domain = {
	network: string;
	subdomain: string;
};

export type ServiceData = NodeData & {
	type: ServiceType;
	repository:
		| {
				id: string;
		  }
		| {
				id: string;
				branch: string;
		  }
		| {
				id: string;
				branch: string;
				rootDir: string;
		  };
	env: string[];
	volume: string[];
	preBuildCommands: string;
	isChoosingPortToConnect: boolean;
	dev?:
		| {
				enabled: false;
				expose?: Domain;
		  }
		| {
				enabled: true;
				expose?: Domain;
				codeServerNodeId: string;
				sshNodeId: string;
		  };
};

export type ServiceNode = Node<ServiceData> & {
	type: "app";
};

export type VolumeType = "ReadWriteOnce" | "ReadOnlyMany" | "ReadWriteMany" | "ReadWriteOncePod";

export type VolumeData = NodeData & {
	type: VolumeType;
	size: string;
	attachedTo: string[];
};

export type VolumeNode = Node<VolumeData> & {
	type: "volume";
};

export type PostgreSQLData = NodeData & {
	volumeId: string;
};

export type PostgreSQLNode = Node<PostgreSQLData> & {
	type: "postgresql";
};

export type MongoDBData = NodeData & {
	volumeId: string;
};

export type MongoDBNode = Node<MongoDBData> & {
	type: "mongodb";
};

export type GithubData = NodeData & {
	repository?: {
		id: number;
		sshURL: string;
		fullName: string;
	};
};

export type GithubNode = Node<GithubData> & {
	type: "github";
};

export type NANode = Node<NodeData> & {
	type: undefined;
};

export type AppNode =
	| NetworkNode
	| GatewayHttpsNode
	| GatewayTCPNode
	| ServiceNode
	| VolumeNode
	| PostgreSQLNode
	| MongoDBNode
	| GithubNode
	| NANode;

export function nodeLabel(n: AppNode): string {
	try {
		switch (n.type) {
			case "network":
				return n.data.domain;
			case "app":
				return n.data.label || "Service";
			case "github":
				return n.data.repository?.fullName || "Github";
			case "gateway-https": {
				if (n.data && n.data.subdomain) {
					return `${n.data.subdomain}`;
				} else {
					return "HTTPS Gateway";
				}
			}
			case "gateway-tcp": {
				if (n.data && n.data.subdomain) {
					return `${n.data.subdomain}`;
				} else {
					return "TCP Gateway";
				}
			}
			case "mongodb":
				return n.data.label || "MongoDB";
			case "postgresql":
				return n.data.label || "PostgreSQL";
			case "volume":
				return n.data.label || "Volume";
			case undefined:
				throw new Error("MUST NOT REACH!");
		}
	} catch (e) {
		console.error("opaa", e);
	} finally {
		console.log("done");
	}
}

export function nodeIsConnectable(n: AppNode, handle: string): boolean {
	switch (n.type) {
		case "network":
			return true;
		case "app":
			if (handle === "ports") {
				return n.data !== undefined && n.data.ports !== undefined && n.data.ports.length > 0;
			} else if (handle === "repository") {
				if (!n.data || !n.data.repository || !n.data.repository.id) {
					return true;
				}
				return false;
			}
			return false;
		case "github":
			if (n.data.repository?.id !== undefined) {
				return true;
			}
			return false;
		case "gateway-https":
			if (handle === "subdomain") {
				return n.data.network === undefined;
			}
			return n.data === undefined || n.data.https === undefined;
		case "gateway-tcp":
			if (handle === "subdomain") {
				return n.data.network === undefined;
			}
			return true;
		case "mongodb":
			return true;
		case "postgresql":
			return true;
		case "volume":
			if (n.data === undefined || n.data.type === undefined) {
				return false;
			}
			if (n.data.type === "ReadWriteOnce" || n.data.type === "ReadWriteOncePod") {
				return n.data.attachedTo === undefined || n.data.attachedTo.length === 0;
			}
			return true;
		case undefined:
			throw new Error("MUST NOT REACH!");
	}
}

export type BoundEnvVar =
	| {
			id: string;
			source: string | null;
	  }
	| {
			id: string;
			source: string | null;
			name: string;
			isEditting: boolean;
	  }
	| {
			id: string;
			source: string | null;
			name: string;
			alias: string;
			isEditting: boolean;
	  }
	| {
			id: string;
			source: string | null;
			portId: string;
			name: string;
			alias: string;
			isEditting: boolean;
	  };

export type EnvVar = {
	name: string;
	value: string;
};

export function nodeEnvVarNamePort(n: AppNode, portName: string): string {
	return `DODO_SERVICE_${n.data.label.toUpperCase()}_ADDRESS_${portName.toUpperCase()}`;
}

export function nodeEnvVarNames(n: AppNode): string[] {
	switch (n.type) {
		case "app":
			return [
				`DODO_SERVICE_${n.data.label.toUpperCase()}_ADDRESS`,
				...(n.data.ports || []).map((p) => nodeEnvVarNamePort(n, p.name)),
			];
		case "github":
			return [];
		case "gateway-https":
			return [];
		case "gateway-tcp":
			return [];
		case "mongodb":
			return [`DODO_MONGODB_${n.data.label.toUpperCase()}_URL`];
		case "postgresql":
			return [`DODO_POSTGRESQL_${n.data.label.toUpperCase()}_URL`];
		case "volume":
			return [`DODO_VOLUME_${n.data.label.toUpperCase()}_PATH`];
		case undefined:
			throw new Error("MUST NOT REACH");
		default:
			throw new Error("MUST NOT REACH");
	}
}

export type NodeType = Exclude<Pick<AppNode, "type">["type"], undefined>;

export type MessageType = "INFO" | "WARNING" | "FATAL";

export type Message = {
	id: string;
	type: MessageType;
	nodeId?: string;
	message: string;
	onHighlight?: (state: AppState) => void;
	onLooseHighlight?: (state: AppState) => void;
	onClick?: (state: AppState) => void;
};

export const envSchema = z.object({
	managerAddr: z.optional(z.string().min(1)),
	deployKey: z.optional(z.nullable(z.string().min(1))),
	networks: z
		.array(
			z.object({
				name: z.string().min(1),
				domain: z.string().min(1),
			}),
		)
		.default([]),
	integrations: z.object({
		github: z.boolean(),
	}),
	services: z.array(z.string()),
	user: z.object({
		id: z.string(),
		username: z.string(),
	}),
});

export type Env = z.infer<typeof envSchema>;

const defaultEnv: Env = {
	managerAddr: undefined,
	deployKey: undefined,
	networks: [],
	integrations: {
		github: false,
	},
	services: [],
	user: {
		id: "",
		username: "",
	},
};

export type Project = {
	id: string;
	name: string;
};

export type IntegrationsConfig = {
	github: boolean;
};

type NodeUpdate<T extends NodeType> = DeepPartial<Extract<AppNode, { type: T }>>;
type NodeDataUpdate<T extends NodeType> = DeepPartial<Extract<AppNode, { type: T }>["data"]>;

type Viewport = {
	transformX: number;
	transformY: number;
	transformZoom: number;
	width: number;
	height: number;
};

export type AppState = {
	projectId: string | undefined;
	mode: "edit" | "deploy";
	projects: Project[];
	nodes: AppNode[];
	edges: Edge[];
	zoom: ReactFlowViewport;
	categories: Category[];
	messages: Message[];
	env: Env;
	viewport: Viewport;
	setViewport: (viewport: Viewport) => void;
	githubService: GitHubService | null;
	setHighlightCategory: (name: string, active: boolean) => void;
	onNodesChange: OnNodesChange<AppNode>;
	onEdgesChange: OnEdgesChange;
	onConnect: OnConnect;
	addNode: (node: Omit<AppNode, "position">) => void;
	setNodes: (nodes: AppNode[]) => void;
	setEdges: (edges: Edge[]) => void;
	setProject: (projectId: string | undefined) => Promise<void>;
	setMode: (mode: "edit" | "deploy") => void;
	updateNode: <T extends NodeType>(id: string, node: NodeUpdate<T>) => void;
	updateNodeData: <T extends NodeType>(id: string, data: NodeDataUpdate<T>) => void;
	replaceEdge: (c: Connection, id?: string) => void;
	refreshEnv: () => Promise<void>;
};

const projectIdSelector = (state: AppState) => state.projectId;
const categoriesSelector = (state: AppState) => state.categories;
const messagesSelector = (state: AppState) => state.messages;
const githubServiceSelector = (state: AppState) => state.githubService;
const envSelector = (state: AppState) => state.env;
const zoomSelector = (state: AppState) => state.zoom;

export function useZoom(): ReactFlowViewport {
	return useStateStore(zoomSelector);
}

export function useProjectId(): string | undefined {
	return useStateStore(projectIdSelector);
}

export function useCategories(): Category[] {
	return useStateStore(categoriesSelector);
}

export function useMessages(): Message[] {
	return useStateStore(messagesSelector);
}

export function useNodeMessages(id: string): Message[] {
	return useMessages().filter((m) => m.nodeId === id);
}

export function useNodeLabel(id: string): string {
	return nodeLabel(useNodes<AppNode>().find((n) => n.id === id)!);
}

export function useNodePortName(id: string, portId: string): string {
	return (useNodes<AppNode>().find((n) => n.id === id)!.data.ports || []).find((p) => p.id === portId)!.name;
}

export function useEnv(): Env {
	return useStateStore(envSelector);
}

export function useGithubService(): GitHubService | null {
	return useStateStore(githubServiceSelector);
}

const v: Validator = CreateValidators();

function getRandomPosition({ width, height, transformX, transformY, transformZoom }: Viewport): XYPosition {
	const zoomMultiplier = 1 / transformZoom;
	const realWidth = width * zoomMultiplier;
	const realHeight = height * zoomMultiplier;
	const paddingMultiplier = 0.8;
	const ret = {
		x: -transformX * zoomMultiplier + Math.random() * realWidth * paddingMultiplier,
		y: -transformY * zoomMultiplier + Math.random() * realHeight * paddingMultiplier,
	};
	return ret;
}

export const useStateStore = create<AppState>((set, get): AppState => {
	const setN = (nodes: AppNode[]) => {
		set({
			nodes,
			messages: v(nodes),
		});
	};

	const injectNetworkNodes = () => {
		const newNetworks = get().env.networks.filter(
			(x) => !get().nodes.some((n) => n.type === "network" && n.data.domain === x.domain),
		);
		newNetworks.forEach((n) => {
			get().addNode({
				id: n.domain,
				type: "network",
				connectable: true,
				data: {
					domain: n.domain,
					label: n.domain,
					envVars: [],
					ports: [],
					state: "success", // TODO(gio): monitor network health
				},
			});
			console.log("added network", n.domain);
		});
	};

	const restoreSaved = async () => {
		const { projectId } = get();
		const resp = await fetch(`/api/project/${projectId}/saved/${get().mode === "deploy" ? "deploy" : "draft"}`, {
			method: "GET",
		});
		const inst = await resp.json();
		setN(inst.nodes);
		set({ edges: inst.edges });
		injectNetworkNodes();
		if (
			get().zoom.x !== inst.viewport.x ||
			get().zoom.y !== inst.viewport.y ||
			get().zoom.zoom !== inst.viewport.zoom
		) {
			set({ zoom: inst.viewport });
		}
	};

	function updateNodeData<T extends NodeType>(id: string, data: NodeDataUpdate<T>): void {
		setN(
			get().nodes.map((n) => {
				if (n.id === id) {
					return {
						...n,
						data: {
							...n.data,
							...data,
						},
					} as Extract<AppNode, { type: T }>;
				}
				return n;
			}),
		);
	}

	function updateNode<T extends NodeType>(id: string, node: NodeUpdate<T>): void {
		setN(
			get().nodes.map((n) => {
				if (n.id === id) {
					return {
						...n,
						...node,
					} as Extract<AppNode, { type: T }>;
				}
				return n;
			}),
		);
	}

	function onConnect(c: Connection) {
		const { nodes, edges } = get();
		set({
			edges: addEdge(c, edges),
		});
		const sn = nodes.filter((n) => n.id === c.source)[0]!;
		const tn = nodes.filter((n) => n.id === c.target)[0]!;
		if (tn.type === "network") {
			if (sn.type === "gateway-https") {
				updateNodeData<"gateway-https">(sn.id, {
					network: tn.data.domain,
				});
			} else if (sn.type === "gateway-tcp") {
				updateNodeData<"gateway-tcp">(sn.id, {
					network: tn.data.domain,
				});
			}
		}
		if (tn.type === "app") {
			if (c.sourceHandle === "env_var" && c.targetHandle === "env_var") {
				const sourceEnvVars = nodeEnvVarNames(sn);
				if (sourceEnvVars.length === 0) {
					throw new Error("MUST NOT REACH!");
				}
				const id = uuidv4();
				if (sourceEnvVars.length === 1) {
					updateNode<"app">(c.target, {
						...tn,
						data: {
							...tn.data,
							envVars: [
								...(tn.data.envVars || []),
								{
									id: id,
									source: c.source,
									name: sourceEnvVars[0],
									isEditting: false,
								},
							],
						},
					});
				} else {
					updateNode<"app">(c.target, {
						...tn,
						data: {
							...tn.data,
							envVars: [
								...(tn.data.envVars || []),
								{
									id: id,
									source: c.source,
								},
							],
						},
					});
				}
			}
			if (c.sourceHandle === "ports" && c.targetHandle === "env_var") {
				const sourcePorts = sn.data.ports || [];
				const id = uuidv4();
				if (sourcePorts.length === 1) {
					updateNode<"app">(c.target, {
						...tn,
						data: {
							...tn.data,
							envVars: [
								...(tn.data.envVars || []),
								{
									id: id,
									source: c.source,
									name: nodeEnvVarNamePort(sn, sourcePorts[0].name),
									portId: sourcePorts[0].id,
									isEditting: false,
								},
							],
						},
					});
				}
			}
		}
		if (c.sourceHandle === "volume") {
			updateNodeData<"volume">(c.source, {
				attachedTo: ((sn as VolumeNode).data.attachedTo || []).concat(c.source),
			});
		}
		if (c.targetHandle === "volume") {
			if (tn.type === "postgresql" || tn.type === "mongodb") {
				updateNodeData(c.target, {
					volumeId: c.source,
				});
			}
		}
		if (c.targetHandle === "https") {
			if ((sn.data.ports || []).length === 1) {
				updateNodeData<"gateway-https">(c.target, {
					https: {
						serviceId: c.source,
						portId: sn.data.ports![0].id,
					},
				});
			} else {
				updateNodeData<"gateway-https">(c.target, {
					https: {
						serviceId: c.source,
						portId: "", // TODO(gio)
					},
				});
			}
		}
		if (c.targetHandle === "tcp") {
			const td = tn.data as GatewayTCPData;
			if ((sn.data.ports || []).length === 1) {
				updateNodeData<"gateway-tcp">(c.target, {
					exposed: (td.exposed || []).concat({
						serviceId: c.source,
						portId: sn.data.ports![0].id,
					}),
				});
			} else {
				updateNodeData<"gateway-tcp">(c.target, {
					selected: {
						serviceId: c.source,
						portId: undefined,
					},
				});
			}
		}
		if (sn.type === "app") {
			if (c.sourceHandle === "ports") {
				updateNodeData<"app">(sn.id, {
					isChoosingPortToConnect: true,
				});
			}
		}
		if (tn.type === "app") {
			if (c.targetHandle === "repository") {
				updateNodeData<"app">(tn.id, {
					repository: {
						id: c.source,
						branch: "master",
						rootDir: "/",
					},
				});
			}
		}
	}
	return {
		projectId: undefined,
		mode: "edit",
		projects: [],
		nodes: [],
		edges: [],
		categories: defaultCategories,
		messages: v([]),
		env: defaultEnv,
		viewport: {
			transformX: 0,
			transformY: 0,
			transformZoom: 1,
			width: 800,
			height: 600,
		},
		zoom: {
			x: 0,
			y: 0,
			zoom: 1,
		},
		githubService: null,
		setViewport: (viewport) => {
			const { viewport: vp } = get();
			if (
				viewport.transformX !== vp.transformX ||
				viewport.transformY !== vp.transformY ||
				viewport.transformZoom !== vp.transformZoom ||
				viewport.width !== vp.width ||
				viewport.height !== vp.height
			) {
				set({ viewport });
			}
		},
		setHighlightCategory: (name, active) => {
			set({
				categories: get().categories.map((c) => {
					if (c.title.toLowerCase() !== name.toLowerCase()) {
						return c;
					} else {
						return {
							...c,
							active,
						};
					}
				}),
			});
		},
		onNodesChange: (changes) => {
			const nodes = applyNodeChanges(changes, get().nodes);
			setN(nodes);
		},
		onEdgesChange: (changes) => {
			set({
				edges: applyEdgeChanges(changes, get().edges),
			});
		},
		addNode: (node) => {
			const { viewport, nodes } = get();
			setN(
				nodes.concat({
					...node,
					position: getRandomPosition(viewport),
				}),
			);
		},
		setNodes: (nodes) => {
			setN(nodes);
		},
		setEdges: (edges) => {
			set({ edges });
		},
		replaceEdge: (c, id) => {
			let change: EdgeChange;
			if (id === undefined) {
				change = {
					type: "add",
					item: {
						id: uuidv4(),
						...c,
					},
				};
				onConnect(c);
			} else {
				change = {
					type: "replace",
					id,
					item: {
						id,
						...c,
					},
				};
			}
			set({
				edges: applyEdgeChanges([change], get().edges),
			});
		},
		updateNode,
		updateNodeData,
		onConnect,
		refreshEnv: async () => {
			const projectId = get().projectId;
			let env: Env = defaultEnv;

			try {
				if (projectId) {
					const response = await fetch(`/api/project/${projectId}/env`);
					if (response.ok) {
						const data = await response.json();
						const result = envSchema.safeParse(data);
						if (result.success) {
							env = result.data;
						} else {
							console.error("Invalid env data:", result.error);
						}
					}
				}
			} catch (error) {
				console.error("Failed to fetch integrations:", error);
			} finally {
				if (JSON.stringify(get().env) !== JSON.stringify(env)) {
					set({ env });
					injectNetworkNodes();

					if (env.integrations.github) {
						set({ githubService: new GitHubServiceImpl(projectId!) });
					} else {
						set({ githubService: null });
					}
				}
			}
		},
		setMode: (mode) => {
			set({ mode });
		},
		setProject: async (projectId) => {
			if (projectId === get().projectId) {
				return;
			}
			set({
				projectId,
			});
			if (projectId) {
				await get().refreshEnv();
				if (get().env.deployKey) {
					set({ mode: "deploy" });
				} else {
					set({ mode: "edit" });
				}
				restoreSaved();
			} else {
				set({
					nodes: [],
					edges: [],
				});
			}
		},
	};
});
