import { useRef, useEffect, isValidElement, createElement } from 'react';
import { createRoot } from 'react-dom/client';

const isDOMElement = (obj) => obj instanceof HTMLElement;
const isReactElement = (child) => isValidElement(child);

// Transform React elements to DOM, or return DOM elements as-is
const domify = (element, ...args) => {
  // If it's already a DOM element, return it directly
  if (isDOMElement(element)) return element;
  
  // If it's a React element, bridge it and return the DOM container
  if (isReactElement(element)) {
    const container = document.createElement('div');
    container.style.display = 'contents';
    const root = createRoot(container);
    root.render(element);
    // Store root for potential cleanup
    container._reactRoot = root;
    return container;
  }

  // If it's a function (React component), create element with props and children
  if (typeof element === 'function') {
    const [props, ...children] = args;
    const reactElement = createElement(element, props, ...children);
    return domify(reactElement);
  }

  return null;
};

// Process mixed children (React elements or DOM elements)
const processChild = (child) => {
  // If it's a function, call it and process the result
  if (typeof child === 'function') {
    const result = child();
    return processChild(result);
  }
  // If it's an object with .element property (like ZikoJS UIElement)
  if (
    child &&
    typeof child === 'object' &&
    'element' in child &&
    isDOMElement(child.element)
  ) return child.element;
  
  // Use domify for all other cases (DOM elements, React elements, or React components)
  return domify(child);
};

export function DOMWrapper({ children }) {
  const containerRef = useRef(null);
  const mountedRootsRef = useRef([]);

  useEffect(() => {
    if (!containerRef.current || !children) return;

    // Cleanup previous React roots
    mountedRootsRef.current.forEach((root) => {
      if (root?.unmount) {
        root.unmount();
      }
    });
    mountedRootsRef.current = [];

    containerRef.current.innerHTML = '';
    const childArray = Array.isArray(children) ? children : [children];

    childArray.forEach((child) => {
      const processedElement = processChild(child);

      if (processedElement instanceof HTMLElement) {
        containerRef.current.appendChild(processedElement);

        // Track React roots for cleanup
        if (processedElement._reactRoot) {
          mountedRootsRef.current.push(processedElement._reactRoot);
        }
      }
    });

    // Cleanup function
    return () => {
      mountedRootsRef.current.forEach((root) => {
        if (root?.unmount) {
          root.unmount();
        }
      });
      mountedRootsRef.current = [];
    };
  }, [children]);

  return <div ref={containerRef} style={{ display: 'contents' }} />;
}

// Pure DOM element creators
const createButton = (text, onClick) => {
  const btn = document.createElement('button');
  btn.textContent = text;
  btn.style.cssText =
    'padding: 8px 16px; margin: 5px; background: #4CAF50; color: white; border: none; cursor: pointer; border-radius: 4px;';
  if (onClick) btn.onclick = onClick;
  return btn;
};

const createParagraph = (text) => {
  const p = document.createElement('p');
  p.textContent = text;
  p.style.margin = '10px 0';
  return p;
};

const createCard = (title, ...children) => {
  const card = document.createElement('div');
  card.style.cssText =
    'padding: 15px; border: 2px solid #4CAF50; margin: 10px; border-radius: 8px; background: #f0f0f0;';

  const titleEl = document.createElement('h4');
  titleEl.textContent = title;
  titleEl.style.marginTop = '0';
  card.appendChild(titleEl);

  children.forEach((child) => {
    const element = domify(child);
    if (element) {
      card.appendChild(element);
    }
  });

  return card;
};

// You can also use domify directly with React components
const createReactButton = (onClick, ...children) => {
  return domify(ReactButton, { onClick }, ...children);
};

// React component
function ReactCard({ title, children, color = '#2196F3' }) {
  return (
    <div
      style={{
        padding: '15px',
        border: `2px solid ${color}`,
        margin: '10px',
        borderRadius: '8px',
        background: color === '#2196F3' ? '#e3f2fd' : '#fff3e0',
      }}
    >
      <h4 style={{ marginTop: 0 }}>{title}</h4>
      {children}
    </div>
  );
}

