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

export const GithubRepositorySchema = z.object({
	id: z.number(),
	name: z.string(),
	full_name: z.string(),
	html_url: z.string(),
	ssh_url: z.string(),
});

const DeployKeysSchema = z.array(
	z.object({
		id: z.number(),
		key: z.string(),
	}),
);

const WebhookSchema = z.object({
	id: z.number(),
	config: z.object({
		url: z.string().optional(), // url might not always be present
		content_type: z.string().optional(),
	}),
	events: z.array(z.string()),
	active: z.boolean(),
});

const ListWebhooksResponseSchema = z.array(WebhookSchema);

export type GithubRepository = z.infer<typeof GithubRepositorySchema>;

export class GithubClient {
	private token: string;

	constructor(token: string) {
		this.token = token;
	}

	private getHeaders() {
		return {
			Authorization: `Bearer ${this.token}`,
			Accept: "application/vnd.github.v3+json",
			"X-GitHub-Api-Version": "2022-11-28",
		};
	}

	async getRepositories(): Promise<GithubRepository[]> {
		const response = await axios.get("https://api.github.com/user/repos", {
			headers: this.getHeaders(),
		});
		return z.array(GithubRepositorySchema).parse(response.data);
	}

	async addDeployKey(repoPath: string, key: string) {
		const sshUrl = repoPath;
		const repoOwnerAndName = sshUrl.replace("git@github.com:", "").replace(".git", "");
		await axios.post(
			`https://api.github.com/repos/${repoOwnerAndName}/keys`,
			{
				title: "dodo",
				key: key,
				read_only: true,
			},
			{
				headers: this.getHeaders(),
			},
		);
	}

	async removeDeployKey(repoPath: string, key: string) {
		const sshUrl = repoPath;
		const repoOwnerAndName = sshUrl.replace("git@github.com:", "").replace(".git", "");
		const response = await axios.get(`https://api.github.com/repos/${repoOwnerAndName}/keys`, {
			headers: this.getHeaders(),
		});
		const result = DeployKeysSchema.safeParse(response.data);
		if (!result.success) {
			throw new Error("Failed to parse deploy keys response");
		}
		const deployKeys = result.data.filter((k) => k.key === key);
		await Promise.all(
			deployKeys.map((deployKey) =>
				axios.delete(`https://api.github.com/repos/${repoOwnerAndName}/keys/${deployKey.id}`, {
					headers: this.getHeaders(),
				}),
			),
		);
	}

	async addPushWebhook(repoPath: string, callbackAddress: string): Promise<boolean> {
		const repoOwnerAndName = repoPath.replace("git@github.com:", "").replace(".git", "");
		const resp = await axios.post(
			`https://api.github.com/repos/${repoOwnerAndName}/hooks`,
			{
				name: "web",
				active: true,
				events: ["push"],
				config: {
					url: callbackAddress,
					content_type: "json",
				},
			},
			{
				headers: this.getHeaders(),
			},
		);
		return resp.status === 201;
	}

	async removePushWebhook(repoPath: string, callbackAddress: string): Promise<boolean> {
		const repoOwnerAndName = repoPath.replace("git@github.com:", "").replace(".git", "");
		const listHooksUrl = `https://api.github.com/repos/${repoOwnerAndName}/hooks`;
		try {
			const response = await axios.get(listHooksUrl, {
				headers: this.getHeaders(),
			});
			const parsedHooks = ListWebhooksResponseSchema.safeParse(response.data);
			if (!parsedHooks.success) {
				throw new Error(`Failed to parse webhooks list for ${repoOwnerAndName}`);
			}
			const results = await Promise.all(
				parsedHooks.data
					.filter((hook) => hook.config.url === callbackAddress && hook.events.includes("push"))
					.map(async (hook) => {
						const deleteHookUrl = `https://api.github.com/repos/${repoOwnerAndName}/hooks/${hook.id}`;
						const resp = await axios.delete(deleteHookUrl, { headers: this.getHeaders() });
						return resp.status === 204;
					}),
			);
			return results.reduce((acc, curr) => acc && curr, true);
			// eslint-disable-next-line @typescript-eslint/no-explicit-any
		} catch (error: any) {
			console.error(
				`Failed to list or remove webhooks for ${repoOwnerAndName}:`,
				error.response?.data || error.message,
			);
			throw error; // Re-throw to let the caller handle it
		}
	}
}
