import { AbortReasonsBarChart } from "@/app/admin/charts/abort-reasons";
import { LoadFactorChart } from "@/app/admin/charts/load-factor";
import { PrintJobsDonut } from "@/app/admin/charts/printjobs-donut";
import { DataCard } from "@/components/data-card";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { db } from "@/server/db";
import type { Metadata } from "next";

export const metadata: Metadata = {
	title: "Admin Dashboard",
};

export const dynamic = "force-dynamic";

export default async function AdminPage() {
	const allPrintJobs = await db.query.printJobs.findMany({
		with: {
			printer: true,
		},
	});

	const totalAmountOfPrintJobs = allPrintJobs.length;

	const now = new Date();
	const completedPrintJobs = allPrintJobs.filter((job) => {
		if (job.aborted) return false;
		const endAt = new Date(job.startAt).getTime() + job.durationInMinutes * 1000 * 60;
		return endAt < now.getTime();
	}).length;
	const abortedPrintJobs = allPrintJobs.filter((job) => job.aborted).length;
	const pendingPrintJobs = totalAmountOfPrintJobs - completedPrintJobs - abortedPrintJobs;

	const abortedPrintJobsReasons = Object.entries(
		allPrintJobs.reduce((accumulator: Record<string, number>, job) => {
			if (job.aborted && job.abortReason) {
				if (!accumulator[job.abortReason]) {
					accumulator[job.abortReason] = 1;
				} else {
					accumulator[job.abortReason]++;
				}
			}
			return accumulator;
		}, {}),
	).map(([name, count]) => ({ name, Anzahl: count }));

	const mostAbortedPrinter = allPrintJobs.reduce((prev, current) => (prev.aborted > current.aborted ? prev : current));

	const mostUsedPrinter = allPrintJobs.reduce((prev, current) =>
		prev.durationInMinutes > current.durationInMinutes ? prev : current,
	);

	const allPrinters = await db.query.printers.findMany();

	const freePrinters = allPrinters.filter((printer) => {
		const jobs = allPrintJobs.filter((job) => job.printerId === printer.id);
		const now = new Date();
		const inUse = jobs.some((job) => {
			const endAt = new Date(job.startAt).getTime() + job.durationInMinutes * 1000 * 60;
			return endAt > now.getTime();
		});
		return !inUse;
	});

	return (
		<>
			<Tabs defaultValue={"@general"} className="flex flex-col gap-4 items-start">
				<TabsList className="bg-neutral-100 w-full py-6">
					<TabsTrigger value="@general">Allgemein</TabsTrigger>
					{allPrinters.map((printer) => (
						<TabsTrigger key={printer.id} value={printer.id}>
							{printer.name}
						</TabsTrigger>
					))}
				</TabsList>
				<TabsContent value="@general" className="w-full">
					<div className="flex flex-col lg:grid lg:grid-cols-2 gap-4">
						<DataCard title="Drucker mit meisten Reservierungen" value={mostUsedPrinter.printer.name} icon="Printer" />
						<DataCard title="Drucker mit meisten Abbrüchen" value={mostAbortedPrinter.printer.name} icon="Printer" />
						<Card className="w-full">
							<CardHeader>
								<CardTitle>Druckaufträge</CardTitle>
								<CardDescription>nach Status</CardDescription>
							</CardHeader>
							<CardContent>
								<PrintJobsDonut
									data={[
										{ name: "Abgeschlossen", value: completedPrintJobs },
										{ name: "Abgebrochen", value: abortedPrintJobs },
										{ name: "Ausstehend", value: pendingPrintJobs },
									]}
								/>
							</CardContent>
						</Card>
						<Card className="w-full ">
							<CardHeader>
								<CardTitle>
									Auslastung: <span>{((1 - freePrinters.length / allPrinters.length) * 100).toFixed(2)}%</span>
								</CardTitle>
							</CardHeader>
							<CardContent>
								<LoadFactorChart
									data={[
										{ name: "Frei", value: freePrinters.length },
										{ name: "Belegt", value: allPrinters.length - freePrinters.length },
									]}
								/>
							</CardContent>
						</Card>
						<Card className="w-full col-span-2">
							<CardHeader>
								<CardTitle>Abgebrochene Druckaufträge nach Abbruchgrund</CardTitle>
							</CardHeader>
							<CardContent>
								<AbortReasonsBarChart data={abortedPrintJobsReasons} />
							</CardContent>
						</Card>
					</div>
				</TabsContent>
				{allPrinters.map((printer) => (
					<TabsContent key={printer.id} value={printer.id}>
						{printer.description}
					</TabsContent>
				))}
			</Tabs>
		</>
	);
}
