import React, { useState, useMemo, useRef, useEffect } from 'react';
import PropTypes from 'prop-types';
import CapRow from '@capillarytech/cap-ui-library/CapRow';
import CapColumn from '@capillarytech/cap-ui-library/CapColumn';
import PreviewControls from './PreviewControls';
import NotificationContainer from './NotificationContainer';
import {
  OS_OPTIONS,
  STATE_OPTIONS,
  DEFAULT_OS,
  DEFAULT_BROWSER,
  DEFAULT_STATE,
  LAYOUT_MODE,
  DEVICE_ASSET_MAP,
} from './constants';
import {
  getBrowserOptionsForOS,
  getResolvedVariant,
  coerceStateForVariant,
  getSupportedStates,
} from './config/notificationMappings';
import './preview.scss';

/**
 * DevicePreviewContent Component
 * 
 * Displays device frame previews with web push notifications positioned
 * relative to device frames. This component will be used inside the
 * "Preview in all devices" SlideBox.
 * 
 * The component renders:
 * - Dropdown controls for OS, Browser, and State selection
 * - A background container (100% width, height determined by device frame, #F4F5F7 background)
 * - Device frames centered within the container
 * - Notification previews positioned relative to device frames (Phase 4)
 * 
 * NOTIFICATION POSITIONING SYSTEM:
 * 
 * The notification position is configured using x, y coordinates relative to the device frame.
 * Position is calculated relative to device frame boundaries, not background container.
 * 
 * @param {string} notificationTitle - Title of the notification
 * @param {string} notificationBody - Body text of the notification
 * @param {string} url - URL for the notification
 * @param {string} layoutMode - Layout mode for controls: LAYOUT_MODE.COMPACT, LAYOUT_MODE.INLINE, or LAYOUT_MODE.NEW_ROW (default: LAYOUT_MODE.COMPACT)
 */
