import z from "zod";
import { env } from "~/env";

const FileMetadataSchema = z.object({
	id: z.string(),
	originalName: z.string(),
	size: z.number(),
	mimeType: z.string(),
	blockCount: z.number(),
	uploadedAt: z.string(),
	expiresAt: z.string().nullable(),
});

export type FileMetadata = z.infer<typeof FileMetadataSchema>;

export type FileMetadataWithAdmin = FileMetadata & {
	from_admin: boolean;
};

// Helper to fetch the list of all files
export async function fetchFiles(): Promise<FileMetadata[]> {
	try {
		const response = await fetch(
			`${env.STORAGE_URL}/bucket/storage?token=${env.STORAGE_TOKEN}`,
		);
		if (!response.ok) {
			console.error("Failed to fetch file list:", response.statusText);
			return [];
		}
		const parse = FileMetadataSchema.array().safeParse(await response.json());

		if (parse.success) {
			return parse.data;
		}
		console.error("Failed to parse file metadata:", parse.error);
		return [];
	} catch (error) {
		console.error("Error fetching file list:", error);
		return [];
	}
}

export async function getFileInfo(id: string): Promise<FileMetadata | null> {
	try {
		const response = await fetch(
			`${env.STORAGE_URL}/info/${id}?token=${env.STORAGE_TOKEN}`,
		);
		if (!response.ok) {
			console.error("Failed to fetch file list:", response.statusText);
			return null;
		}
		const parse = FileMetadataSchema.safeParse(await response.json());

		if (parse.success) {
			return parse.data;
		}
		console.error("Failed to parse file metadata:", parse.error);
		return null;
	} catch (error) {
		console.error("Error fetching file list:", error);
		return null;
	}
}

type EditResponse =
	| {
			success: true;
			id: string;
	  }
	| {
			success: false;
			error: string;
	  };
export async function editFile(
	id: string,
	filename?: string,
	expiresAt?: string,
): Promise<EditResponse> {
	const formData = new FormData();
	formData.append("id", id);
	if (expiresAt) {
		formData.append("expires_at", expiresAt);
	}
	if (filename) {
		formData.append("filename", filename);
	}

	try {
		const response = await fetch(
			`${env.STORAGE_URL}/edit?token=${env.STORAGE_TOKEN}`,
			{
				method: "POST",
				body: formData,
			},
		);

		if (response.ok) {
			const res = await response.json();
			const parsed = z
				.object({
					id: z.string(),
				})
				.parse(res);
			const fileID = parsed.id;

			return { success: true, id: fileID };
		}

		return {
			success: false,
			error: `Modifica fallita con status: ${response.status}`,
		};
	} catch (e) {
		return {
			success: false,
			error: `Errore Modifica file: ${(e as Error).message}`,
		};
	}
}

type DeleteResponse =
	| {
			success: true;
	  }
	| {
			success: false;
			error: string;
	  };
// Helper to handle file deletion
export async function deleteFile(fileID: string): Promise<DeleteResponse> {
	try {
		// The Go server accepts POST with form data for delete
		const response = await fetch(
			`${env.STORAGE_URL}/delete/${fileID}?token=${env.STORAGE_TOKEN}`,
			{
				method: "DELETE",
			},
		);

		// Treat redirect as success
		if (response.ok || (response.status >= 300 && response.status < 400)) {
			return { success: true };
		}

		return {
			success: false,
			error: `Eliminazione fallita con status: ${response.status}`,
		};
	} catch (error) {
		console.error("Error during file deletion:", error);
		return { success: false, error: (error as Error).message };
	}
}

// export const handleDownload = async (file: FileMetadata) => {
// 	try {
// 		const response = await fetch(
// 			`${env.STORAGE_URL}/get/${file.id}?token=${env.STORAGE_TOKEN}&mode=download`,
// 		);

// 		if (!response.ok) {
// 			throw new Error("File fetch failed");
// 		}

// 		const blob = await response.blob();
// 		const url = window.URL.createObjectURL(blob);
// 		const a = document.createElement("a");
// 		a.href = url;
// 		a.download = file.originalName;
// 		document.body.appendChild(a);
// 		a.click();
// 		a.remove();
// 		window.URL.revokeObjectURL(url);
// 	} catch {
// 		throw new Error("File download failed");
// 	}
// };

const safeRetrive = z.object({
	available: z.array(FileMetadataSchema),
	unavailable: z.array(z.string()),
});

export async function retriveFilesSafely(ids: string[]) {
	try {
		const response = await fetch(
			`${env.STORAGE_URL}/files-check?token=${env.STORAGE_TOKEN}`,
			{
				method: "POST",
				headers: {
					"Content-Type": "application/json",
				},
				body: JSON.stringify(ids),
			},
		);

		if (!response.ok) {
			throw new Error("File fetch failed");
		}
		const parse = safeRetrive.safeParse(await response.json());

		if (parse.success) {
			return parse.data;
		}
		throw new Error("File fetch parse failed");
	} catch (e) {
		throw new Error(`File fetch failed: ${(e as Error).message}`);
	}
}
