import axios from "axios";
import { z } from "zod";

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 DeployResponseSchema = z.object({
	id: z.string(),
	deployKey: z.string(),
	access: z.array(accessSchema),
});

export type DeployResponse = z.infer<typeof DeployResponseSchema>;

export class AppManager {
	private baseUrl: string;

	constructor(baseUrl: string = "http://appmanager.hgrz-appmanager.svc.cluster.local") {
		this.baseUrl = baseUrl;
	}

	async deploy(config: unknown): Promise<DeployResponse> {
		const response = await axios.request({
			url: `${this.baseUrl}/api/dodo-app`,
			method: "post",
			data: { config },
		});
		if (response.status !== 200) {
			throw new Error(`Failed to deploy application: ${response.statusText}`);
		}
		const result = DeployResponseSchema.safeParse(response.data);
		if (!result.success) {
			throw new Error(`Invalid deploy response format: ${result.error.message}`);
		}
		return result.data;
	}

	async update(instanceId: string, config: unknown): Promise<DeployResponse> {
		const response = await axios.request({
			url: `${this.baseUrl}/api/dodo-app/${instanceId}`,
			method: "put",
			data: { config },
		});
		if (response.status !== 200) {
			throw new Error(`Failed to update application: ${response.statusText}`);
		}
		const result = DeployResponseSchema.safeParse(response.data);
		if (!result.success) {
			throw new Error(`Invalid update response format: ${result.error.message}`);
		}
		return result.data;
	}

	async getStatus(instanceId: string): Promise<unknown> {
		const response = await axios.request({
			url: `${this.baseUrl}/api/instance/${instanceId}/status`,
			method: "get",
		});
		if (response.status !== 200) {
			throw new Error(`Failed to get application status: ${response.statusText}`);
		}
		return response.data;
	}

	async removeInstance(instanceId: string): Promise<boolean> {
		const response = await axios.request({
			url: `${this.baseUrl}/api/instance/${instanceId}/remove`,
			method: "post",
		});
		return response.status === 200;
	}
}
