import React from "react";

import { api } from "../api";
import { useI18n } from "../i18n/I18nProvider";

type Props = {
  children: React.ReactNode;
};

type ErrorBoundaryInnerProps = Props & {
  t: (key: "errorBoundaryTitle" | "errorBoundaryBody" | "errorBoundaryUnknown" | "errorBoundaryRefresh") => string;
};

type State = {
  hasError: boolean;
  errorId?: string;
};

class ErrorBoundaryInner extends React.Component<ErrorBoundaryInnerProps, State> {
  state: State = { hasError: false };

  static getDerivedStateFromError() {
    return { hasError: true };
  }

  componentDidCatch(error: any, info: any) {
    const errorId = `ui_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
    this.setState({ errorId });

    void api.post("/client-errors", {
      errorId,
      message: String(error?.message ?? error),
      stack: String(error?.stack ?? ""),
      componentStack: String(info?.componentStack ?? ""),
      url: window.location.href,
      userAgent: navigator.userAgent,
      at: new Date().toISOString(),
    });
  }

  render() {
    if (!this.state.hasError) return this.props.children;

    return (
      <div style={{ padding: 24, maxWidth: 820, margin: "0 auto" }}>
        <h2 style={{ margin: "0 0 8px 0" }}>{this.props.t("errorBoundaryTitle")}</h2>
        <div style={{ opacity: 0.8, marginBottom: 16 }}>
          {this.props.t("errorBoundaryBody")}
          <div style={{ fontFamily: "monospace", marginTop: 6 }}>
            {this.state.errorId ?? this.props.t("errorBoundaryUnknown")}
          </div>
        </div>
        <button onClick={() => window.location.reload()}>{this.props.t("errorBoundaryRefresh")}</button>
      </div>
    );
  }
}

export default function ErrorBoundary(props: Props) {
  const { t } = useI18n();
  return <ErrorBoundaryInner {...props} t={t} />;
}