function ReactButton({ children, onClick }) {
  return (
    <button
      onClick={onClick}
      style={{
        padding: '8px 16px',
        margin: '5px',
        background: '#2196F3',
        color: 'white',
        border: 'none',
        cursor: 'pointer',
        borderRadius: '4px',
      }}
    >
      {children}
    </button>
  );
}

// Demo
export default function Demo() {
  return (
    <div style={{ padding: '20px', fontFamily: 'sans-serif' }}>
      <h2>DOMWrapper - Interleaving Demo (Refactored)</h2>
      <p style={{ color: '#666' }}>
        Seamlessly mix DOM elements and React components with domify()
      </p>

      <div style={{ marginTop: '20px' }}>
        <h3>Example 1: Simple DOM Elements</h3>
        <DOMWrapper>
          {createParagraph('This is a pure DOM paragraph')}
          {createButton('DOM Button', () => alert('DOM button clicked!'))}
          {createReactButton(() => alert('domified'), 'Domified Button')}
        </DOMWrapper>
      </div>

      <div style={{ marginTop: '20px' }}>
        <h3>Example 2: React Components with Props & Children</h3>
        <DOMWrapper>
          {createCard(
            'DOM Card with React Inside',
            createParagraph('DOM paragraph'),
            <ReactCard title="Props Work!" color="#FF9800">
              <p>This ReactCard has props: title and color</p>
              <ReactButton onClick={() => alert('Children work too!')}>
                Click Me - I'm a child!
              </ReactButton>
            </ReactCard>,
            <ReactCard title="Multiple React Components">
              <p>You can domify multiple React components</p>
              <p>Each with their own props and children</p>
            </ReactCard>
          )}
        </DOMWrapper>
      </div>

      <div style={{ marginTop: '20px' }}>
        <h3>Example 3: DOM → React</h3>
        <DOMWrapper>
          {createCard(
            'DOM Card',
            createParagraph('This is DOM content'),
            <ReactCard title="Nested React Card">
              <p>This is React content inside a DOM element!</p>
              <ReactButton onClick={() => alert('React button!')}>
                React Button
              </ReactButton>
            </ReactCard>
          )}
        </DOMWrapper>
      </div>

      <div style={{ marginTop: '20px' }}>
        <h3>Example 4: React → DOM</h3>
        <DOMWrapper>
          <ReactCard title="React Card" color="#FF9800">
            <p>React component here</p>
            <DOMWrapper>
              {createParagraph('DOM content inside React!')}
              {createButton('DOM Button Inside React', () => alert('Works!'))}
            </DOMWrapper>
          </ReactCard>
        </DOMWrapper>
      </div>

      <div style={{ marginTop: '20px' }}>
        <h3>Example 5: Deep Nesting (DOM → React → DOM → React)</h3>
        <DOMWrapper>
          {createCard(
            'Level 1: DOM',
            createParagraph('DOM content'),
            <ReactCard title="Level 2: React">
              <p>React component</p>
              <DOMWrapper>
                {createCard(
                  'Level 3: DOM',
                  createParagraph('Back to DOM!'),
                  <ReactCard title="Level 4: React" color="#FF9800">
                    <p>🎉 Full interleaving works!</p>
                    <ReactButton onClick={() => alert('Deep nested button!')}>
                      Click Me
                    </ReactButton>
                  </ReactCard>
                )}
              </DOMWrapper>
            </ReactCard>
          )}
        </DOMWrapper>
      </div>

      <div style={{ marginTop: '20px' }}>
        <h3>Example 6: Mixed Array</h3>
        <DOMWrapper>
          {[
            createParagraph('First DOM element'),
            <ReactCard title="React in the middle">
              <DOMWrapper>
                {createButton('Nested DOM Button', () => alert('Nested!'))}
              </DOMWrapper>
            </ReactCard>,
            createParagraph('Last DOM element'),
          ]}
        </DOMWrapper>
      </div>
    </div>
  );
}
