import { useEffect, useState } from "react";
import * as stylex from "@stylexjs/stylex";
import { ApiError } from "@/lib/api";
import { styles as shared } from "@/ui/styles";
import { colors } from "@/ui/tokens.stylex";

const styles = stylex.create({
	message: {
		marginTop: "0.5rem",
		fontSize: "0.875rem",
		lineHeight: "1.25rem",
		color: colors.danger,
	},
	retry: {
		cursor: { default: "pointer", ":disabled": "not-allowed" },
		borderStyle: "none",
		backgroundColor: "transparent",
		padding: 0,
		color: "inherit",
		fontSize: "inherit",
		fontWeight: 500,
		textDecorationLine: "underline",
	},
});

/**
 * Inline mutation error per ruling 17: 400/409 messages verbatim, 429 with
 * countdown. Pass `onRetry` to append a retry button for a failed query.
 */
export default function InlineError({ error, onRetry }: { error: unknown; onRetry?: () => void }) {
	const retryAfter = error instanceof ApiError && error.status === 429 ? (error.retryAfter ?? null) : null;
	const [remaining, setRemaining] = useState<number | null>(retryAfter);

	useEffect(() => {
		setRemaining(retryAfter);
		if (retryAfter === null) return;
		const timer = setInterval(() => setRemaining((s) => (s === null || s <= 1 ? 0 : s - 1)), 1000);
		return () => clearInterval(timer);
	}, [error, retryAfter]);

	if (error === null || error === undefined) return null;

	let message: string;
	if (error instanceof ApiError) {
		if (error.status === 429) {
			message =
				remaining !== null && remaining > 0
					? `Rate limited. Try again in ${remaining}s.`
					: "Rate limited. Try again.";
		} else if (error.status === 503) {
			message = "The server is starting or degraded. Try again shortly.";
		} else {
			message = error.message;
		}
	} else {
		message = "Could not reach the server.";
	}

	return (
		<p role="alert" {...stylex.props(styles.message)}>
			{message}
			{onRetry !== undefined && (
				<>
					{" "}
					<button type="button" onClick={onRetry} {...stylex.props(styles.retry, shared.focusRing)}>
						Retry
					</button>
				</>
			)}
		</p>
	);
}
