import { useMemo, useState, type ElementType, type ReactNode } from "react";
import { Link } from "react-router-dom";
import {
	Activity,
	AlertTriangle,
	Bell,
	CheckCircle2,
	ChevronDown,
	ExternalLink,
	Gauge,
	Inbox,
	Radio,
	RefreshCw,
	Server,
	ServerOff,
	XCircle,
} from "lucide-react";
import {
	useAlertmanagerAlerts,
	useAlertmanagerStatus,
	useGrafanaStatus,
	usePrometheusStatus,
	usePrometheusTargets,
	useMonitoringMachines,
} from "../hooks/useObservability";
import { useServiceInstances } from "../hooks/useServices";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Button } from "@/components/ui/button";
import {
	Select,
	SelectContent,
	SelectItem,
	SelectTrigger,
	SelectValue,
} from "@/components/ui/select";
import { Skeleton } from "@/components/ui/skeleton";
import {
	Collapsible,
	CollapsibleContent,
	CollapsibleTrigger,
} from "@/components/ui/collapsible";
import type {
	AlertmanagerAlert,
	MonitoringMachine,
	PrometheusTarget,
} from "../types";

function severityVariant(
	severity: string,
): "default" | "secondary" | "destructive" | "outline" {
	switch (severity.toLowerCase()) {
		case "critical":
			return "destructive";
		case "warning":
			return "default";
		case "info":
			return "secondary";
		default:
			return "outline";
	}
}

function HealthCard({
	title,
	status,
	detail,
	icon: Icon,
	isLoading,
}: {
	title: string;
	status: "ok" | "warning" | "error" | "unknown";
	detail: string;
	icon: ElementType;
	isLoading?: boolean;
}) {
	const statusIcon =
		status === "ok" ? (
			<CheckCircle2 className="h-5 w-5 text-green-500" />
		) : status === "warning" ? (
			<AlertTriangle className="h-5 w-5 text-amber-500" />
		) : status === "error" ? (
			<XCircle className="h-5 w-5 text-red-500" />
		) : (
			<Radio className="h-5 w-5 text-muted-foreground" />
		);

	return (
		<Card>
			<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
				<CardTitle className="text-sm font-medium">{title}</CardTitle>
				<Icon className="h-4 w-4 text-muted-foreground" />
			</CardHeader>
			<CardContent>
				<div className="flex items-center gap-2">
					{isLoading ? <Skeleton className="h-5 w-5" /> : statusIcon}
					<span className="text-2xl font-bold capitalize">{status}</span>
				</div>
				<p className="mt-1 text-xs text-muted-foreground">{detail}</p>
			</CardContent>
		</Card>
	);
}

function EmptyState({
	icon: Icon,
	title,
	description,
	action,
}: {
	icon: ElementType;
	title: string;
	description: string;
	action?: ReactNode;
}) {
	return (
		<div className="flex h-full min-h-[160px] flex-col items-center justify-center gap-2 rounded-md border p-6 text-center">
			<Icon className="h-8 w-8 text-muted-foreground" />
			<div className="font-medium">{title}</div>
			<div className="max-w-md text-sm text-muted-foreground">
				{description}
			</div>
			{action ? <div className="mt-2">{action}</div> : null}
		</div>
	);
}

function QueryError({
	label,
	error,
	refetch,
}: {
	label: string;
	error: Error | null;
	refetch: () => void;
}) {
	if (!error) return null;
	return (
		<Alert variant="destructive">
			<AlertTitle>{label} failed</AlertTitle>
			<AlertDescription className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
				<span className="break-words">{error.message}</span>
				<Button variant="outline" size="sm" className="mobile-touch-target" onClick={() => refetch()}>
					<RefreshCw className="mr-1 h-3 w-3" />
					Retry
				</Button>
			</AlertDescription>
		</Alert>
	);
}

