import { MantineProvider } from '@mantine/core';
import '@mantine/core/styles.css';
import '@mantine/dates/styles.css';
import '@mantine/tiptap/styles.css';
import { BrowserAgent } from '@newrelic/browser-agent/loaders/browser-agent';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import 'mac-scrollbar/dist/mac-scrollbar.css';
import { configure } from 'mobx';
import React from 'react';
import { createRoot } from 'react-dom/client';
import 'react-toastify/dist/ReactToastify.css';
import 'reflect-metadata';
import { App } from './app';
import './app/config/i18n/i18n';
import NewrelicConfig from './app/config/newrelic/newrelic';
import './app/styles/main.css';
import { MultichatProvider } from './modules/multichat';
import { TelephonyProvider } from './modules/telephony';
import { envUtil } from './shared';

// Error Boundary Component
class ErrorBoundary extends React.Component<{ children: React.ReactNode }, { hasError: boolean; error?: Error }> {
  constructor(props: { children: React.ReactNode }) {
    super(props);
    this.state = { hasError: false };
  }

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

  componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
    console.error('Application error:', error, errorInfo);
    // Send error to logging service if available
    if (window.gtag) {
      window.gtag('event', 'exception', {
        description: error.toString(),
        fatal: false,
      });
    }
  }

  render() {
    if (this.state.hasError) {
      return (
        <div style={{ padding: '20px', textAlign: 'center' }}>
          <h2>Something went wrong</h2>
          <p>The application encountered an error. Please try refreshing the page.</p>
          <button onClick={() => window.location.reload()}>Refresh Page</button>
          {process.env.NODE_ENV === 'development' && (
            <details style={{ marginTop: '20px', textAlign: 'left' }}>
              <summary>Error Details</summary>
              <pre>{this.state.error?.stack}</pre>
            </details>
          )}
        </div>
      );
    }

    return this.props.children;
  }
}

declare global {
  interface Window {
    dataLayer: any;
    gtag: any;
  }
}

if (envUtil.newRelicEnabled) new BrowserAgent(NewrelicConfig);

export const queryClient = new QueryClient();

const container = document.getElementById('root') as HTMLElement;
const root = createRoot(container);

// this way mobx will consider all actions in methods as they are wrapped in runInAction
setTimeout(() => {
  configure({
    enforceActions: 'never',
    isolateGlobalState: true,
    reactionScheduler: f => setTimeout(f),
  });
});

root.render(
  <ErrorBoundary>
    <QueryClientProvider client={queryClient}>
      <MantineProvider>
        <TelephonyProvider>
          <MultichatProvider>
            <App />
          </MultichatProvider>
        </TelephonyProvider>
      </MantineProvider>

      {envUtil.reactQueryDevtoolsEnabled && <ReactQueryDevtools initialIsOpen={false} />}
    </QueryClientProvider>
  </ErrorBoundary>
);
