import { useMemo } from "react";
import {
	Box,
	Card,
	CardContent,
	Divider,
	Grid,
	LinearProgress,
	Stack,
	Typography,
} from "@mui/material";
import { useNavigate } from "react-router-dom";
import { useCounts, useLibraries, useActivity } from "../hooks/useDashboard";
import { useMonitoringMetrics, useDiskSpace } from "../hooks/useMonitoring";
import { NowPlaying } from "../components/NowPlaying";
import { MetricCard } from "../components/MetricCard";
import { LibraryOverview } from "../components/LibraryOverview";

function formatBytes(bytes: number): string {
	if (!bytes || bytes === 0) return "0 B";
	const units = ["B", "KB", "MB", "GB", "TB"];
	let value = bytes;
	let unitIdx = 0;
	while (value >= 1000 && unitIdx < units.length - 1) {
		value /= 1000;
		unitIdx++;
	}
	return `${value.toFixed(1)} ${units[unitIdx]}`;
}

function formatRate(bytes: number): string {
	return `${formatBytes(bytes)}/s`;
}

function formatPct(value: number): string {
	return `${value.toFixed(1)}%`;
}

function summarize(values: number[]) {
	if (values.length === 0) return null;
	const total = values.reduce((sum, value) => sum + value, 0);
	return {
		avg: total / values.length,
		min: Math.min(...values),
		max: Math.max(...values),
	};
}

function DiskSpaceCard({
	used,
	available,
	size,
	usedPct,
}: {
	used: number;
	available: number;
	size: number;
	usedPct: string;
}) {
	const pct = Math.max(0, Math.min(100, Number.parseFloat(usedPct) || 0));
	const barColor = pct < 70 ? "success" : pct < 90 ? "warning" : "error";
	return (
		<Card variant="outlined" sx={{ height: "100%" }}>
			<CardContent sx={{ p: { xs: 1.5, sm: 2 } }}>
				<Stack spacing={1.5}>
					<Box>
						<Typography
							variant="caption"
							color="text.secondary"
							sx={{ textTransform: "uppercase" }}
						>
							Disk space
						</Typography>
						<Typography
							variant="h5"
							sx={{
								fontWeight: 700,
								fontSize: { xs: "1.05rem", sm: "1.5rem" },
							}}
						>
							{usedPct} used
						</Typography>
					</Box>

					<Box sx={{ width: "100%" }}>
						<LinearProgress
							variant="determinate"
							value={pct}
							color={barColor}
							sx={{
								height: 12,
								borderRadius: 999,
								bgcolor: "action.hover",
								"& .MuiLinearProgress-bar": {
									borderRadius: 999,
								},
							}}
						/>
					</Box>

					<Grid container spacing={1.5} sx={{ alignItems: "stretch" }}>
						<Grid size={{ xs: 12, sm: 4 }}>
							<Box
								sx={{
									p: 1.5,
									borderRadius: 2,
									bgcolor: "action.hover",
									height: "100%",
									display: "flex",
									flexDirection: "column",
									alignItems: "center",
									justifyContent: "center",
									textAlign: "center",
									gap: 0.25,
								}}
							>
								<Typography variant="caption" color="text.secondary">
									Used
								</Typography>
								<Typography variant="body2" sx={{ fontWeight: 600 }}>
									{formatBytes(used)}
								</Typography>
							</Box>
						</Grid>
						<Grid size={{ xs: 12, sm: 4 }}>
							<Box
								sx={{
									p: 1.5,
									borderRadius: 2,
									bgcolor: "action.hover",
									height: "100%",
									display: "flex",
									flexDirection: "column",
									alignItems: "center",
									justifyContent: "center",
									textAlign: "center",
									gap: 0.25,
								}}
							>
								<Typography variant="caption" color="text.secondary">
									Free
								</Typography>
								<Typography variant="body2" sx={{ fontWeight: 600 }}>
									{formatBytes(available)}
								</Typography>
							</Box>
						</Grid>
						<Grid size={{ xs: 12, sm: 4 }}>
							<Box
								sx={{
									p: 1.5,
									borderRadius: 2,
									bgcolor: "action.hover",
									height: "100%",
									display: "flex",
									flexDirection: "column",
									alignItems: "center",
									justifyContent: "center",
									textAlign: "center",
									gap: 0.25,
								}}
							>
								<Typography variant="caption" color="text.secondary">
									Total
								</Typography>
								<Typography variant="body2" sx={{ fontWeight: 600 }}>
									{formatBytes(size)}
								</Typography>
							</Box>
						</Grid>
					</Grid>
				</Stack>
			</CardContent>
		</Card>
	);
}

