import { StatsToggle } from "(app)/_components/StatsToggle";

import { prisma } from "@repo/db";
import { getServerSession } from "api/auth/[...nextauth]/auth";
import { PlaneIcon } from "lucide-react";

export const PilotStats = async () => {
	const session = await getServerSession();
	if (!session) return null;
	const user = session.user;
	const mostFlownStationsIds = await prisma.missionOnStationUsers.groupBy({
		where: {
			userId: user?.id,
		},
		by: ["stationId"],
		orderBy: {
			_count: {
				stationId: "desc",
			},
		},
		take: 1,
		_count: {
			stationId: true,
		},
	});

	let mostFlownStation = null;

	if (mostFlownStationsIds[0]?.stationId) {
		mostFlownStation = await prisma.station.findUnique({
			where: {
				id: mostFlownStationsIds[0]?.stationId,
			},
		});
	}

	const dispoSessions = await prisma.connectedAircraft.findMany({
		where: {
			userId: user?.id,
			logoutTime: {
				not: null,
			},
		},
		select: {
			loginTime: true,
			logoutTime: true,
		},
	});

	const totalFlownMissions = await prisma.missionOnStationUsers.count({
		where: {
			userId: user?.id,
		},
	});

	// Get the user's rank by missions flown
	const missionsFlownRanks = await prisma.missionOnStationUsers.groupBy({
		by: ["userId"],
		_count: { userId: true },
		orderBy: { _count: { userId: "desc" } },
	});

	const ownRankMissionsFlown = missionsFlownRanks.findIndex((rank) => rank.userId === user?.id) + 1;

	const totalUserCount = await prisma.user.count({
		where: {
			NOT: {
				id: user?.id,
			},
		},
	});

	const totalStationsCount = await prisma.station.count();

	const unflownStationsCount = totalStationsCount - mostFlownStationsIds.length;

	const totalPilotTime = dispoSessions.reduce((acc, session) => {
		const logoffTime = new Date(session.logoutTime!).getTime();
		const logonTime = new Date(session.loginTime).getTime();
		return acc + (logoffTime - logonTime);
	}, 0);

	const hours = Math.floor(totalPilotTime / (1000 * 60 * 60));
	const minutes = Math.floor((totalPilotTime % (1000 * 60 * 60)) / (1000 * 60));

	const totalFlownMissionsPercent = ((ownRankMissionsFlown * 100) / totalUserCount).toFixed(0);

	return (
		<div className="stats shadow">
			<div className="stat">
				<div className="stat-figure text-primary">
					<svg
						xmlns="http://www.w3.org/2000/svg"
						fill="none"
						viewBox="0 0 24 24"
						className="inline-block h-8 w-8 stroke-current"
					>
						<path
							strokeLinecap="round"
							strokeLinejoin="round"
							strokeWidth="2"
							d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"
						></path>
					</svg>
				</div>
				<div className="stat-title">Einsätze geflogen</div>
				<div className="stat-value text-primary">{totalFlownMissions}</div>
				<div className="stat-desc">
					Du bist damit unter den top{" "}
					{!isNaN(Number(totalFlownMissionsPercent)) ? totalFlownMissionsPercent : 0}%!
				</div>
			</div>

			<div className="stat">
				<div className="stat-figure text-secondary">
					<svg
						xmlns="http://www.w3.org/2000/svg"
						fill="none"
						viewBox="0 0 24 24"
						className="inline-block h-8 w-8 stroke-current"
					>
						<path
							strokeLinecap="round"
							strokeLinejoin="round"
							strokeWidth="2"
							d="M13 10V3L4 14h7v7l9-11h-7z"
						></path>
					</svg>
				</div>
				<div className="stat-title">Pilot Login Zeit</div>
				<div className="stat-value text-secondary">
					{hours}h {minutes}min
				</div>
			</div>

			{mostFlownStation && (
				<div className="stat">
					<div className="stat-figure text-info">
						<PlaneIcon className="w-8 h-8" />
					</div>
					<div className="stat-value text-info">{mostFlownStation?.bosCallsign}</div>
					<div className="stat-title">War bisher dein Rettungsmittel der Wahl</div>
					{unflownStationsCount > 0 && (
						<div className="stat-desc text-secondary">
							{unflownStationsCount} {unflownStationsCount > 1 ? "Stationen" : "Station"} warten
							noch auf dich!
						</div>
					)}
					{unflownStationsCount === 0 && (
						<div className="stat-desc text-secondary">
							Du hast alle Stationen geflogen! Krass...
						</div>
					)}
				</div>
			)}
		</div>
	);
};

