import React, { useEffect } from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
import './i18n' // Initialize i18n
import { registerSW } from 'virtual:pwa-register'
import twemoji from 'twemoji'

// Only register service worker when not in Electron (file:// protocol doesn't support SW)
const isElectron = window.location.protocol === 'file:'
if (!isElectron) {
  registerSW({
    onNeedRefresh() {
      if (confirm('New version available! Reload to update?')) {
        window.location.reload()
      }
    },
    onOfflineReady() {
      console.log('App ready to work offline')
    },
  })
}

const twemojiOpts = {
  folder: 'svg',
  ext: '.svg',
  base: 'https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/'
};

const initTwemoji = () => {
  twemoji.parse(document.body, twemojiOpts);
};

const TwemojiWrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  useEffect(() => {
    // Initial parse of entire body
    initTwemoji();

    // Collect added nodes and parse them in batches AFTER React finishes
    // its synchronous render cycle. Without deferral, Twemoji replaces
    // emoji text nodes with <img> elements while React is still
    // reconciling the DOM, causing NotFoundError on removeChild.
    let pendingNodes = new Set<Node>();
    let rafId: number | null = null;

    const processPending = () => {
      for (const node of pendingNodes) {
        // Only parse nodes still in the document (React may have removed them)
        if (node.nodeType === Node.ELEMENT_NODE && document.body.contains(node)) {
          twemoji.parse(node as HTMLElement, twemojiOpts);
        }
      }
      pendingNodes.clear();
      rafId = null;
    };

    const observer = new MutationObserver((mutations) => {
      for (const mutation of mutations) {
        for (const node of mutation.addedNodes) {
          if (node.nodeType === Node.ELEMENT_NODE) {
            pendingNodes.add(node);
          }
        }
      }
      if (pendingNodes.size > 0 && rafId === null) {
        rafId = requestAnimationFrame(processPending);
      }
    });

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

    return () => {
      observer.disconnect();
      if (rafId !== null) cancelAnimationFrame(rafId);
    };
  }, []);

  return <>{children}</>;
};

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <TwemojiWrapper>
      <App />
    </TwemojiWrapper>
  </React.StrictMode>,
)
