/**
 * PreviewPane - Live preview panel with responsive device frames
 *
 * Features:
 * - Live HTML/CSS/JavaScript preview
 * - Responsive device frames (Desktop/Mobile/Mobile Device)
 * - Sandboxed iframe for security
 * - Real-time content updates
 *
 * Security:
 * - Uses DOMPurify-based contentSanitizer.js for comprehensive XSS protection
 * - Sanitizes all HTML content before rendering in iframe
 * - Removes dangerous elements: <script>, <iframe>, <object>, <embed>, <applet>
 * - Strips event handler attributes (onclick, onload, etc.)
 * - Filters dangerous protocols (javascript:, data:, vbscript:)
 * - Variant-aware sanitization (EMAIL vs INAPP with different security levels)
 * - Iframe sandbox uses "allow-scripts" only (no allow-same-origin for security)
 * - Content delivered via srcdoc attribute for CSP compliance (replaces blob URLs)
 *
 * Previous Security Issues (FIXED):
 * - Removed insecure manual sanitizeJavaScript function that only escaped </script> tags
 * - Replaced with robust DOMPurify-based sanitization for full XSS protection
 * - Removed "allow-same-origin" from iframe sandbox to prevent same-origin access
 * - Replaced blob URLs with srcdoc to comply with CSP frame-src directives
 */

import React, { useMemo, useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from 'react-intl';

import CapRow from '@capillarytech/cap-ui-library/CapRow';

// Security utilities
import { sanitizeHTML, SANITIZER_VARIANTS } from '../../utils/contentSanitizer';

// Components
import PreviewModeGroup from '../EditorToolbar/PreviewModeGroup';
import InAppPreviewPane from '../InAppPreviewPane';

// Context
import { useEditorContext } from '../common/EditorContext';

// Constants
import { PREVIEW_MODES, HTML_EDITOR_VARIANTS } from '../../constants';
import { LAYOUT_TYPES } from '../InAppPreviewPane/constants';

// Messages
import messages from '../../messages';

// Styles
import './_previewPane.scss';

const PreviewPane = ({
  intl,
  className = '',
  isFullscreenMode = false,
  isModalContext = false,
  layoutType = LAYOUT_TYPES.MODAL,
}) => {
  const { content, layout, variant } = useEditorContext();

  // Destructure for better readability
  const { content: contentValue } = content || {};
  const { viewMode, setViewMode, mobileWidth } = layout || {};

  /**
   * Sanitize content for secure preview rendering
   *
   * This function uses the robust contentSanitizer.js utility which employs DOMPurify
   * for comprehensive XSS protection. The sanitizer handles:
   * - Script tag removal/escaping
   * - Event handler attribute removal
   * - Dangerous protocol filtering (javascript:, data:, etc.)
   * - Malicious HTML structure prevention
   *
   * The variant is determined based on the editor context - EMAIL for email templates,
   * INAPP for in-app content with more permissive multimedia support.
   */
  const combinedContent = useMemo(() => {
    if (!contentValue) {
      return '';
    }

    // Determine sanitization variant based on editor variant
    // Default to EMAIL for stricter security if variant is not available
    const sanitizationVariant = variant === HTML_EDITOR_VARIANTS.INAPP
      ? SANITIZER_VARIANTS.INAPP
      : SANITIZER_VARIANTS.EMAIL;

    // Use the robust contentSanitizer with DOMPurify for comprehensive XSS protection
    const sanitizationResult = sanitizeHTML(contentValue, sanitizationVariant);

    // Log security warnings in development for debugging
    if (process.env.NODE_ENV === 'development' && sanitizationResult.warnings.length > 0) {
      console.warn('PreviewPane: Content sanitization warnings:', sanitizationResult.warnings);
    }

    // Log removed elements in development for security awareness
    if (process.env.NODE_ENV === 'development' && sanitizationResult.removedElements.length > 0) {
      console.warn('PreviewPane: Removed potentially unsafe elements:', sanitizationResult.removedElements);
    }

    return sanitizationResult.sanitized;
  }, [contentValue, variant]);

  // Use srcdoc instead of blob URLs for CSP compliance
  // srcdoc allows embedding HTML directly in iframe without violating frame-src CSP directives
  // This is more secure and CSP-compliant than blob URLs
  const iframeContent = useMemo(() => {
    if (!combinedContent) {
      return null;
    }

    // srcdoc has a size limit (~2MB in some browsers), but for HTML preview content this should be sufficient
    // If content is too large, we'll fall back to about:blank and log a warning
    const MAX_SRCDOC_SIZE = 2000000; // 2MB limit
    if (combinedContent.length > MAX_SRCDOC_SIZE) {
      console.warn('PreviewPane: Content too large for srcdoc, using about:blank');
      return null;
    }

    return combinedContent;
  }, [combinedContent]);

  // Generate CSS classes based on view mode
  const getIframeClasses = () => {
    const baseClass = 'preview-pane__iframe';
    const classes = [baseClass];

    if (viewMode === PREVIEW_MODES.MOBILE) {
      classes.push(`${baseClass}--mobile`);
    }

    return classes.join(' ');
  };

  // Generate inline styles for responsive sizing based on view mode
  const getPreviewStyles = () => {
    const baseStyles = {};

    // Apply sizing based on current view mode
    if (viewMode === PREVIEW_MODES.MOBILE || viewMode === PREVIEW_MODES.MOBILE_DEVICE) {
      // Use layout.mobileWidth or fallback to 375px
      const width = mobileWidth || 375;
      baseStyles.width = `${width}px`;
    }
    baseStyles.height = '100%'; // Fill container height
    return baseStyles;
  };

  const renderDeviceFrame = () => (
    <iframe
      src={iframeContent ? undefined : 'about:blank'}
      srcDoc={iframeContent || undefined}
      title={intl.formatMessage(messages.htmlPreview)}
      className={getIframeClasses()}
      style={getPreviewStyles()}
      sandbox="allow-scripts"
    />
  );

  const renderEmptyState = () => (
    <div className="preview-empty">
      <div className="empty-content">
        <p className="preview-mode-info"></p>
      </div>
    </div>
  );

  // Render InApp preview for InApp variant
  if (variant === HTML_EDITOR_VARIANTS.INAPP) {
    return (
      <InAppPreviewPane
        intl={intl}
        className={className}
        isFullscreenMode={isFullscreenMode}
        isModalContext={isModalContext}
        layoutType={layoutType}
      />
    );
  }

  // Render Email preview for Email variant
  return (
    <div className={`preview-pane ${className}`}>
      <CapRow className="preview-pane__mode-controls">
        <PreviewModeGroup
          value={viewMode}
          onChange={setViewMode}
        />
      </CapRow>

      <CapRow className="preview-pane__content">
        {iframeContent ? renderDeviceFrame() : renderEmptyState()}
      </CapRow>
    </div>
  );
};

PreviewPane.propTypes = {
  intl: intlShape.isRequired,
  className: PropTypes.string,
  isFullscreenMode: PropTypes.bool,
  isModalContext: PropTypes.bool,
  layoutType: PropTypes.oneOf(Object.values(LAYOUT_TYPES)),
};

export default injectIntl(PreviewPane);
