import { Component, type ErrorInfo, type ReactNode } from "react";

interface ErrorBoundaryProps {
  children: ReactNode;
}

interface ErrorBoundaryState {
  error: Error | null;
}

/**
 * App-wide error boundary. Without this, any render-time exception unmounts the
 * React tree and the user sees a blank white screen. This surfaces the actual
 * error message + stack so failures are diagnosable in place.
 */
export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
  state: ErrorBoundaryState = { error: null };

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

  componentDidCatch(error: Error, info: ErrorInfo) {
    // eslint-disable-next-line no-console
    console.error("[ErrorBoundary] Uncaught render error:", error, info.componentStack);
  }

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

  render() {
    const { error } = this.state;

    if (!error) return this.props.children;

    return (
      <div
        style={{
          minHeight: "100vh",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          padding: 24,
          background: "#f8fafc",
          fontFamily: "system-ui, sans-serif",
        }}
      >
        <div
          style={{
            maxWidth: 720,
            width: "100%",
            background: "#fff",
            border: "1px solid #fecaca",
            borderRadius: 12,
            padding: 24,
            boxShadow: "0 1px 3px rgba(0,0,0,0.08)",
          }}
        >
          <h2 style={{ margin: 0, color: "#b91c1c", fontSize: 18 }}>Something went wrong</h2>
          <p style={{ color: "#64748b", fontSize: 14 }}>
            A render error was caught. Details below — share this with the developer.
          </p>
          <pre
            style={{
              whiteSpace: "pre-wrap",
              wordBreak: "break-word",
              background: "#0f172a",
              color: "#fca5a5",
              padding: 16,
              borderRadius: 8,
              fontSize: 12,
              maxHeight: 320,
              overflow: "auto",
            }}
          >
            {error.message}
            {"\n\n"}
            {error.stack}
          </pre>
          <button
            type="button"
            onClick={this.handleReset}
            style={{
              marginTop: 12,
              padding: "8px 16px",
              border: "none",
              borderRadius: 8,
              background: "#0f766e",
              color: "#fff",
              cursor: "pointer",
              fontSize: 14,
            }}
          >
            Dismiss
          </button>
        </div>
      </div>
    );
  }
}