export const DispoStats = async () => {
	const session = await getServerSession();
	if (!session) return null;
	const user = session.user;

	const dispoSessions = await prisma.connectedDispatcher.findMany({
		where: {
			userId: user?.id,
			logoutTime: {
				not: null,
			},
		},
		select: {
			loginTime: true,
			logoutTime: true,
		},
	});

	const mostDispatchedStationIds = await prisma.mission.groupBy({
		where: {
			createdUserId: user?.id,
		},
		by: ["missionStationIds"],
		orderBy: {
			_count: {
				missionStationIds: "desc",
			},
		},
		take: 1,
		_count: {
			missionStationIds: true,
		},
	});

	let mostDispatchedStation = null;

	if (mostDispatchedStationIds[0]?.missionStationIds[0]) {
		mostDispatchedStation = await prisma.station.findUnique({
			where: {
				id: mostDispatchedStationIds[0]?.missionStationIds[0],
			},
		});
	}

	const totalDispatchedMissions = await prisma.mission.count({
		where: {
			createdUserId: user?.id,
		},
	});

	const totalDispoTime = dispoSessions.reduce((acc, session) => {
		const logoffTime = new Date(session.logoutTime!).getTime();
		const logonTime = new Date(session.loginTime).getTime();
		return acc + (logoffTime - logonTime);
	}, 0);

	const hours = Math.floor(totalDispoTime / (1000 * 60 * 60));
	const minutes = Math.floor((totalDispoTime % (1000 * 60 * 60)) / (1000 * 60));

	return (
		<div className="stats shadow">
			<div className="stat">
				<div className="stat-figure text-primary">
					<svg
						xmlns="http://www.w3.org/2000/svg"
						fill="none"
						viewBox="0 0 24 24"
						className="inline-block h-8 w-8 stroke-current"
					>
						<path
							strokeLinecap="round"
							strokeLinejoin="round"
							strokeWidth="2"
							d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"
						></path>
					</svg>
				</div>
				<div className="stat-title">Einsätze disponiert</div>
				<div className="stat-value text-primary">{totalDispatchedMissions}</div>
			</div>

			<div className="stat">
				<div className="stat-figure text-secondary">
					<svg
						xmlns="http://www.w3.org/2000/svg"
						fill="none"
						viewBox="0 0 24 24"
						className="inline-block h-8 w-8 stroke-current"
					>
						<path
							strokeLinecap="round"
							strokeLinejoin="round"
							strokeWidth="2"
							d="M13 10V3L4 14h7v7l9-11h-7z"
						></path>
					</svg>
				</div>
				<div className="stat-title">Disponent Login Zeit</div>
				<div className="stat-value text-secondary">
					{hours}h {minutes}m
				</div>
			</div>

			{mostDispatchedStation && (
				<div className="stat">
					<div className="stat-figure text-info">
						<PlaneIcon className="w-8 h-8" />
					</div>
					<div className="stat-value text-info">{mostDispatchedStation?.bosCallsign}</div>
					<div className="stat-title">Wurde von dir am meisten Disponiert</div>
					<div className="stat-desc text-secondary">
						{mostDispatchedStationIds[0]?._count.missionStationIds} Einsätze
					</div>
				</div>
			)}
		</div>
	);
};

export const Stats = async ({ stats }: { stats: "pilot" | "dispo" }) => {
	const session = await getServerSession();
	if (!session) return null;

	return (
		<>
			{session.user.permissions.includes("DISPO") && <StatsToggle />}
			<div className="card bg-base-200 shadow-xl mb-4 col-span-6 xl:col-span-3">
				{stats === "dispo" && <DispoStats />}
				{stats === "pilot" && <PilotStats />}
			</div>
		</>
	);
};
