import { useState } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { Link, useNavigate, useParams } from "@tanstack/react-router";
import * as stylex from "@stylexjs/stylex";
import InlineError from "@/lib/InlineError";
import { formatDuration, formatTime } from "@/lib/format";
import { diagnosticPurgeMutation, diagnosticQuery } from "@/lib/queries";
import ConfirmDialog from "@/ui/ConfirmDialog";
import { styles as shared } from "@/ui/styles";
import { colors } from "@/ui/tokens.stylex";
import SeverityBadge from "./SeverityBadge";
import { componentLabel, copyFor } from "./eventCopy";

const styles = stylex.create({
	back: {
		fontSize: "0.875rem",
		lineHeight: "1.25rem",
		color: colors.primaryOnSurface,
		textDecorationLine: "none",
	},
	headingRow: {
		marginTop: "0.5rem",
		display: "flex",
		alignItems: "center",
		flexWrap: "wrap",
		gap: "0.5rem",
	},
	heading: {
		fontSize: "1.5rem",
		lineHeight: "2rem",
		fontWeight: 600,
	},
	purgeAction: {
		marginInlineStart: "auto",
	},
	subject: {
		marginTop: "0.25rem",
		color: colors.textSecondary,
		wordBreak: "break-all",
	},
	panel: {
		marginTop: "1rem",
		maxWidth: "48rem",
		borderRadius: "0.25rem",
		borderWidth: 1,
		borderStyle: "solid",
		borderColor: colors.border,
		backgroundColor: colors.surfaceRaised,
		padding: "1rem",
	},
	facts: {
		display: "grid",
		gap: "0.5rem 1rem",
		gridTemplateColumns: {
			default: "auto",
			"@media (min-width: 640px)": "max-content 1fr",
		},
		margin: 0,
		fontSize: "0.875rem",
		lineHeight: "1.25rem",
	},
	term: {
		color: colors.textMuted,
	},
	value: {
		margin: 0,
	},
	sectionHeading: {
		marginTop: "1.5rem",
		fontSize: "1.125rem",
		lineHeight: "1.75rem",
		fontWeight: 600,
	},
	prose: {
		marginTop: "0.5rem",
		maxWidth: "48rem",
		fontSize: "0.875rem",
		lineHeight: "1.5rem",
	},
	detail: {
		marginTop: "0.5rem",
		maxWidth: "48rem",
		overflowX: "auto",
		borderRadius: "0.25rem",
		borderWidth: 1,
		borderStyle: "solid",
		borderColor: colors.border,
		padding: "0.75rem",
		fontSize: "0.8125rem",
		lineHeight: "1.25rem",
		whiteSpace: "pre-wrap",
		wordBreak: "break-all",
	},
	links: {
		marginTop: "1rem",
		fontSize: "0.875rem",
		lineHeight: "1.25rem",
	},
	link: {
		color: colors.primaryOnSurface,
	},
	loading: {
		marginTop: "1rem",
		color: colors.textMuted,
	},
});

