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

export const DeployResponseSchema = z.object({
	id: z.string(),
	deployKey: z.string(),
});

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<boolean> {
		const response = await axios.request({
			url: `${this.baseUrl}/api/dodo-app/${instanceId}`,
			method: "put",
			data: { config },
		});
		return response.status === 200;
	}

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