import { useMemo, useState } from "react";
import { useNavigate } from "react-router-dom";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import {
	Dialog,
	DialogContent,
	DialogHeader,
	DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
	Select,
	SelectContent,
	SelectItem,
	SelectTrigger,
	SelectValue,
} from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
import {
	useDashboardShortcuts,
	useDeleteDashboardShortcut,
	useSaveDashboardShortcut,
} from "../hooks/useDashboard";
import { useWidgetInstances } from "../hooks/useWidgets";
import type { DashboardShortcut, DashboardShortcutInput } from "../types";
import { SectionCard } from "../components/SectionCard";
import { ConfirmDialog } from "../components/ConfirmDialog";
import { DialogFooter } from "../components/DialogFooter";
import { WidgetInstanceCard } from "../components/WidgetInstance";
import { WidgetConfigDialog } from "../components/WidgetConfigDialog";

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 Field({
	label,
	htmlFor,
	helper,
	children,
}: {
	label: string;
	htmlFor: string;
	helper?: string;
	children: React.ReactNode;
}) {
	return (
		<div className="flex flex-col gap-1.5">
			<Label htmlFor={htmlFor}>{label}</Label>
			{children}
			{helper ? (
				<p className="text-xs text-muted-foreground">{helper}</p>
			) : null}
		</div>
	);
}

function ShortcutDialog({
	open,
	draft,
	onChange,
	onClose,
	onSave,
}: {
	open: boolean;
	draft: DashboardShortcutInput;
	onChange: (shortcut: DashboardShortcutInput) => void;
	onClose: () => void;
	onSave: () => void;
}) {
	return (
		<Dialog
			open={open}
			onOpenChange={(next) => {
				if (!next) onClose();
			}}
		>
			<DialogContent className="sm:max-w-lg">
				<DialogHeader>
					<DialogTitle>
						{draft.id ? "Edit shortcut" : "New shortcut"}
					</DialogTitle>
				</DialogHeader>
				<div className="flex flex-col gap-4">
					<div className="grid grid-cols-1 gap-3 sm:grid-cols-12">
						<div className="flex flex-col gap-1.5 sm:col-span-5">
							<Field label="Label" htmlFor="shortcut-label">
								<Input
									id="shortcut-label"
									value={draft.label}
									onChange={(e) =>
										onChange({ ...draft, label: e.target.value })
									}
								/>
							</Field>
						</div>
						<div className="flex flex-col gap-1.5 sm:col-span-2">
							<Field
								label="Icon"
								htmlFor="shortcut-icon"
								helper="Emoji or glyph"
							>
								<Input
									id="shortcut-icon"
									value={draft.icon}
									onChange={(e) => onChange({ ...draft, icon: e.target.value })}
								/>
							</Field>
						</div>
						<div className="flex flex-col gap-1.5 sm:col-span-5">
							<Field
								label="Type"
								htmlFor="shortcut-type"
								helper="Website opens a URL. Saved actions jump to a task. Users deep-link."
							>
								<Select
									value={draft.shortcut_type}
									onValueChange={(value) =>
										onChange({
											...draft,
											shortcut_type:
												value as DashboardShortcutInput["shortcut_type"],
										})
									}
								>
									<SelectTrigger id="shortcut-type" className="w-full">
										<SelectValue />
									</SelectTrigger>
									<SelectContent>
										<SelectItem value="website">Website</SelectItem>
										<SelectItem value="action">Saved action</SelectItem>
										<SelectItem value="user">User</SelectItem>
									</SelectContent>
								</Select>
							</Field>
						</div>
					</div>

					{draft.shortcut_type === "website" ? (
						<Field
							label="Website URL"
							htmlFor="shortcut-url"
							helper="https:// is added if missing."
						>
							<Input
								id="shortcut-url"
								value={draft.url}
								onChange={(e) => onChange({ ...draft, url: e.target.value })}
							/>
						</Field>
					) : draft.shortcut_type === "action" ? (
						<div className="grid grid-cols-1 gap-3 md:grid-cols-2">
							<Field
								label="Task ID"
								htmlFor="shortcut-task"
								helper="Saved action ID."
							>
								<Input
									id="shortcut-task"
									value={draft.task_id}
									onChange={(e) =>
										onChange({ ...draft, task_id: e.target.value })
									}
								/>
							</Field>
							<Field
								label="Machine ID"
								htmlFor="shortcut-machine"
								helper="Optional machine target."
							>
								<Input
									id="shortcut-machine"
									value={draft.machine_id}
									onChange={(e) =>
										onChange({ ...draft, machine_id: e.target.value })
									}
								/>
							</Field>
						</div>
					) : (
						<Field
							label="User ID"
							htmlFor="shortcut-user"
							helper="Jellyfin user ID."
						>
							<Input
								id="shortcut-user"
								value={draft.user_id}
								onChange={(e) =>
									onChange({ ...draft, user_id: e.target.value })
								}
							/>
						</Field>
					)}

					<Field label="Notes" htmlFor="shortcut-notes">
						<Input
							id="shortcut-notes"
							value={draft.notes}
							onChange={(e) => onChange({ ...draft, notes: e.target.value })}
						/>
					</Field>
					<div className="flex items-center gap-2">
						<Switch
							id="shortcut-enabled"
							checked={draft.enabled}
							onCheckedChange={(checked) =>
								onChange({ ...draft, enabled: checked })
							}
						/>
						<Label htmlFor="shortcut-enabled">Enabled</Label>
					</div>
				</div>
				<DialogFooter
					onCancel={onClose}
					onConfirm={onSave}
					confirmLabel="Save shortcut"
					confirmBusyLabel="Save shortcut"
				/>
			</DialogContent>
		</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 className="h-full">
			<CardContent className="flex flex-col gap-3 p-3">
				<div className="flex flex-row items-start justify-between gap-2">
					<div className="min-w-0">
						<div className="truncate font-semibold">{shortcut.label}</div>
						<div className="truncate text-sm text-muted-foreground">
							{subtitle}
						</div>
					</div>
					<div className="flex flex-row items-center gap-2">
						{shortcut.icon ? (
							<div className="grid size-8 place-items-center rounded-md bg-muted text-lg">
								{shortcut.icon}
							</div>
						) : null}
						<Badge variant="outline">{shortcut.shortcut_type}</Badge>
					</div>
				</div>
				{shortcut.notes ? (
					<p className="text-xs text-muted-foreground">{shortcut.notes}</p>
				) : null}
				<div className="flex flex-row flex-wrap gap-2">
					<Button
						size="sm"
						disabled={!shortcut.enabled || !href}
						onClick={onOpen}
					>
						Open
					</Button>
					<Button size="sm" variant="outline" onClick={onEdit}>
						Edit
					</Button>
					<Button size="sm" variant="destructive" onClick={onDelete}>
						Delete
					</Button>
				</div>
			</CardContent>
		</Card>
	);
}

