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 & {
	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 & {
	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 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;
};

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 {
	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.network && n.data.subdomain) {
				return `https://${n.data.subdomain}.${n.data.network}`;
			} else {
				return "HTTPS Gateway";
			}
		}
		case "gateway-tcp": {
			if (n.data && n.data.network && n.data.subdomain) {
				return `${n.data.subdomain}.${n.data.network}`;
			} 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!");
	}
}

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()),
});

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

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

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 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 || [] });
		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 });
					const newNetworks = 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
							},
						});
					});

					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: [],
				});
			}
		},
	};
});
