import { useEffect, useRef, useState } from 'react';
import { bindIframeDocumentHeightSync, measureDocumentHeight } from '../utils/iframeContentHeight';
import {
  buildEditablePreviewDocument,
  MINDSPACE_PAGE_CONTENT_MESSAGE,
} from '../utils/mindspaceVisualEditor';

export function MindSpacePageEditablePreviewFrame({
  title,
  content,
  reloadKey,
  minHeight = 680,
  maxHeight = 12000,
  className,
  compact = false,
  fillViewport = false,
  showHint = true,
  onFrameReady,
  onContentChange,
}: {
  title: string;
  content: string;
  reloadKey: number;
  minHeight?: number;
  maxHeight?: number;
  className?: string;
  compact?: boolean;
  fillViewport?: boolean;
  showHint?: boolean;
  onFrameReady?: (iframe: HTMLIFrameElement | null) => void;
  onContentChange: (html: string) => void;
}) {
  const scrollInsideFrame = compact || fillViewport;
  const frameClassName =
    className ?? (compact ? 'page-save-mini-page-frame' : 'mindspace-page-preview-frame');
  const [previewFailed, setPreviewFailed] = useState(false);
  const [srcdoc, setSrcdoc] = useState(() => buildEditablePreviewDocument(content));
  const [height, setHeight] = useState(minHeight);
  const iframeContentRef = useRef(content);
  const iframeRef = useRef<HTMLIFrameElement>(null);
  const syncHeightRef = useRef<(() => void) | null>(null);

  useEffect(() => {
    iframeContentRef.current = content;
    setSrcdoc(buildEditablePreviewDocument(content));
    setPreviewFailed(false);
    setHeight(minHeight);
  }, [reloadKey]);

  useEffect(() => {
    if (content === iframeContentRef.current) return;
    iframeContentRef.current = content;
    setSrcdoc(buildEditablePreviewDocument(content));
    setPreviewFailed(false);
    setHeight(minHeight);
  }, [content, minHeight]);

  useEffect(() => {
    const onMessage = (event: MessageEvent) => {
      if (event.source !== iframeRef.current?.contentWindow) return;
      if (event.data?.type !== MINDSPACE_PAGE_CONTENT_MESSAGE) return;
      const html = String(event.data.html ?? '');
      if (!html.trim()) return;
      iframeContentRef.current = html;
      onContentChange(html);
      syncHeightRef.current?.();
    };

    window.addEventListener('message', onMessage);
    return () => window.removeEventListener('message', onMessage);
  }, [onContentChange]);

  useEffect(() => {
    if (scrollInsideFrame) {
      syncHeightRef.current = null;
      return;
    }

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

    const applyHeight = (nextHeight: number) => setHeight(nextHeight);
    const unbind = bindIframeDocumentHeightSync(iframe, {
      minHeight,
      maxHeight,
      onHeight: applyHeight,
    });
    syncHeightRef.current = () => {
      try {
        const doc = iframe.contentDocument;
        if (!doc) return;
        applyHeight(Math.min(measureDocumentHeight(doc, minHeight), maxHeight));
      } catch {
        applyHeight(minHeight);
      }
    };

    return () => {
      syncHeightRef.current = null;
      unbind();
    };
  }, [maxHeight, minHeight, scrollInsideFrame, srcdoc]);

  useEffect(() => {
    onFrameReady?.(iframeRef.current);
    return () => {
      onFrameReady?.(null);
    };
  }, [onFrameReady, reloadKey, srcdoc, minHeight, maxHeight, scrollInsideFrame, compact, fillViewport]);

  if (previewFailed) {
    return <div className="mindspace-state mindspace-error">页面预览加载失败</div>;
  }

  return (
    <>
      {showHint ? (
        <p className="mindspace-page-editable-hint">
          <span className="mindspace-page-editable-legend-swatch mindspace-page-editable-legend-swatch-text" />
          文字
          <span className="mindspace-page-editable-legend-swatch mindspace-page-editable-legend-swatch-media" />
          图片/媒体
          <span className="mindspace-page-editable-legend-swatch mindspace-page-editable-legend-swatch-link" />
          链接
          <span className="mindspace-page-editable-legend-swatch mindspace-page-editable-legend-swatch-bg" />
          背景 — 预览内左上角有完整图例，虚线框即可直接修改
        </p>
      ) : null}
      <iframe
        ref={iframeRef}
        title={`${title || '页面'} 预览`}
        srcDoc={srcdoc}
        sandbox="allow-scripts"
        scrolling={scrollInsideFrame ? 'yes' : 'no'}
        className={frameClassName}
        style={scrollInsideFrame ? { height: '100%' } : { height: `${height}px` }}
        onError={() => setPreviewFailed(true)}
      />
    </>
  );
}