const DevicePreviewContent = ({
  notificationTitle,
  notificationBody,
  url,
  imageSrc,
  brandIconSrc,
  buttons = [],
  layoutMode = LAYOUT_MODE.COMPACT,
}) => {
  // State for device selection
  const [selectedOS, setSelectedOS] = useState(DEFAULT_OS);
  const [selectedBrowser, setSelectedBrowser] = useState(DEFAULT_BROWSER);
  const [selectedState, setSelectedState] = useState(DEFAULT_STATE);

  // Filtered browser options per OS
  const browserOptionsForOS = useMemo(() => getBrowserOptionsForOS(selectedOS), [selectedOS]);

  // Coerce browser when OS changes and current browser is unsupported
  useEffect(() => {
    const hasBrowser = browserOptionsForOS.some((option) => option.value === selectedBrowser);
    if (!hasBrowser && browserOptionsForOS.length) {
      setSelectedBrowser(browserOptionsForOS[0].value);
    }
  }, [browserOptionsForOS, selectedBrowser]);

  // Coerce state when OS/Browser changes and current state is unsupported
  useEffect(() => {
    const coercedState = coerceStateForVariant(selectedOS, selectedBrowser, selectedState);
    if (coercedState && coercedState !== selectedState) {
      setSelectedState(coercedState);
    }
  }, [selectedOS, selectedBrowser, selectedState]);

  const stateOptionsForVariant = useMemo(() => {
    const supportedStates = getSupportedStates(selectedOS, selectedBrowser);
    if (!supportedStates.length) return STATE_OPTIONS;
    return supportedStates.map((state) => ({ value: state, label: state }));
  }, [selectedOS, selectedBrowser]);

  // Disable State dropdown when there's only one option (e.g., iOS, iPadOS)
  // Note: Can extend to pass tooltip message: { disabled: true, tooltip: "Only Collapsed state is supported" }
  const stateDropdownDisabled = useMemo(() => {
    return stateOptionsForVariant.length <= 1;
  }, [stateOptionsForVariant]);

  // Refs for measuring device frame and notification dimensions
  const deviceFrameRef = useRef(null);
  const notificationRef = useRef(null);

  // Get the device frame asset for the selected OS
  const deviceFrameAsset = useMemo(() => {
    return DEVICE_ASSET_MAP[selectedOS] || DEVICE_ASSET_MAP['macOS'];
  }, [selectedOS]);

  const resolvedVariant = useMemo(() => {
    return getResolvedVariant(selectedOS, selectedBrowser, selectedState);
  }, [selectedOS, selectedBrowser, selectedState]);

  // Notification position using x, y coordinates from variant configuration
  const notificationPosition = useMemo(() => {
    if (resolvedVariant?.stateConfig?.position?.custom) {
      return resolvedVariant.stateConfig.position.custom;
    }
    // Fallback to origin (0, 0) if no position configured
    return { x: 0, y: 0 };
  }, [resolvedVariant]);

  const handleOSChange = (value) => {
    setSelectedOS(value);
  };

  const handleBrowserChange = (value) => {
    setSelectedBrowser(value);
  };

  const handleStateChange = (value) => {
    setSelectedState(value);
  };

  return (
    <CapRow>
      <CapColumn span={24}>
        {/* Dropdown Controls */}
        <PreviewControls
          selectedOS={selectedOS}
          selectedBrowser={selectedBrowser}
          selectedState={selectedState}
          osOptions={OS_OPTIONS}
          browserOptions={browserOptionsForOS}
          stateOptions={stateOptionsForVariant}
          onOSChange={handleOSChange}
          onBrowserChange={handleBrowserChange}
          onStateChange={handleStateChange}
          layoutMode={layoutMode}
          showStateDropdown={true}
          stateDropdownDisabled={stateDropdownDisabled}
        />

        {/* Background Container - Preview Section */} 
        <div className="device-preview-container">
          {/* Device Frame Display */}
          {/* Device frames are centered horizontally and vertically within the container */}
          <div className="device-frame-wrapper">
            <div className="device-frame-asset">
              <img
                ref={deviceFrameRef}
                src={deviceFrameAsset}
                alt={`${selectedOS} device frame`}
                className="device-frame"
              />
              {/* Notification preview positioned relative to the device frame image */}
              {/* Inline styles kept: Dynamic positioning calculated at runtime based on OS/browser/state selection.
                  These values change with user interaction and cannot be moved to static SCSS. 
                  notificationPosition is computed from variant configuration and device frame measurements. */}
              <div
                ref={notificationRef}
                className={`device-notification-wrapper ${resolvedVariant ? '' : 'preview-unavailable'}`.trim()}
                style={{
                  position: 'absolute',
                  left: `${notificationPosition?.x || 0}px`,
                  ...(notificationPosition?.bottom !== undefined
                    ? { bottom: `${notificationPosition.bottom}px` }
                    : { top: `${notificationPosition?.y || 0}px` }),
                  zIndex: 10,
                }}
              >
                {resolvedVariant && (
                  <NotificationContainer
                    notificationTitle={notificationTitle}
                    notificationBody={notificationBody}
                    url={url}
                    selectedOS={selectedOS}
                    selectedBrowser={selectedBrowser}
                    notificationState={resolvedVariant.stateKey}
                    icon={resolvedVariant.variant.icon}
                    supportsExpanded={resolvedVariant.stateConfig.supportsExpanded}
                    enableMedia={resolvedVariant.stateConfig.showMedia}
                    enableCtas={buttons.length > 0}
                    className={resolvedVariant.variant.notificationClassName}
                    imageSrc={imageSrc}
                    brandIconSrc={brandIconSrc}
                    buttons={buttons}
                    showSeparateIOSCTAs={true}
                  />
                )}
              </div>
            </div>
          </div>
        </div>
      </CapColumn>
    </CapRow>
  );
};

DevicePreviewContent.propTypes = {
  notificationTitle: PropTypes.string,
  notificationBody: PropTypes.string,
  url: PropTypes.string,
  imageSrc: PropTypes.string,
  brandIconSrc: PropTypes.string,
  buttons: PropTypes.arrayOf(
    PropTypes.shape({
      text: PropTypes.string,
      url: PropTypes.string,
      type: PropTypes.string,
    })
  ),
  layoutMode: PropTypes.oneOf([LAYOUT_MODE.COMPACT, LAYOUT_MODE.INLINE, LAYOUT_MODE.NEW_ROW]),
};

DevicePreviewContent.defaultProps = {
  notificationTitle: '',
  notificationBody: '',
  url: '',
  imageSrc: '',
  brandIconSrc: '',
  buttons: [],
  layoutMode: LAYOUT_MODE.COMPACT,
};

export default DevicePreviewContent;

