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

const UNKNOWN_ERROR = "Erreur frontend inconnue";

export function installGlobalErrorLogging(): void {
  const globalWindow = globalThis.window;
  if (!globalWindow || globalWindow.__IDEA_GLOBAL_ERROR_LOGGING__) return;
  globalWindow.__IDEA_GLOBAL_ERROR_LOGGING__ = true;

  globalWindow.addEventListener("error", (event) => {
    console.error("[idea-ui] uncaught error", {
      message: event.message,
      filename: event.filename,
      lineno: event.lineno,
      colno: event.colno,
      error: event.error,
    });
  });

  globalWindow.addEventListener("unhandledrejection", (event) => {
    console.error("[idea-ui] unhandled promise rejection", event.reason);
  });
}

interface RootErrorBoundaryProps {
  children: ReactNode;
}

interface RootErrorBoundaryState {
  error: Error | null;
  componentStack: string | null;
}

export class RootErrorBoundary extends Component<
  RootErrorBoundaryProps,
  RootErrorBoundaryState
> {
  state: RootErrorBoundaryState = {
    error: null,
    componentStack: null,
  };

  static getDerivedStateFromError(error: Error): RootErrorBoundaryState {
    return { error, componentStack: null };
  }

  componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
    console.error("[idea-ui] root render failed", error, errorInfo);
    this.setState({ componentStack: errorInfo.componentStack ?? null });
  }

  render(): ReactNode {
    const { error, componentStack } = this.state;
    if (!error) return this.props.children;

    const message = error.message || UNKNOWN_ERROR;
    const details = [error.stack, componentStack].filter(Boolean).join("\n\n");

    return (
      <main className="flex h-full items-center justify-center bg-canvas p-6 text-content">
        <section
          role="alert"
          aria-labelledby="root-error-title"
          className="flex w-full max-w-2xl flex-col gap-4 rounded-lg border border-danger/50 bg-surface p-5 shadow-xl"
        >
          <div className="flex flex-col gap-1">
            <p className="text-xs font-medium uppercase text-danger">
              Interface interrompue
            </p>
            <h1 id="root-error-title" className="text-lg font-semibold">
              IdeA a rencontré une erreur d'affichage.
            </h1>
            <p className="text-sm text-muted">
              L'application reste ouverte. Rechargez la fenêtre après avoir copié
              le diagnostic si le problème doit être investigué.
            </p>
          </div>

          <pre className="max-h-72 overflow-auto rounded-md border border-border bg-canvas p-3 font-mono text-xs leading-relaxed text-muted">
            {details || message}
          </pre>

          <div className="flex justify-end">
            <button
              type="button"
              className="rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-on-primary hover:bg-primary-hover"
              onClick={() => window.location.reload()}
            >
              Recharger
            </button>
          </div>
        </section>
      </main>
    );
  }
}

declare global {
  interface Window {
    __IDEA_GLOBAL_ERROR_LOGGING__?: boolean;
  }
}
