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",
	"nodejs:23.1.0",
	"nodejs:24.0.2",
] 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");
	}
	return "Unknown Node";
}

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 accessSchema = z.discriminatedUnion("type", [
	z.object({
		type: z.literal("https"),
		name: z.string(),
		address: z.string(),
	}),
	z.object({
		type: z.literal("ssh"),
		name: z.string(),
		host: z.string(),
		port: z.number(),
	}),
	z.object({
		type: z.literal("tcp"),
		name: z.string(),
		host: z.string(),
		port: z.number(),
	}),
	z.object({
		type: z.literal("udp"),
		name: z.string(),
		host: z.string(),
		port: z.number(),
	}),
	z.object({
		type: z.literal("postgresql"),
		name: z.string(),
		host: z.string(),
		port: z.number(),
		database: z.string(),
		username: z.string(),
		password: z.string(),
	}),
	z.object({
		type: z.literal("mongodb"),
		name: z.string(),
		host: z.string(),
		port: z.number(),
		database: z.string(),
		username: z.string(),
		password: z.string(),
	}),
]);

export const serviceInfoSchema = z.object({
	name: z.string(),
	workers: z.array(
		z.object({
			id: z.string(),
			commit: z.optional(
				z.object({
					hash: z.string(),
					message: z.string(),
				}),
			),
			commands: z.optional(
				z.array(
					z.object({
						command: z.string(),
						state: z.string(),
					}),
				),
			),
		}),
	),
});

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),
				hasAuth: z.boolean(),
			}),
		)
		.default([]),
	integrations: z.object({
		github: z.boolean(),
	}),
	services: z.array(serviceInfoSchema),
	user: z.object({
		id: z.string(),
		username: z.string(),
	}),
	access: z.array(accessSchema),
});

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

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

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

let refreshEnvIntervalId: number | null = null;

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 useSetProject(): (projectId: string | undefined) => void {
	return useStateStore((state) => state.setProject);
}

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

export function useMode(): "edit" | "deploy" {
	return useStateStore((state) => state.mode);
}

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 startRefreshEnvInterval = () => {
		if (refreshEnvIntervalId) {
			clearInterval(refreshEnvIntervalId);
		}
		if (get().projectId && typeof document !== "undefined" && document.visibilityState === "visible") {
			console.log("Starting refreshEnv interval for project:", get().projectId);
			refreshEnvIntervalId = setInterval(async () => {
				if (get().projectId && typeof document !== "undefined" && document.visibilityState === "visible") {
					console.log("Interval: Calling refreshEnv for project:", get().projectId);
					await get().refreshEnv();
				} else if (refreshEnvIntervalId) {
					console.log(
						"Interval: Conditions not met (project removed or tab hidden), stopping interval from inside.",
					);
					clearInterval(refreshEnvIntervalId);
					refreshEnvIntervalId = null;
				}
			}, 5000) as unknown as number;
		} else {
			console.log(
				"Not starting refreshEnv interval. Project ID:",
				get().projectId,
				"Visibility:",
				typeof document !== "undefined" ? document.visibilityState : "SSR",
			);
		}
	};

	const stopRefreshEnvInterval = () => {
		if (refreshEnvIntervalId) {
			console.log("Stopping refreshEnv interval for project:", get().projectId);
			clearInterval(refreshEnvIntervalId);
			refreshEnvIntervalId = null;
		}
	};

	if (typeof document !== "undefined") {
		document.addEventListener("visibilitychange", () => {
			if (document.visibilityState === "visible") {
				console.log("Tab became visible, attempting to start refreshEnv interval.");
				startRefreshEnvInterval();
			} else {
				console.log("Tab became hidden, stopping refreshEnv interval.");
				stopRefreshEnvInterval();
			}
		});
	}

	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),
				} as AppNode),
			);
		},
		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) => {
			const currentProjectId = get().projectId;
			if (projectId === currentProjectId) {
				return;
			}
			stopRefreshEnvInterval();
			set({
				projectId,
			});
			if (projectId) {
				await get().refreshEnv();
				if (get().env.deployKey) {
					set({ mode: "deploy" });
				} else {
					set({ mode: "edit" });
				}
				restoreSaved();
				startRefreshEnvInterval();
			} else {
				set({
					nodes: [],
					edges: [],
					env: defaultEnv,
					githubService: null,
				});
			}
		},
	};
});
