/** React error boundary that catches render-time exceptions and shows a
 * recoverable error UI instead of a white screen. */
import * as React from "react";

interface Props {
	children: React.ReactNode;
}

interface State {
	error: Error | null;
}

/** Catches uncaught render exceptions in its subtree and displays a message. */
export class ErrorBoundary extends React.Component<Props, State> {
	constructor(props: Props) {
		super(props);
		this.state = { error: null };
	}

	static getDerivedStateFromError(error: Error): State {
		return { error };
	}

	handleReset = () => {
		this.setState({ error: null });
	};

	render() {
		if (this.state.error) {
			return (
				<div
					style={{
						display: "flex",
						flexDirection: "column",
						alignItems: "center",
						justifyContent: "center",
						height: "100vh",
						background: "#0d1117",
						color: "#e6edf3",
						fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
						gap: "16px",
						padding: "32px",
						textAlign: "center",
					}}
				>
					<div style={{ fontSize: "2em" }}>⚠</div>
					<div style={{ fontWeight: 600, fontSize: "1.1em" }}>
						Something went wrong
					</div>
					<div style={{ color: "#8b949e", fontSize: "0.9em", maxWidth: "480px" }}>
						{this.state.error.message}
					</div>
					<button
						type="button"
						onClick={this.handleReset}
						style={{
							padding: "8px 18px",
							borderRadius: "6px",
							border: "1px solid #30363d",
							background: "#21262d",
							color: "#e6edf3",
							cursor: "pointer",
							fontSize: "0.9em",
						}}
					>
						Try again
					</button>
				</div>
			);
		}
		return this.props.children;
	}
}
