import { Component, type ReactNode } from "react";
// @ts-ignore
import { BlockMath, InlineMath } from "react-katex";

// ─── Error boundary ───────────────────────────────────────────────────────────
// react-katex throws synchronously during render for invalid LaTeX, so a class
// error boundary is the only reliable way to catch it.

interface MathErrorBoundaryProps {
  raw: string; // the original LaTeX string, shown as fallback
  children: ReactNode;
}

interface MathErrorBoundaryState {
  failed: boolean;
}

export class MathErrorBoundary extends Component<
  MathErrorBoundaryProps,
  MathErrorBoundaryState
> {
  state: MathErrorBoundaryState = { failed: false };

  static getDerivedStateFromError(): MathErrorBoundaryState {
    return { failed: true };
  }

  render() {
    if (this.state.failed) {
      return (
        <span
          title={`Could not render: ${this.props.raw}`}
          style={{
            fontFamily: "monospace",
            background: "rgba(239,68,68,0.08)",
            border: "1px solid rgba(239,68,68,0.3)",
            borderRadius: 4,
            padding: "0 4px",
            color: "#f87171",
            fontSize: "0.9em",
          }}
        >
          {this.props.raw}
        </span>
      );
    }
    return this.props.children;
  }
}

// ─── Renderer ─────────────────────────────────────────────────────────────────

export const renderQuestionText = (text: string) => {
  if (!text) return null;
  const parts = text.split(/(\$\$.*?\$\$|\$.*?\$)/gs);

  return (
    <>
      {parts.map((part, index) => {
        if (part.startsWith("$$")) {
          const latex = part.slice(2, -2);
          return (
            <MathErrorBoundary key={index} raw={part}>
              <BlockMath>{latex}</BlockMath>
            </MathErrorBoundary>
          );
        }
        if (part.startsWith("$")) {
          const latex = part.slice(1, -1);
          return (
            <MathErrorBoundary key={index} raw={part}>
              <InlineMath>{latex}</InlineMath>
            </MathErrorBoundary>
          );
        }
        return <span key={index}>{part}</span>;
      })}
    </>
  );
};
