// ErrorBoundary：React 渲染异常兜底
// 依据：01-understanding.md §9.1 复用 Shell 暴露的 ErrorBoundary
// 独立模式下使用本地实现，MF 模式下由 Shell 提供

"use client";

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

interface ErrorBoundaryProps {
  children: ReactNode;
  fallback?: ReactNode;
}

interface ErrorBoundaryState {
  hasError: boolean;
  error: Error | null;
}

export class ErrorBoundary extends Component<
  ErrorBoundaryProps,
  ErrorBoundaryState
> {
  constructor(props: ErrorBoundaryProps) {
    super(props);
    this.state = { hasError: false, error: null };
  }

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

  override componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
    // 生产环境上报到监控系统（P6-1 OTel 接入后替换）
    if (process.env.NODE_ENV === "production") {
      console.error("[ErrorBoundary]", error, errorInfo.componentStack);
    } else {
      console.error("[ErrorBoundary]", error, errorInfo);
    }
  }

  handleReset = (): void => {
    this.setState({ hasError: false, error: null });
  };

  override render(): ReactNode {
    if (this.state.hasError) {
      if (this.props.fallback) {
        return this.props.fallback;
      }

      return (
        <div className="flex min-h-[400px] flex-col items-center justify-center gap-4 p-8">
          <div className="text-center">
            <h2 className="font-serif text-xl text-ink">页面渲染异常</h2>
            <p className="mt-2 text-sm text-ink-muted">
              抱歉，页面遇到了问题。请尝试刷新或返回首页。
            </p>
          </div>
          <div className="flex gap-3">
            <button
              type="button"
              onClick={this.handleReset}
              className="rounded-lg border border-rule px-4 py-2 text-sm text-ink-muted hover:bg-paper-elevated"
            >
              重试
            </button>
            <a
              href="/parent/dashboard"
              className="rounded-lg bg-accent px-4 py-2 text-sm text-paper hover:opacity-90"
            >
              返回首页
            </a>
          </div>
          {process.env.NODE_ENV === "development" && this.state.error && (
            <pre className="mt-4 max-w-2xl overflow-x-auto rounded-lg border border-rule bg-paper-elevated p-4 text-xs text-danger">
              {this.state.error.stack}
            </pre>
          )}
        </div>
      );
    }

    return this.props.children;
  }
}

export default ErrorBoundary;