export default function DiagnosticDetailPage() {
	const { id } = useParams({ from: "/shell/diagnostics/$id" });
	const eventId = Number(id);
	const { data, error, isPending, refetch } = useQuery(diagnosticQuery(eventId));

	const navigate = useNavigate();
	const queryClient = useQueryClient();
	const purge = useMutation(diagnosticPurgeMutation(queryClient));
	const [confirming, setConfirming] = useState(false);

	function confirmPurge() {
		setConfirming(false);
		// The row this page is about is gone, so staying here would show the
		// 404 the purge itself caused.
		purge.mutate(eventId, { onSuccess: () => void navigate({ to: "/diagnostics" }) });
	}

	if (isPending) {
		return (
			<p {...stylex.props(styles.loading, shared.pulse)} role="status">
				Loading event…
			</p>
		);
	}
	if (data === undefined) {
		return (
			<section>
				<Link to="/diagnostics" {...stylex.props(styles.back, shared.focusRing)}>
					← All diagnostics
				</Link>
				<InlineError error={error} onRetry={() => void refetch()} />
			</section>
		);
	}

	const copy = copyFor(data.code);
	const resolvedAt = data.resolved_at;
	const span = (resolvedAt ?? Math.floor(Date.now() / 1000)) - data.first_seen;

	return (
		<section>
			<Link to="/diagnostics" {...stylex.props(styles.back, shared.focusRing)}>
				← All diagnostics
			</Link>
			<div {...stylex.props(styles.headingRow)}>
				<h1 {...stylex.props(styles.heading)}>{copy.title}</h1>
				<SeverityBadge severity={data.severity} />
				{/* Only history can be purged: an open episode is the current state of the box. */}
				{resolvedAt !== null && (
					<button
						type="button"
						onClick={() => setConfirming(true)}
						disabled={purge.isPending}
						{...stylex.props(styles.purgeAction, shared.dangerLinkButton, shared.focusRing)}
					>
						Purge
					</button>
				)}
			</div>
			<p {...stylex.props(styles.subject)}>{data.subject}</p>
			<InlineError error={purge.error} />

			<div {...stylex.props(styles.panel)}>
				<dl {...stylex.props(styles.facts)}>
					<dt {...stylex.props(styles.term)}>State</dt>
					<dd {...stylex.props(styles.value)}>
						{resolvedAt === null
							? `Active for ${formatDuration(span)}`
							: `Resolved after ${formatDuration(span)}`}
					</dd>
					<dt {...stylex.props(styles.term)}>First seen</dt>
					<dd {...stylex.props(styles.value)}>{formatTime(data.first_seen)}</dd>
					<dt {...stylex.props(styles.term)}>Last seen</dt>
					<dd {...stylex.props(styles.value)}>{formatTime(data.last_seen)}</dd>
					<dt {...stylex.props(styles.term)}>Occurrences</dt>
					<dd {...stylex.props(styles.value, shared.tabularNums)}>{data.occurrences}</dd>
					<dt {...stylex.props(styles.term)}>Resolved</dt>
					<dd {...stylex.props(styles.value)}>
						{data.resolved_at === null ? "Not yet — still failing" : formatTime(data.resolved_at)}
					</dd>
					<dt {...stylex.props(styles.term)}>Component</dt>
					<dd {...stylex.props(styles.value)}>{componentLabel(data.component)}</dd>
					<dt {...stylex.props(styles.term)}>Code</dt>
					<dd {...stylex.props(styles.value, shared.mono)}>{data.code}</dd>
				</dl>
			</div>

			<h2 {...stylex.props(styles.sectionHeading)}>Impact</h2>
			<p {...stylex.props(styles.prose)}>{copy.impact}</p>

			<h2 {...stylex.props(styles.sectionHeading)}>What to do</h2>
			<p {...stylex.props(styles.prose)}>{copy.remediation}</p>

			<h2 {...stylex.props(styles.sectionHeading)}>Last error</h2>
			{data.detail === "" ? (
				<p {...stylex.props(styles.prose)}>The server recorded no error text for this event.</p>
			) : (
				<pre {...stylex.props(styles.detail, shared.mono)}>{data.detail}</pre>
			)}

			{copy.link !== undefined && (
				<p {...stylex.props(styles.links)}>
					{copy.link.to === "/configuration/protection" ? (
						<Link
							to="/configuration/protection"
							search={{ tab: "sources" }}
							{...stylex.props(styles.link, shared.focusRing)}
						>
							Go to {copy.link.label}
						</Link>
					) : copy.link.to === "/configuration/resolution" ? (
						<Link
							to="/configuration/resolution"
							search={{ tab: "upstreams" }}
							{...stylex.props(styles.link, shared.focusRing)}
						>
							Go to {copy.link.label}
						</Link>
					) : (
						<Link to={copy.link.to} {...stylex.props(styles.link, shared.focusRing)}>
							Go to {copy.link.label}
						</Link>
					)}
				</p>
			)}

			<ConfirmDialog
				isOpen={confirming}
				title="Purge event"
				message="Purge this resolved event? Its history is gone for good."
				confirmLabel="Purge"
				onConfirm={confirmPurge}
				onCancel={() => setConfirming(false)}
			/>
		</section>
	);
}
