// 全局错误边界组件 — 防止页面渲染错误导致白屏
// 使用方式：在 app.tsx 中包裹 children

import { Component, ReactNode } from "react";
import { View, Text, Button } from "@tarojs/components";

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

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

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

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

  componentDidCatch(error: Error, info: any) {
    console.error("[ErrorBoundary]", error, info?.componentStack);
    // 可选：上报到监控平台
    // reportError(error, info);
  }

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

  handleRestart = () => {
    // 小程序没有 window.location.reload，用 reLaunch 回首页
    const Taro = require("@tarojs/taro").default;
    Taro.reLaunch({ url: "/pages/home/index" });
  };

  render() {
    if (this.state.hasError) {
      if (this.props.fallback) {
        return this.props.fallback;
      }
      return (
        <View style={{ padding: "80rpx 40rpx", textAlign: "center" }}>
          <Text style={{ fontSize: "36rpx", fontWeight: "bold", display: "block", marginBottom: "24rpx" }}>
            😵 页面出了点问题
          </Text>
          <Text style={{ fontSize: "26rpx", color: "#999", display: "block", marginBottom: "40rpx" }}>
            {this.state.error?.message || "未知错误"}
          </Text>
          <View style={{ display: "flex", gap: "24rpx", justifyContent: "center" }}>
            <Button size="mini" onClick={this.handleReload}>重试</Button>
            <Button size="mini" type="primary" onClick={this.handleRestart}>回首页</Button>
          </View>
        </View>
      );
    }
    return this.props.children;
  }
}

/**
 * 页面级错误边界工厂 — 各页面可自定义 fallback
 * 用法：
 *   export default PageWrap(function MyPage() { ... })
 *   export default PageWrap(function MyPage() { ... }, customFallback)
 */
export function PageWrap(PageComponent: React.FC<any>, fallback?: ReactNode) {
  return function WrappedPage(props: any) {
    return (
      <ErrorBoundary fallback={fallback}>
        <PageComponent {...props} />
      </ErrorBoundary>
    );
  };
}