export function Dashboard() {
	const navigate = useNavigate();
	const { data: counts } = useCounts();
	const { data: libraries } = useLibraries();
	const { data: activity } = useActivity();
	const { data: metrics } = useMonitoringMetrics();
	const { data: disk } = useDiskSpace();

	const monitoringWindow = useMemo(() => {
		const samples = metrics?.samples ?? [];
		if (samples.length === 0) return [];
		const latestTs = samples.at(-1)?.ts ?? 0;
		const windowStart = latestTs - 10 * 60;
		const windowed = samples.filter((sample) => sample.ts >= windowStart);
		return windowed.length > 0 ? windowed : samples;
	}, [metrics?.samples]);

	const cpuSummary = summarize(
		monitoringWindow.map((sample) => sample.cpu_pct),
	);
	const iowaitSummary = summarize(
		monitoringWindow
			.map((sample) => sample.iowait_pct)
			.filter((value): value is number => value !== undefined),
	);
	const memSummary = summarize(
		monitoringWindow.map((sample) => sample.mem_pct),
	);
	const netRxSummary = summarize(
		monitoringWindow.map((sample) => sample.net_rx_bytes_per_sec),
	);
	const netTxSummary = summarize(
		monitoringWindow.map((sample) => sample.net_tx_bytes_per_sec),
	);
	const diskReadSummary = summarize(
		monitoringWindow.map((sample) => sample.disk_read_bps),
	);
	const diskWriteSummary = summarize(
		monitoringWindow.map((sample) => sample.disk_write_bps),
	);

	return (
		<Stack spacing={3}>
			<Box>
				<Typography variant="h5" sx={{ mb: 1.5 }}>
					Activity
				</Typography>
				{activity && (
					<NowPlaying
						sessions={activity}
						onSelectSession={(session) =>
							navigate(`/users?user=${encodeURIComponent(session.user)}`)
						}
					/>
				)}
			</Box>

			<Divider />

			<Box>
				<Typography variant="h5" sx={{ mb: 1.5 }}>
					Monitoring Overview
				</Typography>
				<Grid container spacing={2} sx={{ alignItems: "stretch" }}>
					<Grid size={{ xs: 6, md: 3, lg: 12 / 7 }}>
						<MetricCard
							label="CPU (10m avg)"
							value={cpuSummary ? formatPct(cpuSummary.avg) : "-"}
							subtext={
								cpuSummary
									? `High: ${formatPct(cpuSummary.max)}\nLow: ${formatPct(cpuSummary.min)}`
									: undefined
							}
						/>
					</Grid>
					<Grid size={{ xs: 6, md: 3, lg: 12 / 7 }}>
						<MetricCard
							label="IO Wait (10m avg)"
							value={iowaitSummary ? formatPct(iowaitSummary.avg) : "-"}
							subtext={
								iowaitSummary
									? `High: ${formatPct(iowaitSummary.max)}\nLow: ${formatPct(iowaitSummary.min)}`
									: undefined
							}
						/>
					</Grid>
					<Grid size={{ xs: 6, md: 3, lg: 12 / 7 }}>
						<MetricCard
							label="RAM (10m avg)"
							value={memSummary ? formatPct(memSummary.avg) : "-"}
							subtext={
								memSummary
									? `High: ${formatPct(memSummary.max)}\nLow: ${formatPct(memSummary.min)}`
									: undefined
							}
						/>
					</Grid>
					<Grid size={{ xs: 6, md: 3, lg: 12 / 7 }}>
						<MetricCard
							label="Net down (10m avg)"
							value={netRxSummary ? formatRate(netRxSummary.avg) : "-"}
							subtext={
								netRxSummary
									? `High: ${formatRate(netRxSummary.max)}\nLow: ${formatRate(netRxSummary.min)}`
									: undefined
							}
						/>
					</Grid>
					<Grid size={{ xs: 6, md: 3, lg: 12 / 7 }}>
						<MetricCard
							label="Net up (10m avg)"
							value={netTxSummary ? formatRate(netTxSummary.avg) : "-"}
							subtext={
								netTxSummary
									? `High: ${formatRate(netTxSummary.max)}\nLow: ${formatRate(netTxSummary.min)}`
									: undefined
							}
						/>
					</Grid>
					<Grid size={{ xs: 6, md: 3, lg: 12 / 7 }}>
						<MetricCard
							label="Disk read (10m avg)"
							value={diskReadSummary ? formatRate(diskReadSummary.avg) : "-"}
							subtext={
								diskReadSummary
									? `High: ${formatRate(diskReadSummary.max)}\nLow: ${formatRate(diskReadSummary.min)}`
									: undefined
							}
						/>
					</Grid>
					<Grid size={{ xs: 6, md: 3, lg: 12 / 7 }}>
						<MetricCard
							label="Disk write (10m avg)"
							value={diskWriteSummary ? formatRate(diskWriteSummary.avg) : "-"}
							subtext={
								diskWriteSummary
									? `High: ${formatRate(diskWriteSummary.max)}\nLow: ${formatRate(diskWriteSummary.min)}`
									: undefined
							}
						/>
					</Grid>
				</Grid>
				{disk && (
					<Box sx={{ mt: 0.5 }}>
						<DiskSpaceCard
							used={disk.used}
							available={disk.available}
							size={disk.size}
							usedPct={disk.used_pct}
						/>
					</Box>
				)}
			</Box>

			<Divider />

			<Box>
				<Typography variant="h5" sx={{ mb: 1.5 }}>
					Library Stats
				</Typography>
				{counts && (
					<Grid container spacing={2} sx={{ mb: 2, alignItems: "stretch" }}>
						<Grid size={{ xs: 6, md: 3 }}>
							<MetricCard
								label="Total"
								value={(
									counts.movies +
									counts.series +
									counts.episodes
								).toLocaleString()}
							/>
						</Grid>
						<Grid size={{ xs: 6, md: 3 }}>
							<MetricCard
								label="Movies"
								value={counts.movies.toLocaleString()}
							/>
						</Grid>
						<Grid size={{ xs: 6, md: 3 }}>
							<MetricCard
								label="Series"
								value={counts.series.toLocaleString()}
							/>
						</Grid>
						<Grid size={{ xs: 6, md: 3 }}>
							<MetricCard
								label="Episodes"
								value={counts.episodes.toLocaleString()}
							/>
						</Grid>
					</Grid>
				)}
				{libraries && <LibraryOverview libraries={libraries} />}
			</Box>
		</Stack>
	);
}
