import { createRoot } from 'react-dom/client';
import { Root } from 'react-dom/client';

import Cmdb from '../components/Cmdb';
import { ThemeListener } from '../components/ThemeListener/ThemeListener';
import { Provider } from 'react-redux';
import '../styles.scss';
import { store } from '../components/Cmdb/store';

let root: Root | null = null;
let propsObserver: MutationObserver | null = null;

// observer body change and mount component
// as root element might not be rendered on the loading time
const mountReactComponent = () => {
  const el = document.querySelector('#cmdb-root:not([data-react-mounted])');

  if (el) {
    let data;
    try {
      data = JSON.parse((el as HTMLElement).dataset.props || '{}');
    } catch (e) {
      return;
    }

    root = createRoot(el as HTMLElement);
    root.render(
      <Provider store={store}>
        <ThemeListener>
          <Cmdb
            identifier={data?.identifier}
            displayShowJson={data?.displayShowJson}
            ishub={data?.ishub}
            cmdbServiceUrl={data?.cmdbServiceUrl || ''}
          />
        </ThemeListener>
      </Provider>
    );

    // Mark the element to avoid re-rendering
    el.setAttribute('data-react-mounted', 'true');

    // watch for changes to data-props attribute
    propsObserver = new MutationObserver((mutations) => {
      mutations.forEach((mutation) => {
        if (mutation.type === 'attributes' && mutation.attributeName === 'data-props') {
          let updatedData;
          try {
            updatedData = JSON.parse((el as HTMLElement).dataset.props || '{}');
          } catch (e) {
            return;
          }

          if (root) {
            root.render(
              <Provider store={store}>
                <ThemeListener>
                  <Cmdb
                    identifier={updatedData?.identifier}
                    displayShowJson={updatedData?.displayShowJson}
                    ishub={updatedData?.ishub}
                    cmdbServiceUrl={updatedData?.cmdbServiceUrl || ''}
                  />
                </ThemeListener>
              </Provider>
            );
          }
        }
      });
    });

    propsObserver.observe(el, { attributes: true, attributeFilter: ['data-props'] });
  }
};

const observer = new MutationObserver(() => {
  mountReactComponent();
});

observer.observe(document.body, { childList: true, subtree: true });
mountReactComponent();
