/** @jsxImportSource react */
import { Component, type ErrorInfo, type ReactNode } from "react";

export interface IslandErrorBoundaryProps {
  name: string;
  development: boolean;
  /** Optional so createElement(Boundary, props, child) typechecks. */
  children?: ReactNode;
}

interface IslandErrorBoundaryState {
  error: Error | null;
}

/**
 * Contains island failures locally: a crashed island must never blank the
 * surrounding server-rendered page.
 */
export class IslandErrorBoundary extends Component<
  IslandErrorBoundaryProps,
  IslandErrorBoundaryState
> {
  override state: IslandErrorBoundaryState = { error: null };

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

  override componentDidCatch(error: Error, info: ErrorInfo): void {
    console.error(`[wrnexus] island '${this.props.name}' failed to render`, error, info);
  }

  override render(): ReactNode {
    const { error } = this.state;
    if (!error) return this.props.children;
    if (!this.props.development) return null;
    return (
      <div data-wrn-island-error={this.props.name} style={{ padding: "0.75rem" }}>
        <strong>{`Island '${this.props.name}' failed`}</strong>
        <pre>{error.stack ?? error.message}</pre>
      </div>
    );
  }
}
