import { useMemo, useState } from "react";
import {
	Alert,
	Box,
	Button,
	Card,
	CardContent,
	Chip,
	Dialog,
	DialogContent,
	DialogTitle,
	FormControl,
	FormControlLabel,
	FormHelperText,
	Grid,
	InputLabel,
	MenuItem,
	Select,
	Stack,
	Switch,
	TextField,
	Typography,
} from "@mui/material";
import { useNavigate } from "react-router-dom";
import {
	useActivity,
	useDashboardShortcuts,
	useDeleteDashboardShortcut,
	useMonitoringOverview,
	useSaveDashboardShortcut,
} from "../hooks/useDashboard";
import { useMonitoringSettings } from "../hooks/useSettings";
import type { DashboardShortcut, DashboardShortcutInput } from "../types";
import { NowPlaying } from "../components/NowPlaying";
import { MonitoringOverviewTable } from "../components/MonitoringOverviewTable";
import { SectionCard } from "../components/SectionCard";
import { DialogFooter } from "../components/DialogFooter";
import BackupDashboardWidget from "../components/BackupDashboardWidget";

function emptyShortcut(): DashboardShortcutInput {
	return {
		id: null,
		label: "",
		shortcut_type: "website",
		enabled: true,
		icon: "",
		url: "",
		task_id: "",
		machine_id: "",
		user_id: "",
		notes: "",
	};
}

