'use client';
import { useEffect, useRef, useState } from 'react';
import ReactDOM from 'react-dom';
import { cn } from '@/lib/utils';
import { ViewportSimulatorProps } from '@/types/preview';

export function ViewportSimulator({ viewportConfig, children, className }: ViewportSimulatorProps) {
  const iframeRef = useRef<HTMLIFrameElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  const [rootElement, setRootElement] = useState<HTMLElement | null>(null);
  const [isLoading, setIsLoading] = useState(true);

  const syncThemeWithIframe = (swapValues: boolean = true) => {
    const iframe = iframeRef.current;
    if (!iframe?.contentDocument) return;
    const computedStyle = getComputedStyle(document.documentElement);
    const currentBackground = computedStyle.getPropertyValue('--color-background').trim();
    const currentText = computedStyle.getPropertyValue('--color-text').trim();
    iframe.contentDocument.documentElement.style.setProperty('--color-background', swapValues ? currentText : currentBackground);
    iframe.contentDocument.documentElement.style.setProperty('--color-text', swapValues ? currentBackground : currentText);
  };

  useEffect(() => {
    if (viewportConfig.isFullWidth) {
      return;
    }

    const iframe = iframeRef.current;
    if (!iframe || iframe.srcdoc) return;

    const handleIframeLoad = () => {
      const doc = iframe.contentDocument;
      if (!doc) return;

      setIsLoading(true);

      const linkTags = document.querySelectorAll('link[rel="stylesheet"]');
      const stylesheets = Array.from(linkTags);
      let loadedStylesheets = 0;

      const checkAllStylesLoaded = () => {
        loadedStylesheets++;
        if (loadedStylesheets === stylesheets.length) {
          setupIframeContent(doc);
        }
      };

      const handleLinkClick = (event: MouseEvent) => {
        const target = event.target as HTMLElement;
        if (target.tagName === 'A') {
          event.preventDefault();
        }
      };

      doc.addEventListener('click', handleLinkClick);

      stylesheets.forEach((linkTag) => {
        const newLink = doc.createElement('link');
        newLink.rel = 'stylesheet';
        newLink.href = linkTag.getAttribute('href') ?? '';
        newLink.onload = checkAllStylesLoaded;
        newLink.onerror = checkAllStylesLoaded;
        doc.head.appendChild(newLink);
      });

      if (stylesheets.length === 0) {
        setupIframeContent(doc);
      }
    };

    const setupIframeContent = (doc: Document) => {
      const computedStyle = getComputedStyle(document.documentElement);
      const cssVars = [
        '--color-background',
        '--color-text',
        '--color-accent',
        '--heading-font-family',
        '--text-font-family',
      ];

      const cssVarsStyle = doc.createElement('style');
      cssVarsStyle.textContent = `
        :root {
          ${cssVars.map((varName) => `${varName}: ${computedStyle.getPropertyValue(varName)};`).join('\n')}
        }
      `;
      doc.head.appendChild(cssVarsStyle);

      const viewportMeta = doc.createElement('meta');
      viewportMeta.name = 'viewport';
      viewportMeta.content = 'width=device-width, initial-scale=1';
      doc.head.appendChild(viewportMeta);

      const style = doc.createElement('style');
      style.textContent = `
        html, body {
          margin: 0;
          padding: 0;
          width: 100%;
          height: 100%;
          background-color: var(--color-background);
          color: var(--color-text);
          font-family: var(--text-font-family);
          overflow-y: auto;
        }

        ::selection {
          background-color: var(--color-accent);
          color: var(--color-background);
        }
        
        #root {
          width: 100%;
          height: 100%;
          min-height: 100%;
          display: flex;
          flex-direction: column;
        }

        h1, h2, h3, h4, h5, h6 {
          font-family: var(--heading-font-family);
        }

        * {
          box-sizing: border-box;
        }
      `;
      doc.head.appendChild(style);

      const root = doc.getElementById('root') || doc.body;
      setRootElement(root);
      setIsLoading(false);
      syncThemeWithIframe(false);
    };

    iframe.onload = handleIframeLoad;

    const iframeHTML = `
      <!DOCTYPE html>
      <html>
        <head>
          <meta charset="utf-8">
          <title>Viewport Simulator</title>
        </head>
        <body>
          <div id="root"></div>
        </body>
      </html>
    `;

    if (!iframe.srcdoc) {
      iframe.srcdoc = iframeHTML;
    }
  }, [viewportConfig.width, viewportConfig.isFullWidth]);

  useEffect(() => {
    const observer = new MutationObserver((mutations) => {
      mutations.forEach((mutation) => {
        if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
          syncThemeWithIframe();
        }
      });
    });

    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['style'],
    });

    return () => observer.disconnect();
  }, []);

  useEffect(() => {
    const storageChangeListener = (event: StorageEvent) => {
      if (event.storageArea === localStorage) {
        syncThemeWithIframe();
      }
    };

    window.addEventListener('storage', storageChangeListener);

    return () => window.removeEventListener('storage', storageChangeListener);
  }, []);

  if (viewportConfig.isFullWidth) {
    return (
      <div className='flex items-center justify-center h-screen pt-16 w-full'>
        <div className='w-full h-full overflow-auto bg-[var(--color-background)]'>{children}</div>
      </div>
    );
  }

  return (
    <div
      ref={containerRef}
      className={cn('relative shadow-2xl border-2 border-neutral-800 mt-16 rounded-md max-h-[90%]', className)}
      style={{
        width: typeof viewportConfig.width === 'number' ? viewportConfig.width : '100%',
        height: typeof viewportConfig.height === 'number' ? viewportConfig.height : '100%',
        transition: 'height 0.5s ease-out, width 0.5s ease-out',
        maxHeight: '85vh',
      }}
    >
      <iframe
        ref={iframeRef}
        className='w-full h-full border-1 bg-white'
        style={{
          width: '100%',
          height: '100%',
        }}
        title='Viewport Simulator'
      />
      {!isLoading && rootElement && ReactDOM.createPortal(children, rootElement)}
    </div>
  );
}
