import { Category, defaultCategories } from "./categories";
import { CreateValidators, Validator } from "./config";
import { GitHubService, GitHubServiceImpl } from "./github";
import type { Edge, Node, OnConnect, OnEdgesChange, OnNodesChange } from "@xyflow/react";
import { addEdge, applyEdgeChanges, applyNodeChanges, Connection, EdgeChange, useNodes } 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;
	};
};

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?.sshURL || "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.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(),
	}),
});

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

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

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"]>;

export type AppState = {
	projectId: string | undefined;
	projects: Project[];
	nodes: AppNode[];
	edges: Edge[];
	categories: Category[];
	messages: Message[];
	env: Env;
	githubService: GitHubService | null;
	setHighlightCategory: (name: string, active: boolean) => void;
	onNodesChange: OnNodesChange<AppNode>;
	onEdgesChange: OnEdgesChange;
	onConnect: OnConnect;
	setNodes: (nodes: AppNode[]) => void;
	setEdges: (edges: Edge[]) => void;
	setProject: (projectId: string | undefined) => 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;

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

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

	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,
		projects: [],
		nodes: [],
		edges: [],
		categories: defaultCategories,
		messages: v([]),
		env: defaultEnv,
		githubService: null,
		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),
			});
		},
		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 {
				set({ env: env });
				if (env.integrations.github) {
					set({ githubService: new GitHubServiceImpl(projectId!) });
				} else {
					set({ githubService: null });
				}
			}
		},
		setProject: (projectId) => {
			set({
				projectId,
			});
			if (projectId) {
				get().refreshEnv();
			}
		},
	};
});