function normalizeWebsiteUrl(url: string): string {
	const trimmed = url.trim();
	if (!trimmed) return "";
	if (/^https?:\/\//i.test(trimmed)) return trimmed;
	return `https://${trimmed}`;
}

function shortcutHref(shortcut: DashboardShortcut): string {
	if (shortcut.shortcut_type === "website") {
		return normalizeWebsiteUrl(shortcut.url);
	}
	if (shortcut.shortcut_type === "action") {
		if (!shortcut.task_id) return "";
		const params = new URLSearchParams({ task: shortcut.task_id });
		if (shortcut.machine_id) params.set("machine_id", shortcut.machine_id);
		return `/actions?${params.toString()}`;
	}
	if (!shortcut.user_id) return "";
	return `/users?user=${encodeURIComponent(shortcut.user_id)}`;
}

function ShortcutDialog({
	open,
	draft,
	onChange,
	onClose,
	onSave,
}: {
	open: boolean;
	draft: DashboardShortcutInput;
	onChange: (shortcut: DashboardShortcutInput) => void;
	onClose: () => void;
	onSave: () => void;
}) {
	return (
		<Dialog open={open} onClose={onClose} fullWidth maxWidth="md">
			<DialogTitle>{draft.id ? "Edit shortcut" : "New shortcut"}</DialogTitle>
			<DialogContent dividers>
				<Stack spacing={1.25} sx={{ pt: 0.25 }}>
					<Grid container spacing={1}>
						<Grid size={{ xs: 12, sm: 6, md: 5 }}>
							<TextField
								fullWidth
								size="small"
								label="Label"
								value={draft.label}
								onChange={(e) => onChange({ ...draft, label: e.target.value })}
							/>
						</Grid>
						<Grid size={{ xs: 12, sm: 3, md: 2 }}>
							<TextField
								fullWidth
								size="small"
								label="Icon"
								value={draft.icon}
								onChange={(e) => onChange({ ...draft, icon: e.target.value })}
								helperText="Emoji or glyph"
							/>
						</Grid>
						<Grid size={{ xs: 12, sm: 3, md: 5 }}>
							<FormControl fullWidth size="small">
								<InputLabel>Type</InputLabel>
								<Select
									label="Type"
									value={draft.shortcut_type}
									onChange={(e) =>
										onChange({
											...draft,
											shortcut_type: e.target
												.value as DashboardShortcutInput["shortcut_type"],
										})
									}
								>
									<MenuItem value="website">Website</MenuItem>
									<MenuItem value="action">Saved action</MenuItem>
									<MenuItem value="user">User</MenuItem>
								</Select>
								<FormHelperText>
									Website opens a URL. Saved actions jump to a task. Users
									deep-link.
								</FormHelperText>
							</FormControl>
						</Grid>
					</Grid>

					{draft.shortcut_type === "website" ? (
						<TextField
							fullWidth
							size="small"
							label="Website URL"
							value={draft.url}
							onChange={(e) => onChange({ ...draft, url: e.target.value })}
							helperText="https:// is added if missing."
						/>
					) : draft.shortcut_type === "action" ? (
						<Grid container spacing={1.25}>
							<Grid size={{ xs: 12, md: 6 }}>
								<TextField
									fullWidth
									size="small"
									label="Task ID"
									value={draft.task_id}
									onChange={(e) =>
										onChange({ ...draft, task_id: e.target.value })
									}
									helperText="Saved action ID."
								/>
							</Grid>
							<Grid size={{ xs: 12, md: 6 }}>
								<TextField
									fullWidth
									size="small"
									label="Machine ID"
									value={draft.machine_id}
									onChange={(e) =>
										onChange({ ...draft, machine_id: e.target.value })
									}
									helperText="Optional machine target."
								/>
							</Grid>
						</Grid>
					) : (
						<TextField
							fullWidth
							size="small"
							label="User ID"
							value={draft.user_id}
							onChange={(e) => onChange({ ...draft, user_id: e.target.value })}
							helperText="Jellyfin user ID."
						/>
					)}

					<TextField
						fullWidth
						size="small"
						label="Notes"
						value={draft.notes}
						onChange={(e) => onChange({ ...draft, notes: e.target.value })}
					/>
					<FormControlLabel
						control={
							<Switch
								checked={draft.enabled}
								onChange={(e) =>
									onChange({ ...draft, enabled: e.target.checked })
								}
							/>
						}
						label="Enabled"
					/>
				</Stack>
			</DialogContent>
			<DialogFooter
				onCancel={onClose}
				onConfirm={onSave}
				confirmLabel="Save shortcut"
				confirmBusyLabel="Save shortcut"
			/>
		</Dialog>
	);
}

function ShortcutCard({
	shortcut,
	onOpen,
	onEdit,
	onDelete,
}: {
	shortcut: DashboardShortcut;
	onOpen: () => void;
	onEdit: () => void;
	onDelete: () => void;
}) {
	const href = shortcutHref(shortcut);
	const subtitle =
		shortcut.shortcut_type === "website"
			? shortcut.url || "No URL configured"
			: shortcut.shortcut_type === "action"
				? [
						shortcut.task_id || "task pending",
						shortcut.machine_id
							? `machine ${shortcut.machine_id}`
							: "any machine",
					].join(" · ")
				: shortcut.user_id || "No user configured";

	return (
		<Card variant="outlined" sx={{ height: "100%" }}>
			<CardContent sx={{ p: 1.25 }}>
				<Stack spacing={1}>
					<Stack
						direction="row"
						spacing={1}
						sx={{ justifyContent: "space-between", alignItems: "flex-start" }}
					>
						<Box sx={{ minWidth: 0 }}>
							<Typography sx={{ fontWeight: 700 }} noWrap>
								{shortcut.label}
							</Typography>
							<Typography variant="body2" color="text.secondary" noWrap>
								{subtitle}
							</Typography>
						</Box>
						<Stack direction="row" spacing={1} sx={{ alignItems: "center" }}>
							{shortcut.icon ? (
								<Box
									sx={{
										width: 32,
										height: 32,
										borderRadius: 1.5,
										display: "grid",
										placeItems: "center",
										bgcolor: "action.hover",
										fontSize: 18,
									}}
								>
									{shortcut.icon}
								</Box>
							) : null}
							<Chip
								size="small"
								variant="outlined"
								label={shortcut.shortcut_type}
							/>
						</Stack>
					</Stack>
					{shortcut.notes ? (
						<Typography variant="caption" color="text.secondary">
							{shortcut.notes}
						</Typography>
					) : null}
					<Stack direction="row" spacing={1} sx={{ flexWrap: "wrap" }}>
						<Button
							size="small"
							variant="contained"
							disabled={!shortcut.enabled || !href}
							onClick={onOpen}
						>
							Open
						</Button>
						<Button size="small" variant="outlined" onClick={onEdit}>
							Edit
						</Button>
						<Button
							size="small"
							variant="outlined"
							color="error"
							onClick={onDelete}
						>
							Delete
						</Button>
					</Stack>
				</Stack>
			</CardContent>
		</Card>
	);
}

export function Dashboard() {
	const navigate = useNavigate();
	const { data: machines = [] } = useMonitoringSettings();
	const jellyfinMachines = useMemo(
		() =>
			machines.filter(
				(machine) => machine.enabled && machine.services.includes("jellyfin"),
			),
		[machines],
	);
	const [activeJellyfinMachineId, setActiveJellyfinMachineId] =
		useState<string>("");
	const selectedJellyfinId =
		activeJellyfinMachineId || jellyfinMachines[0]?.id || "";
	const { data: activity } = useActivity(selectedJellyfinId || undefined);
	const { data: monitoringOverview } = useMonitoringOverview();
	const { data: shortcuts = [] } = useDashboardShortcuts();
	const saveShortcut = useSaveDashboardShortcut();
	const deleteShortcut = useDeleteDashboardShortcut();
	const [shortcutDialogOpen, setShortcutDialogOpen] = useState(false);
	const [shortcutDraft, setShortcutDraft] = useState<DashboardShortcutInput>(
		emptyShortcut(),
	);
	const [deleteShortcutId, setDeleteShortcutId] = useState<string | null>(null);

	const openCreateShortcut = () => {
		setShortcutDraft(emptyShortcut());
		setShortcutDialogOpen(true);
	};

	const openEditShortcut = (shortcut: DashboardShortcut) => {
		setShortcutDraft({
			id: shortcut.id,
			label: shortcut.label,
			shortcut_type: shortcut.shortcut_type,
			enabled: shortcut.enabled,
			icon: shortcut.icon,
			url: shortcut.url,
			task_id: shortcut.task_id,
			machine_id: shortcut.machine_id,
			user_id: shortcut.user_id,
			notes: shortcut.notes,
		});
		setShortcutDialogOpen(true);
	};

	const saveShortcutDraft = async () => {
		await saveShortcut.mutateAsync(shortcutDraft);
		setShortcutDialogOpen(false);
		setShortcutDraft(emptyShortcut());
	};

	return (
		<Stack spacing={2.25}>
			<SectionCard
				title="Shortcuts"
				description="Quick links to websites today, with room for action and user shortcuts later."
				action={
					<Button variant="outlined" onClick={openCreateShortcut}>
						Add shortcut
					</Button>
				}
			>
				{shortcuts.length ? (
					<Grid container spacing={1.25}>
						{shortcuts.map((shortcut) => (
							<Grid key={shortcut.id} size={{ xs: 12, md: 6, lg: 4 }}>
								<ShortcutCard
									shortcut={shortcut}
									onOpen={() => {
										const href = shortcutHref(shortcut);
										if (shortcut.shortcut_type === "website") {
											window.open(href, "_blank", "noopener,noreferrer");
										} else if (href) {
											navigate(href);
										}
									}}
									onEdit={() => openEditShortcut(shortcut)}
									onDelete={() => setDeleteShortcutId(shortcut.id)}
								/>
							</Grid>
						))}
					</Grid>
				) : (
					<Alert severity="info">
						No shortcuts yet. Add a website now, then add action or user
						shortcuts later.
					</Alert>
				)}
			</SectionCard>

			<SectionCard
				title="Jellyfin activity"
				description="Live sessions and idle users from Jellyfin."
				action={
					jellyfinMachines.length > 1 ? (
						<FormControl size="small" sx={{ minWidth: 180 }}>
							<Select
								value={selectedJellyfinId}
								onChange={(e) => setActiveJellyfinMachineId(e.target.value)}
								sx={{ fontSize: "0.8rem" }}
							>
								{jellyfinMachines.map((m) => (
									<MenuItem key={m.id} value={m.id}>
										{m.name}
									</MenuItem>
								))}
							</Select>
						</FormControl>
					) : jellyfinMachines.length === 1 ? (
						<Chip
							label={jellyfinMachines[0].name}
							size="small"
							variant="outlined"
						/>
					) : null
				}
			>
				{activity ? (
					<NowPlaying
						sessions={activity}
						onSelectSession={(session) =>
							navigate(`/users?user=${encodeURIComponent(session.user)}`)
						}
					/>
				) : null}
			</SectionCard>

			<SectionCard
				title="Monitoring overview"
				description="10-minute averages and fleet status across all configured machines."
			>
				<MonitoringOverviewTable overview={monitoringOverview} embedded />
			</SectionCard>

			<BackupDashboardWidget />

			<ShortcutDialog
				open={shortcutDialogOpen}
				draft={shortcutDraft}
				onChange={setShortcutDraft}
				onClose={() => setShortcutDialogOpen(false)}
				onSave={saveShortcutDraft}
			/>
			<Dialog
				open={Boolean(deleteShortcutId)}
				onClose={() => setDeleteShortcutId(null)}
				fullWidth
				maxWidth="xs"
			>
				<DialogTitle>Delete shortcut?</DialogTitle>
				<DialogContent>
					<Typography variant="body2" color="text.secondary">
						This cannot be undone. The shortcut will be removed from the
						dashboard.
					</Typography>
				</DialogContent>
				<DialogFooter
					onCancel={() => setDeleteShortcutId(null)}
					onConfirm={() => {
						if (deleteShortcutId) {
							deleteShortcut.mutate(deleteShortcutId);
						}
						setDeleteShortcutId(null);
					}}
					confirmLabel="Delete"
					confirmColor="error"
				/>
			</Dialog>
		</Stack>
	);
}
