import type { printJobs } from "@/server/db/schema";
import type { InferResultType } from "@/utils/drizzle";
import type { InferSelectModel } from "drizzle-orm";

export interface PrinterErrorRate {
	printerId: string;
	name: string;
	errorRate: number; // Error rate as a percentage (0-100)
}

/**
 * Calculates the error rate for print jobs aggregated by printer as a percentage.
 *
 * @param pJobs - Array of print job objects.
 * @returns An array of PrinterErrorRate objects, each containing the printer ID and its error rate.
 */
export function calculatePrinterErrorRate(
	pJobs: InferResultType<"printJobs", { printer: true }>[],
): PrinterErrorRate[] {
	if (pJobs.length === 0) {
		return []; // No jobs, no data.
	}
	const printers = pJobs.map((job) => job.printer);

	// Group jobs by printer ID
	const jobsByPrinter: Record<string, InferSelectModel<typeof printJobs>[]> = pJobs.reduce(
		(acc, job) => {
			if (!acc[job.printerId]) {
				acc[job.printerId] = [];
			}
			acc[job.printerId].push(job);
			return acc;
		},
		{} as Record<string, InferSelectModel<typeof printJobs>[]>,
	);

	// Calculate the error rate for each printer
	const printerErrorRates: PrinterErrorRate[] = Object.entries(jobsByPrinter).map(([printerId, jobs]) => {
		const totalJobs = jobs.length;
		const abortedJobsCount = jobs.filter((job) => job.aborted).length;
		const errorRate = (abortedJobsCount / totalJobs) * 100;

		const printer = printers.find((printer) => printer.id === printerId);
		const printerName = printer ? printer.name : "Unbekannter Drucker";

		return {
			printerId,
			name: printerName,
			errorRate: Number.parseFloat(errorRate.toFixed(2)), // Rounded to two decimal places
		};
	});

	return printerErrorRates;
}