function AlertItem({ alert }: { alert: AlertmanagerAlert }) {
	return (
		<Collapsible>
			<CollapsibleTrigger asChild>
				<div className="group cursor-pointer rounded-lg border p-3 transition-colors hover:bg-muted/50">
					<div className="flex items-start justify-between gap-2">
						<div className="font-medium text-sm">{alert.name}</div>
						<div className="flex items-center gap-1">
							<Badge variant={severityVariant(alert.severity)}>
								{alert.severity}
							</Badge>
							<ChevronDown className="h-4 w-4 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" />
						</div>
					</div>
					<div className="mt-1 text-xs text-muted-foreground">
						{alert.summary || alert.description}
					</div>
					{alert.active_since && (
						<div className="mt-1 text-[10px] text-muted-foreground">
							Since {new Date(alert.active_since).toLocaleString()}
						</div>
					)}
				</div>
			</CollapsibleTrigger>
			<CollapsibleContent className="overflow-hidden">
				<div className="space-y-2 rounded-b-lg border-x border-b p-3 text-sm">
					{alert.description && (
						<div>
							<span className="font-medium">Description:</span>{" "}
							{alert.description}
						</div>
					)}
					<div className="grid grid-cols-2 gap-2 text-xs">
						{alert.job_name && (
							<div>
								<span className="font-medium">Job:</span> {alert.job_name}
							</div>
						)}
						{alert.category && (
							<div>
								<span className="font-medium">Category:</span> {alert.category}
							</div>
						)}
						<div>
							<span className="font-medium">State:</span> {alert.state}
						</div>
						<div>
							<span className="font-medium">Since:</span>{" "}
							{alert.active_since
								? new Date(alert.active_since).toLocaleString()
								: "unknown"}
						</div>
					</div>
					{alert.labels && Object.keys(alert.labels).length > 0 && (
						<div className="flex flex-wrap gap-1 pt-1">
							{Object.entries(alert.labels).map(([key, value]) => (
								<Badge key={key} variant="secondary" className="text-[10px]">
									{key}={value}
								</Badge>
							))}
						</div>
					)}
				</div>
			</CollapsibleContent>
		</Collapsible>
	);
}

function TargetsTable({ targets }: { targets: PrometheusTarget[] }) {
	return (
		<div className="space-y-3">
			{targets.map((target, idx) => (
				<div key={idx} className="rounded-lg border p-3">
					<div className="font-mono text-sm">{target.targets.join(", ")}</div>
					{target.labels && Object.keys(target.labels).length > 0 && (
						<div className="mt-2 flex flex-wrap gap-1">
							{Object.entries(target.labels).map(([key, value]) => (
								<Badge key={key} variant="outline" className="text-[10px]">
									{key}: {value}
								</Badge>
							))}
						</div>
					)}
				</div>
			))}
		</div>
	);
}

function GrafanaLinkCard({
	title,
	description,
	href,
}: {
	title: string;
	description: string;
	href: string;
}) {
	return (
		<div className="rounded-md border p-4">
			<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
				<div>
					<div className="font-medium">{title}</div>
					<div className="text-sm text-muted-foreground">{description}</div>
				</div>
				<Button variant="outline" size="sm" className="mobile-touch-target" asChild>
					<a
						href={href}
						target="_blank"
						rel="noopener noreferrer"
						className="gap-1"
					>
						Open in Grafana
						<ExternalLink className="h-3 w-3" />
					</a>
				</Button>
			</div>
		</div>
	);
}