export function Dashboard() {
	const navigate = useNavigate();
	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 [widgetDialogOpen, setWidgetDialogOpen] = useState(false);
	const { data: widgetInstances = [] } = useWidgetInstances();

	const visibleWidgets = useMemo(
		() =>
			widgetInstances
				.filter((w) => w.enabled)
				.sort((a, b) => a.sort_order - b.sort_order),
		[widgetInstances],
	);

	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 (
		<div className="flex flex-col gap-4">
			<SectionCard
				title="Shortcuts"
				description="Quick links to websites today, with room for action and user shortcuts later."
				action={
					<div className="flex gap-2">
						<Button variant="outline" onClick={() => setWidgetDialogOpen(true)}>
							Edit dashboard
						</Button>
						<Button variant="outline" onClick={openCreateShortcut}>
							Add shortcut
						</Button>
					</div>
				}
			>
				{shortcuts.length ? (
					<div className="grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-3">
						{shortcuts.map((shortcut) => (
							<ShortcutCard
								key={shortcut.id}
								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)}
							/>
						))}
					</div>
				) : (
					<Alert>
						<AlertDescription>
							No shortcuts yet. Add a website now, then add action or user
							shortcuts later.
						</AlertDescription>
					</Alert>
				)}
			</SectionCard>

			{visibleWidgets.map((widget) => (
				<WidgetInstanceCard key={widget.id} widget={widget} />
			))}

			<ShortcutDialog
				open={shortcutDialogOpen}
				draft={shortcutDraft}
				onChange={setShortcutDraft}
				onClose={() => setShortcutDialogOpen(false)}
				onSave={saveShortcutDraft}
			/>
			<ConfirmDialog
				open={Boolean(deleteShortcutId)}
				title="Delete shortcut?"
				message="This cannot be undone. The shortcut will be removed from the dashboard."
				confirmLabel="Delete"
				onCancel={() => setDeleteShortcutId(null)}
				onConfirm={() => {
					if (deleteShortcutId) {
						deleteShortcut.mutate(deleteShortcutId);
					}
					setDeleteShortcutId(null);
				}}
			/>
			<WidgetConfigDialog
				open={widgetDialogOpen}
				onClose={() => setWidgetDialogOpen(false)}
			/>
		</div>
	);
}
