"use client";

import React, { Component, ErrorInfo, ReactNode } from 'react';
import serverLogging from "@/core/common/ErrorBoundary/action";
import ErrorBoundaryInterface from "@/core/common/ErrorBoundary/component";

interface ErrorBoundaryProps {
  children: ReactNode;
}

interface ErrorBoundaryState {
  hasError: boolean;
  error?: Error;
}

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

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

  componentDidCatch(error: Error, errorInfo: ErrorInfo) {
    this
      .setError(error)
      .logErrorToServer(error, errorInfo)
      .then(() => console.log("INFO: Error info translated to the server"));
  }

  setError(error: Error) {
    this.setState(p => ({ ...p, error }));
    return this;
  }

  async logErrorToServer(error: Error, errorInfo: ErrorInfo) {
    const serializedError = JSON.stringify({
      error: error.toString(),
      errorInfo: errorInfo.componentStack
    });
    await serverLogging(serializedError);
  }

  render() {
    if (this.state.hasError) {
      return (
        <ErrorBoundaryInterface message={this.state.error?.message}
                                stack={this.state.error?.stack} />);
    }
    return this.props.children;
  }
}

export default ErrorBoundary;