export function ObservabilityPage() {
	const {
		data: alertsSummary,
		isLoading: alertsLoading,
		error: alertsError,
		refetch: refetchAlerts,
	} = useAlertmanagerAlerts();
	const {
		data: alertmanagerStatus,
		isLoading: statusLoading,
		error: statusError,
		refetch: refetchStatus,
	} = useAlertmanagerStatus();
	const {
		data: grafanaStatus,
		isLoading: grafanaLoading,
		error: grafanaError,
		refetch: refetchGrafana,
	} = useGrafanaStatus();
	const {
		data: prometheusStatus,
		isLoading: prometheusLoading,
		error: prometheusError,
		refetch: refetchPrometheus,
	} = usePrometheusStatus();
	const {
		data: prometheusTargets,
		isLoading: targetsLoading,
		error: targetsError,
		refetch: refetchTargets,
	} = usePrometheusTargets();
	const {
		data: machines = [],
		isLoading: machinesLoading,
		error: machinesError,
		refetch: refetchMachines,
	} = useMonitoringMachines();
	const { data: grafanaServices = [] } = useServiceInstances("grafana");
	const [selectedMachineId, setSelectedMachineId] = useState<string>("");

	const grafanaService =
		grafanaServices.find((s) => s.enabled) ?? grafanaServices[0];
	const GRAFANA_BASE_URL =
		(grafanaService?.config?.base_url as string | undefined) ?? "";

	const selectedMachine = useMemo<MonitoringMachine | null>(
		() =>
			machines.find((m) => m.id === selectedMachineId) ?? machines[0] ?? null,
		[machines, selectedMachineId],
	);

	const nodeExporterDashboardUrl = useMemo(() => {
		if (!selectedMachine || !GRAFANA_BASE_URL) return "";
		const instance = `${selectedMachine.host || "localhost"}:9100`;
		return `${GRAFANA_BASE_URL}/d/node-exporter-overview/node-exporter-overview?kiosk&var-instance=${encodeURIComponent(instance)}`;
	}, [selectedMachine, GRAFANA_BASE_URL]);

	const logsUrl = useMemo(() => {
		if (!selectedMachine || !GRAFANA_BASE_URL) return "";
		const container =
			selectedMachine.mode === "local" ? "backend" : selectedMachine.name;
		return `${GRAFANA_BASE_URL}/explore?orgId=1&left=${encodeURIComponent(
			JSON.stringify({
				datasource: "Loki",
				queries: [{ refId: "A", expr: `{container="${container}"}` }],
				range: { from: "now-1h", to: "now" },
			}),
		)}`;
	}, [selectedMachine, GRAFANA_BASE_URL]);

	const alertmanagerStatusDetail = alertmanagerStatus?.up
		? alertmanagerStatus.version
			? `version ${alertmanagerStatus.version}`
			: "reachable"
		: "unreachable";

	const targetsCount = prometheusTargets?.length ?? 0;
	const targetsStatus: "ok" | "warning" | "error" | "unknown" = targetsLoading
		? "unknown"
		: targetsError
			? "error"
			: targetsCount > 0
				? "ok"
				: "warning";

	const alertStatus: "ok" | "warning" | "error" | "unknown" = alertsLoading
		? "unknown"
		: alertsError
			? "error"
			: (alertsSummary?.total ?? 0) > 0
				? alertsSummary?.alerts.some((a) => a.severity === "critical")
					? "error"
					: "warning"
				: "ok";

	const machinesStatus: "ok" | "warning" | "error" | "unknown" = machinesLoading
		? "unknown"
		: machinesError
			? "error"
			: machines.length > 0
				? "ok"
				: "warning";

	return (
		<div className="space-y-6">
			<div className="space-y-1">
				<h1 className="text-2xl font-bold tracking-tight">Observability</h1>
				<p className="text-sm text-muted-foreground">
					Unified view of metrics, logs, and alerts from Prometheus, Loki, and
					Alertmanager. Deep dashboards live in Grafana.
				</p>
			</div>

			<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
				<HealthCard
					title="Alertmanager"
					status={
						statusError
							? "error"
							: alertmanagerStatus?.up
								? "ok"
								: statusLoading
									? "unknown"
									: "error"
					}
					detail={alertmanagerStatusDetail}
					icon={Bell}
					isLoading={statusLoading}
				/>
				<HealthCard
					title="Active Alerts"
					status={alertStatus}
					detail={`${alertsSummary?.total ?? 0} firing alert${(alertsSummary?.total ?? 0) === 1 ? "" : "s"}`}
					icon={AlertTriangle}
					isLoading={alertsLoading}
				/>
				<HealthCard
					title="Prometheus Targets"
					status={targetsStatus}
					detail={`${targetsCount} remote Node Exporter target${targetsCount === 1 ? "" : "s"}`}
					icon={Radio}
					isLoading={targetsLoading}
				/>
				<HealthCard
					title="Machines"
					status={machinesStatus}
					detail={`${machines.length} monitoring machine${machines.length === 1 ? "" : "s"}`}
					icon={Server}
					isLoading={machinesLoading}
				/>
				<HealthCard
					title="Grafana"
					status={
						grafanaError
							? "error"
							: grafanaStatus?.up
								? "ok"
								: grafanaLoading
									? "unknown"
									: "error"
					}
					detail={
						grafanaStatus?.up
							? grafanaStatus.version
								? `version ${grafanaStatus.version}`
								: "reachable"
							: grafanaStatus?.error === "no_service_configured"
								? "not configured"
								: "unreachable"
					}
					icon={Gauge}
					isLoading={grafanaLoading}
				/>
				<HealthCard
					title="Prometheus"
					status={
						prometheusError
							? "error"
							: prometheusStatus?.up
								? "ok"
								: prometheusLoading
									? "unknown"
									: "error"
					}
					detail={
						prometheusStatus?.up
							? prometheusStatus.version
								? `version ${prometheusStatus.version}`
								: "reachable"
							: prometheusStatus?.error === "no_service_configured"
								? "not configured"
								: "unreachable"
					}
					icon={Radio}
					isLoading={prometheusLoading}
				/>
			</div>

			<div className="space-y-3">
				{statusError && (
					<QueryError
						label="Alertmanager status"
						error={statusError}
						refetch={refetchStatus}
					/>
				)}
				{alertsError && (
					<QueryError
						label="Active alerts"
						error={alertsError}
						refetch={refetchAlerts}
					/>
				)}
				{targetsError && (
					<QueryError
						label="Prometheus targets"
						error={targetsError}
						refetch={refetchTargets}
					/>
				)}
				{machinesError && (
					<QueryError
						label="Monitoring machines"
						error={machinesError}
						refetch={refetchMachines}
					/>
				)}
				{grafanaError && (
					<QueryError
						label="Grafana status"
						error={grafanaError}
						refetch={refetchGrafana}
					/>
				)}
				{prometheusError && (
					<QueryError
						label="Prometheus status"
						error={prometheusError}
						refetch={refetchPrometheus}
					/>
				)}
			</div>

			{alertsSummary?.error && (
				<Alert variant="destructive">
					<AlertTitle>Alertmanager unreachable</AlertTitle>
					<AlertDescription>
						The UI cannot reach Alertmanager right now. Alerts shown here may be
						stale.
					</AlertDescription>
				</Alert>
			)}

			<div className="grid gap-6 lg:grid-cols-2">
				<div className="space-y-6">
					<Card>
						<CardHeader>
							<CardTitle className="flex items-center gap-2">
								<Bell className="h-4 w-4" />
								Recent Alerts
							</CardTitle>
						</CardHeader>
						<CardContent className="space-y-3">
							{alertsLoading ? (
								<div className="space-y-2">
									<Skeleton className="h-16 w-full" />
									<Skeleton className="h-16 w-full" />
									<Skeleton className="h-16 w-full" />
								</div>
							) : !alertsSummary || alertsSummary.total === 0 ? (
								<EmptyState
									icon={Inbox}
									title="No active alerts"
									description="Everything looks quiet. Alertmanager will list firing alerts here when they occur."
								/>
							) : (
								<>
									{alertsSummary.alerts.map((alert, idx) => (
										<AlertItem key={`${alert.name}-${idx}`} alert={alert} />
									))}
									{alertsSummary.total > alertsSummary.alerts.length && (
										<div className="text-center text-xs text-muted-foreground">
											{alertsSummary.total - alertsSummary.alerts.length} more
											alert
											{alertsSummary.total - alertsSummary.alerts.length === 1
												? ""
												: "s"}{" "}
											in Alertmanager
										</div>
									)}
								</>
							)}
						</CardContent>
					</Card>

					<Card>
						<CardHeader>
							<CardTitle className="flex items-center gap-2">
								<Radio className="h-4 w-4" />
								Prometheus Targets
							</CardTitle>
						</CardHeader>
						<CardContent>
							{targetsLoading ? (
								<div className="space-y-2">
									<Skeleton className="h-16 w-full" />
									<Skeleton className="h-16 w-full" />
								</div>
							) : !prometheusTargets || prometheusTargets.length === 0 ? (
								<EmptyState
									icon={Radio}
									title="No Node Exporter targets"
									description="Enable Node Exporter on an SSH machine in Settings to populate Prometheus scrape targets."
									action={
										<Button variant="outline" size="sm" className="mobile-touch-target" asChild>
											<Link to="/settings">Open Settings</Link>
										</Button>
									}
								/>
							) : (
								<TargetsTable targets={prometheusTargets} />
							)}
						</CardContent>
					</Card>
				</div>

				<Card>
					<CardHeader className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
						<CardTitle className="flex items-center gap-2">
							<Activity className="h-4 w-4" />
							Machine Dashboard
						</CardTitle>
						<Select
							value={selectedMachine?.id ?? ""}
							onValueChange={setSelectedMachineId}
							disabled={machines.length === 0}
						>
							<SelectTrigger className="w-full sm:w-[240px]">
								<SelectValue placeholder="Select machine" />
							</SelectTrigger>
							<SelectContent>
								{machines.map((machine) => (
									<SelectItem key={machine.id} value={machine.id}>
										{machine.name}
									</SelectItem>
								))}
							</SelectContent>
						</Select>
					</CardHeader>
					<CardContent className="space-y-4">
						{selectedMachine ? (
							GRAFANA_BASE_URL ? (
								<>
									<GrafanaLinkCard
										title={`${selectedMachine.name} metrics`}
										description="Open the Node Exporter overview dashboard for this machine in Grafana."
										href={nodeExporterDashboardUrl}
									/>
									<GrafanaLinkCard
										title={`${selectedMachine.name} logs`}
										description="Explore Loki logs for this machine in Grafana."
										href={logsUrl}
									/>
								</>
							) : (
								<EmptyState
									icon={Gauge}
									title="No Grafana service configured"
									description="Add a Grafana service instance to enable deep-links to dashboards and logs."
									action={
										<Button variant="outline" size="sm" className="mobile-touch-target" asChild>
											<Link to="/services">Open Services</Link>
										</Button>
									}
								/>
							)
						) : (
							<EmptyState
								icon={ServerOff}
								title="No machine selected"
								description="Add monitoring machines in Settings to see Grafana drill-down links."
								action={
									<Button variant="outline" size="sm" className="mobile-touch-target" asChild>
										<Link to="/settings">Open Settings</Link>
									</Button>
								}
							/>
						)}
					</CardContent>
				</Card>
			</div>
		</div>
	);
}
