import React from 'react';
import { act } from 'react-dom/test-utils';
import { mountWithIntl, shallowWithIntl } from '../../../../../helpers/intl-enzym-test-helpers';
import WebPushPreview from '../WebPushPreview';
import PreviewControls from '../PreviewControls';
import PreviewContent from '../PreviewContent';
import PreviewDisclaimer from '../PreviewDisclaimer';
import DevicePreviewContent from '../DevicePreviewContent';
import CapSlideBox from '@capillarytech/cap-ui-library/CapSlideBox';
import CapButton from '@capillarytech/cap-ui-library/CapButton';
import CapRow from '@capillarytech/cap-ui-library/CapRow';
import CapColumn from '@capillarytech/cap-ui-library/CapColumn';
import {
  OS_OPTIONS,
  DEFAULT_OS,
  DEFAULT_BROWSER,
  OS_MACOS,
  OS_WINDOWS,
  OS_IOS,
  OS_IPADOS,
  OS_ANDROID_MOBILE,
  OS_ANDROID_TABLET,
  BROWSER_CHROME,
  BROWSER_FIREFOX,
  BROWSER_EDGE,
  BROWSER_SAFARI,
  BROWSER_OPERA,
} from '../constants';
import { getBrowserOptionsForOS } from '../config/notificationMappings';

// Mock CapSlideBox to control its behavior in tests
jest.mock('@capillarytech/cap-ui-library/CapSlideBox', () => {
  const React = require('react');
  return function MockCapSlideBox({ show, handleClose, content, header, className, size }) {
    // Always render the component (even when show is false) so we can test it
    // But use display: none or similar to hide it when show is false
    return (
      <div 
        className={`mock-cap-slidebox ${className || ''}`} 
        data-size={size}
        data-testid={className === 'webpush-preview-slidebox' ? 'webpush-slidebox' : undefined}
        style={{ display: show ? 'block' : 'none' }}
      >
        <div className="mock-slidebox-header">{header}</div>
        <button className="mock-slidebox-close" onClick={handleClose} data-testid="close-slidebox">
          Close
        </button>
        {show && <div className="mock-slidebox-content">{content}</div>}
      </div>
    );
  };
});

describe('WebPushPreview', () => {
  const defaultProps = {
    notificationTitle: 'Test Notification Title',
    notificationBody: 'Test notification body text',
    url: 'https://www.example.com',
    imageSrc: 'https://example.com/image.jpg',
    brandIconSrc: 'https://example.com/icon.png',
  };

  beforeEach(() => {
    jest.clearAllMocks();
  });

  describe('Basic Rendering', () => {
    it('should render correctly with default props', () => {
      const wrapper = shallowWithIntl(<WebPushPreview {...defaultProps} />);
      expect(wrapper).toMatchSnapshot();
    });

    it('should render with minimal props', () => {
      const wrapper = mountWithIntl(<WebPushPreview />);
      expect(wrapper.exists()).toBe(true);
    });

    it('should render main container with correct class', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const container = wrapper.find('.webpush-preview-container').first();
      expect(container.exists()).toBe(true);
      expect(container.is(CapRow)).toBe(true);
    });

    it('should render PreviewControls component', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      expect(previewControls.exists()).toBe(true);
    });

    it('should render PreviewContent component', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewContent = wrapper.find(PreviewContent);
      expect(previewContent.exists()).toBe(true);
    });

    it('should render PreviewDisclaimer component', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewDisclaimer = wrapper.find(PreviewDisclaimer);
      expect(previewDisclaimer.exists()).toBe(true);
    });

    it('should render "Preview in all devices" button', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const buttonRow = wrapper.find('.preview-all-devices-button');
      expect(buttonRow.exists()).toBe(true);
      const button = buttonRow.find(CapButton);
      expect(button.exists()).toBe(true);
      expect(button.hasClass('preview-all-devices-trigger')).toBe(true);
    });

    it('should render CapSlideBox component', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const allSlideBoxes = wrapper.find(CapSlideBox);
      let found = false;
      for (let i = 0; i < allSlideBoxes.length; i++) {
        if (allSlideBoxes.at(i).prop('className') === 'webpush-preview-slidebox') {
          found = true;
          break;
        }
      }
      expect(found).toBe(true);
    });
  });

  describe('Initial State', () => {
    it('should initialize with default OS', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      expect(previewControls.prop('selectedOS')).toBe(DEFAULT_OS);
    });

    it('should initialize with default browser', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      expect(previewControls.prop('selectedBrowser')).toBe(DEFAULT_BROWSER);
    });

    it('should initialize with slidebox closed', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const allSlideBoxes = wrapper.find(CapSlideBox);
      let showState = null;
      for (let i = 0; i < allSlideBoxes.length; i++) {
        if (allSlideBoxes.at(i).prop('className') === 'webpush-preview-slidebox') {
          showState = allSlideBoxes.at(i).prop('show');
          break;
        }
      }
      expect(showState).toBe(false);
    });

    it('should pass correct browser options for default OS', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      const expectedBrowserOptions = getBrowserOptionsForOS(DEFAULT_OS);
      expect(previewControls.prop('browserOptions')).toEqual(expectedBrowserOptions);
    });
  });

  describe('PreviewControls Props', () => {
    it('should pass correct props to PreviewControls', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      expect(previewControls.prop('selectedOS')).toBe(DEFAULT_OS);
      expect(previewControls.prop('selectedBrowser')).toBe(DEFAULT_BROWSER);
      expect(previewControls.prop('osOptions')).toBe(OS_OPTIONS);
      expect(previewControls.prop('layoutMode')).toBe('newRow');
      expect(previewControls.prop('showStateDropdown')).toBe(false);
      
      const expectedBrowserOptions = getBrowserOptionsForOS(DEFAULT_OS);
      expect(previewControls.prop('browserOptions')).toEqual(expectedBrowserOptions);
    });

    it('should pass onOSChange handler to PreviewControls', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      expect(typeof previewControls.prop('onOSChange')).toBe('function');
    });

    it('should pass onBrowserChange handler to PreviewControls', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      expect(typeof previewControls.prop('onBrowserChange')).toBe('function');
    });
  });

  describe('PreviewContent Props', () => {
    it('should pass correct props to PreviewContent', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewContent = wrapper.find(PreviewContent);
      
      expect(previewContent.prop('notificationTitle')).toBe(defaultProps.notificationTitle);
      expect(previewContent.prop('notificationBody')).toBe(defaultProps.notificationBody);
      expect(previewContent.prop('url')).toBe(defaultProps.url);
      expect(previewContent.prop('selectedOS')).toBe(DEFAULT_OS);
      expect(previewContent.prop('selectedBrowser')).toBe(DEFAULT_BROWSER);
      expect(previewContent.prop('notificationState')).toBe('Collapsed');
      expect(previewContent.prop('imageSrc')).toBe(defaultProps.imageSrc);
      expect(previewContent.prop('brandIconSrc')).toBe(defaultProps.brandIconSrc);
    });

    it('should pass updated OS to PreviewContent when OS changes', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onOSChange')(OS_WINDOWS);
      });
      wrapper.update();
      
      const previewContent = wrapper.find(PreviewContent);
      expect(previewContent.prop('selectedOS')).toBe(OS_WINDOWS);
    });

    it('should pass updated browser to PreviewContent when browser changes', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onBrowserChange')(BROWSER_FIREFOX);
      });
      wrapper.update();
      
      const previewContent = wrapper.find(PreviewContent);
      expect(previewContent.prop('selectedBrowser')).toBe(BROWSER_FIREFOX);
    });
  });

  describe('OS Change and Browser Reset', () => {
    it('should update OS when handleOSChange is called', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onOSChange')(OS_WINDOWS);
      });
      wrapper.update();
      
      const updatedControls = wrapper.find(PreviewControls);
      expect(updatedControls.prop('selectedOS')).toBe(OS_WINDOWS);
    });

    it('should reset browser to first available option when OS changes', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      // Start with macOS and Safari
      act(() => {
        previewControls.prop('onOSChange')(OS_MACOS);
        previewControls.prop('onBrowserChange')(BROWSER_SAFARI);
      });
      wrapper.update();
      
      expect(wrapper.find(PreviewControls).prop('selectedBrowser')).toBe(BROWSER_SAFARI);
      
      // Change to Windows (Safari not supported)
      act(() => {
        previewControls.prop('onOSChange')(OS_WINDOWS);
      });
      wrapper.update();
      
      // Browser should be reset to first available option for Windows
      const windowsBrowserOptions = getBrowserOptionsForOS(OS_WINDOWS);
      expect(wrapper.find(PreviewControls).prop('selectedBrowser')).toBe(windowsBrowserOptions[0].value);
    });

    it('should update browser options when OS changes', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      // macOS should have all browsers including Safari
      act(() => {
        previewControls.prop('onOSChange')(OS_MACOS);
      });
      wrapper.update();
      
      let browserOptions = wrapper.find(PreviewControls).prop('browserOptions');
      expect(browserOptions.some(opt => opt.value === BROWSER_SAFARI)).toBe(true);
      
      // Windows should not have Safari
      act(() => {
        previewControls.prop('onOSChange')(OS_WINDOWS);
      });
      wrapper.update();
      
      browserOptions = wrapper.find(PreviewControls).prop('browserOptions');
      expect(browserOptions.some(opt => opt.value === BROWSER_SAFARI)).toBe(false);
    });

    it('should handle OS change for iOS', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onOSChange')(OS_IOS);
      });
      wrapper.update();
      
      expect(wrapper.find(PreviewControls).prop('selectedOS')).toBe(OS_IOS);
      const browserOptions = wrapper.find(PreviewControls).prop('browserOptions');
      expect(browserOptions.some(opt => opt.value === BROWSER_SAFARI)).toBe(true);
    });

    it('should handle OS change for iPadOS', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onOSChange')(OS_IPADOS);
      });
      wrapper.update();
      
      expect(wrapper.find(PreviewControls).prop('selectedOS')).toBe(OS_IPADOS);
      const browserOptions = wrapper.find(PreviewControls).prop('browserOptions');
      expect(browserOptions.some(opt => opt.value === BROWSER_SAFARI)).toBe(true);
    });

    it('should handle OS change for Android Mobile', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onOSChange')(OS_ANDROID_MOBILE);
      });
      wrapper.update();
      
      expect(wrapper.find(PreviewControls).prop('selectedOS')).toBe(OS_ANDROID_MOBILE);
      const browserOptions = wrapper.find(PreviewControls).prop('browserOptions');
      expect(browserOptions.some(opt => opt.value === BROWSER_SAFARI)).toBe(false);
    });

    it('should handle OS change for Android Tablet', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onOSChange')(OS_ANDROID_TABLET);
      });
      wrapper.update();
      
      expect(wrapper.find(PreviewControls).prop('selectedOS')).toBe(OS_ANDROID_TABLET);
      const browserOptions = wrapper.find(PreviewControls).prop('browserOptions');
      expect(browserOptions.some(opt => opt.value === BROWSER_SAFARI)).toBe(false);
    });

    it('should reset browser when OS changes and current browser is not available', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      // Set to macOS with Safari
      act(() => {
        previewControls.prop('onOSChange')(OS_MACOS);
        previewControls.prop('onBrowserChange')(BROWSER_SAFARI);
      });
      wrapper.update();
      
      expect(wrapper.find(PreviewControls).prop('selectedBrowser')).toBe(BROWSER_SAFARI);
      
      // Change to Windows (Safari not available)
      act(() => {
        previewControls.prop('onOSChange')(OS_WINDOWS);
      });
      wrapper.update();
      
      // Should reset to first available browser (Chrome)
      const windowsBrowserOptions = getBrowserOptionsForOS(OS_WINDOWS);
      expect(wrapper.find(PreviewControls).prop('selectedBrowser')).toBe(windowsBrowserOptions[0].value);
    });

    it('should not reset browser when OS changes and current browser is still available', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      // Set to macOS with Chrome
      act(() => {
        previewControls.prop('onOSChange')(OS_MACOS);
        previewControls.prop('onBrowserChange')(BROWSER_CHROME);
      });
      wrapper.update();
      
      expect(wrapper.find(PreviewControls).prop('selectedBrowser')).toBe(BROWSER_CHROME);
      
      // Change to Windows (Chrome is still available)
      act(() => {
        previewControls.prop('onOSChange')(OS_WINDOWS);
      });
      wrapper.update();
      
      // Browser should remain Chrome
      expect(wrapper.find(PreviewControls).prop('selectedBrowser')).toBe(BROWSER_CHROME);
    });
  });

  describe('Browser Change', () => {
    it('should update browser when handleBrowserChange is called', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onBrowserChange')(BROWSER_FIREFOX);
      });
      wrapper.update();
      
      const updatedControls = wrapper.find(PreviewControls);
      expect(updatedControls.prop('selectedBrowser')).toBe(BROWSER_FIREFOX);
    });

    it('should handle browser change for Chrome', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onBrowserChange')(BROWSER_CHROME);
      });
      wrapper.update();
      
      expect(wrapper.find(PreviewControls).prop('selectedBrowser')).toBe(BROWSER_CHROME);
    });

    it('should handle browser change for Firefox', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onBrowserChange')(BROWSER_FIREFOX);
      });
      wrapper.update();
      
      expect(wrapper.find(PreviewControls).prop('selectedBrowser')).toBe(BROWSER_FIREFOX);
    });

    it('should handle browser change for Edge', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onBrowserChange')(BROWSER_EDGE);
      });
      wrapper.update();
      
      expect(wrapper.find(PreviewControls).prop('selectedBrowser')).toBe(BROWSER_EDGE);
    });

    it('should handle browser change for Safari on macOS', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onOSChange')(OS_MACOS);
        previewControls.prop('onBrowserChange')(BROWSER_SAFARI);
      });
      wrapper.update();
      
      expect(wrapper.find(PreviewControls).prop('selectedBrowser')).toBe(BROWSER_SAFARI);
    });

    it('should handle browser change for Opera', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onBrowserChange')(BROWSER_OPERA);
      });
      wrapper.update();
      
      expect(wrapper.find(PreviewControls).prop('selectedBrowser')).toBe(BROWSER_OPERA);
    });
  });

  describe('Slidebox Toggle', () => {
    // Helper to get the actual CapSlideBox component props
    // Use .get(i) to get the actual React node instead of an Enzyme wrapper
    const getSlideBoxShowState = (wrapper) => {
      const allSlideBoxes = wrapper.find(CapSlideBox);
      for (let i = 0; i < allSlideBoxes.length; i++) {
        try {
          const reactNode = allSlideBoxes.get(i);
          if (reactNode && reactNode.props && reactNode.props.className === 'webpush-preview-slidebox') {
            return reactNode.props.show;
          }
        } catch (e) {
          continue;
        }
      }
      return null;
    };

    const getSlideBoxHandleClose = (wrapper) => {
      const allSlideBoxes = wrapper.find(CapSlideBox);
      for (let i = 0; i < allSlideBoxes.length; i++) {
        try {
          const reactNode = allSlideBoxes.get(i);
          if (reactNode && reactNode.props && reactNode.props.className === 'webpush-preview-slidebox') {
            return reactNode.props.handleClose;
          }
        } catch (e) {
          continue;
        }
      }
      return null;
    };

    const getSlideBoxProp = (wrapper, propName) => {
      const allSlideBoxes = wrapper.find(CapSlideBox);
      for (let i = 0; i < allSlideBoxes.length; i++) {
        try {
          const reactNode = allSlideBoxes.get(i);
          if (reactNode && reactNode.props && reactNode.props.className === 'webpush-preview-slidebox') {
            return reactNode.props[propName];
          }
        } catch (e) {
          continue;
        }
      }
      return null;
    };

    it('should open slidebox when button is clicked', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const button = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      expect(getSlideBoxShowState(wrapper)).toBe(false);
      
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      
      expect(getSlideBoxShowState(wrapper)).toBe(true);
    });

    it('should close slidebox when handleClose is called', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const button = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      // Open slidebox
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      
      expect(getSlideBoxShowState(wrapper)).toBe(true);
      
      // Close slidebox
      const handleClose = getSlideBoxHandleClose(wrapper);
      act(() => {
        handleClose();
      });
      wrapper.update();
      
      expect(getSlideBoxShowState(wrapper)).toBe(false);
    });

    it('should toggle slidebox multiple times', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const button = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      // Open
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      expect(getSlideBoxShowState(wrapper)).toBe(true);
      
      // Close
      const handleClose = getSlideBoxHandleClose(wrapper);
      act(() => {
        handleClose();
      });
      wrapper.update();
      expect(getSlideBoxShowState(wrapper)).toBe(false);
      
      // Open again
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      expect(getSlideBoxShowState(wrapper)).toBe(true);
    });

    it('should pass correct props to CapSlideBox', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      
      expect(getSlideBoxProp(wrapper, 'size')).toBe('size-xl');
      expect(getSlideBoxProp(wrapper, 'className')).toBe('webpush-preview-slidebox');
      expect(typeof getSlideBoxProp(wrapper, 'handleClose')).toBe('function');
    });

    it('should render DevicePreviewContent inside slidebox when open', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const button = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      
      const slideBoxContent = getSlideBoxProp(wrapper, 'content');
      
      // Check if the content is a DevicePreviewContent React element
      expect(slideBoxContent).toBeDefined();
      expect(slideBoxContent.type).toBe(DevicePreviewContent);
    });

    it('should pass correct props to DevicePreviewContent in slidebox', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const button = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      
      const slideBoxContent = getSlideBoxProp(wrapper, 'content');
      
      // Check the props directly on the React element
      expect(slideBoxContent.props.notificationTitle).toBe(defaultProps.notificationTitle);
      expect(slideBoxContent.props.notificationBody).toBe(defaultProps.notificationBody);
      expect(slideBoxContent.props.url).toBe(defaultProps.url);
      expect(slideBoxContent.props.imageSrc).toBe(defaultProps.imageSrc);
      expect(slideBoxContent.props.brandIconSrc).toBe(defaultProps.brandIconSrc);
    });
  });

  describe('Different OS/Browser Combinations', () => {
    const testCombinations = [
      { os: OS_MACOS, browser: BROWSER_CHROME },
      { os: OS_MACOS, browser: BROWSER_SAFARI },
      { os: OS_MACOS, browser: BROWSER_FIREFOX },
      { os: OS_WINDOWS, browser: BROWSER_CHROME },
      { os: OS_WINDOWS, browser: BROWSER_EDGE },
      { os: OS_IOS, browser: BROWSER_CHROME },
      { os: OS_IOS, browser: BROWSER_SAFARI },
      { os: OS_IPADOS, browser: BROWSER_CHROME },
      { os: OS_ANDROID_MOBILE, browser: BROWSER_CHROME },
      { os: OS_ANDROID_TABLET, browser: BROWSER_CHROME },
    ];

    testCombinations.forEach(({ os, browser }) => {
      it(`should handle ${os} + ${browser} combination`, () => {
        const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
        const previewControls = wrapper.find(PreviewControls);
        
        act(() => {
          previewControls.prop('onOSChange')(os);
        });
        wrapper.update();
        
        act(() => {
          previewControls.prop('onBrowserChange')(browser);
        });
        wrapper.update();
        
        const updatedControls = wrapper.find(PreviewControls);
        expect(updatedControls.prop('selectedOS')).toBe(os);
        expect(updatedControls.prop('selectedBrowser')).toBe(browser);
        
        const previewContent = wrapper.find(PreviewContent);
        expect(previewContent.prop('selectedOS')).toBe(os);
        expect(previewContent.prop('selectedBrowser')).toBe(browser);
      });
    });
  });

  describe('Props Updates', () => {
    it('should update PreviewContent when notificationTitle changes', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      
      wrapper.setProps({ notificationTitle: 'New Title' });
      wrapper.update();
      
      const previewContent = wrapper.find(PreviewContent);
      expect(previewContent.prop('notificationTitle')).toBe('New Title');
    });

    it('should update PreviewContent when notificationBody changes', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      
      wrapper.setProps({ notificationBody: 'New Body' });
      wrapper.update();
      
      const previewContent = wrapper.find(PreviewContent);
      expect(previewContent.prop('notificationBody')).toBe('New Body');
    });

    it('should update PreviewContent when url changes', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      
      wrapper.setProps({ url: 'https://new-url.com' });
      wrapper.update();
      
      const previewContent = wrapper.find(PreviewContent);
      expect(previewContent.prop('url')).toBe('https://new-url.com');
    });

    it('should update PreviewContent when imageSrc changes', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      
      wrapper.setProps({ imageSrc: 'https://new-image.jpg' });
      wrapper.update();
      
      const previewContent = wrapper.find(PreviewContent);
      expect(previewContent.prop('imageSrc')).toBe('https://new-image.jpg');
    });

    it('should update PreviewContent when brandIconSrc changes', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      
      wrapper.setProps({ brandIconSrc: 'https://new-icon.png' });
      wrapper.update();
      
      const previewContent = wrapper.find(PreviewContent);
      expect(previewContent.prop('brandIconSrc')).toBe('https://new-icon.png');
    });
  });

  describe('Edge Cases', () => {
    it('should handle empty notificationTitle', () => {
      const wrapper = mountWithIntl(
        <WebPushPreview
          notificationTitle=""
          notificationBody={defaultProps.notificationBody}
          url={defaultProps.url}
        />
      );
      const previewContent = wrapper.find(PreviewContent);
      expect(previewContent.prop('notificationTitle')).toBe('');
    });

    it('should handle empty notificationBody', () => {
      const wrapper = mountWithIntl(
        <WebPushPreview
          notificationTitle={defaultProps.notificationTitle}
          notificationBody=""
          url={defaultProps.url}
        />
      );
      const previewContent = wrapper.find(PreviewContent);
      expect(previewContent.prop('notificationBody')).toBe('');
    });

    it('should handle empty url', () => {
      const wrapper = mountWithIntl(
        <WebPushPreview
          notificationTitle={defaultProps.notificationTitle}
          notificationBody={defaultProps.notificationBody}
          url=""
        />
      );
      const previewContent = wrapper.find(PreviewContent);
      expect(previewContent.prop('url')).toBe('');
    });

    it('should handle missing imageSrc and brandIconSrc', () => {
      const wrapper = mountWithIntl(
        <WebPushPreview
          notificationTitle={defaultProps.notificationTitle}
          notificationBody={defaultProps.notificationBody}
          url={defaultProps.url}
        />
      );
      const previewContent = wrapper.find(PreviewContent);
      expect(previewContent.prop('imageSrc')).toBe('');
      expect(previewContent.prop('brandIconSrc')).toBe('');
    });

    it('should handle rapid OS and browser changes', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onOSChange')(OS_MACOS);
        previewControls.prop('onBrowserChange')(BROWSER_CHROME);
      });
      wrapper.update();
      
      act(() => {
        previewControls.prop('onOSChange')(OS_WINDOWS);
        previewControls.prop('onBrowserChange')(BROWSER_FIREFOX);
      });
      wrapper.update();
      
      act(() => {
        previewControls.prop('onOSChange')(OS_IOS);
        previewControls.prop('onBrowserChange')(BROWSER_SAFARI);
      });
      wrapper.update();
      
      const updatedControls = wrapper.find(PreviewControls);
      expect(updatedControls.prop('selectedOS')).toBe(OS_IOS);
      expect(updatedControls.prop('selectedBrowser')).toBe(BROWSER_SAFARI);
    });

    it('should handle browser options being empty array', () => {
      // This shouldn't happen in practice, but test the edge case
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      // Change to an OS that might have empty options (shouldn't happen)
      act(() => {
        previewControls.prop('onOSChange')(OS_WINDOWS);
      });
      wrapper.update();
      
      const browserOptions = wrapper.find(PreviewControls).prop('browserOptions');
      expect(Array.isArray(browserOptions)).toBe(true);
      expect(browserOptions.length).toBeGreaterThan(0);
    });
  });

  describe('handleOpenPreviewSlideBox', () => {
    // Helper to get the slidebox show state
    const getSlideBoxShowState = (wrapper) => {
      const allSlideBoxes = wrapper.find(CapSlideBox);
      for (let i = 0; i < allSlideBoxes.length; i++) {
        try {
          const reactNode = allSlideBoxes.get(i);
          if (reactNode && reactNode.props && reactNode.props.className === 'webpush-preview-slidebox') {
            return reactNode.props.show;
          }
        } catch (e) {
          continue;
        }
      }
      return null;
    };

    it('should call onClickShowInAllDevices when provided', () => {
      const mockOnClickShowInAllDevices = jest.fn();
      const wrapper = mountWithIntl(
        <WebPushPreview
          {...defaultProps}
          onClickShowInAllDevices={mockOnClickShowInAllDevices}
        />
      );
      const button = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      expect(mockOnClickShowInAllDevices).not.toHaveBeenCalled();
      
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      
      expect(mockOnClickShowInAllDevices).toHaveBeenCalledTimes(1);
      expect(mockOnClickShowInAllDevices).toHaveBeenCalledWith();
    });

    it('should not open slidebox when onClickShowInAllDevices is provided', () => {
      const mockOnClickShowInAllDevices = jest.fn();
      const wrapper = mountWithIntl(
        <WebPushPreview
          {...defaultProps}
          onClickShowInAllDevices={mockOnClickShowInAllDevices}
        />
      );
      const button = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      expect(getSlideBoxShowState(wrapper)).toBe(false);
      
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      
      // Slidebox should remain closed when onClickShowInAllDevices is provided
      expect(getSlideBoxShowState(wrapper)).toBe(false);
      expect(mockOnClickShowInAllDevices).toHaveBeenCalledTimes(1);
    });

    it('should open slidebox when onClickShowInAllDevices is not provided', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const button = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      expect(getSlideBoxShowState(wrapper)).toBe(false);
      
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      
      expect(getSlideBoxShowState(wrapper)).toBe(true);
    });

    it('should handle multiple calls when onClickShowInAllDevices is provided', () => {
      const mockOnClickShowInAllDevices = jest.fn();
      const wrapper = mountWithIntl(
        <WebPushPreview
          {...defaultProps}
          onClickShowInAllDevices={mockOnClickShowInAllDevices}
        />
      );
      const button = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      
      expect(mockOnClickShowInAllDevices).toHaveBeenCalledTimes(3);
      expect(getSlideBoxShowState(wrapper)).toBe(false);
    });

    it('should handle multiple calls when onClickShowInAllDevices is not provided', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const button = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      // First call - should open
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      expect(getSlideBoxShowState(wrapper)).toBe(true);
      
      // Second call - should remain open (state doesn't change)
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      expect(getSlideBoxShowState(wrapper)).toBe(true);
      
      // Third call - should remain open
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      expect(getSlideBoxShowState(wrapper)).toBe(true);
    });

    it('should handle onClickShowInAllDevices being undefined', () => {
      const wrapper = mountWithIntl(
        <WebPushPreview
          {...defaultProps}
          onClickShowInAllDevices={undefined}
        />
      );
      const button = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      expect(getSlideBoxShowState(wrapper)).toBe(false);
      
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      
      // Should open slidebox when prop is undefined
      expect(getSlideBoxShowState(wrapper)).toBe(true);
    });

    it('should handle onClickShowInAllDevices being null', () => {
      const wrapper = mountWithIntl(
        <WebPushPreview
          {...defaultProps}
          onClickShowInAllDevices={null}
        />
      );
      const button = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      expect(getSlideBoxShowState(wrapper)).toBe(false);
      
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      
      // Should open slidebox when prop is null (falsy)
      expect(getSlideBoxShowState(wrapper)).toBe(true);
    });

    it('should handle onClickShowInAllDevices being an empty function', () => {
      const mockOnClickShowInAllDevices = jest.fn(() => {});
      const wrapper = mountWithIntl(
        <WebPushPreview
          {...defaultProps}
          onClickShowInAllDevices={mockOnClickShowInAllDevices}
        />
      );
      const button = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      expect(getSlideBoxShowState(wrapper)).toBe(false);
      
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      
      expect(mockOnClickShowInAllDevices).toHaveBeenCalledTimes(1);
      expect(getSlideBoxShowState(wrapper)).toBe(false);
    });

    it('should work correctly with slidebox close after opening without onClickShowInAllDevices', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const button = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      // Open slidebox
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      expect(getSlideBoxShowState(wrapper)).toBe(true);
      
      // Close slidebox
      const allSlideBoxes = wrapper.find(CapSlideBox);
      let handleClose = null;
      for (let i = 0; i < allSlideBoxes.length; i++) {
        try {
          const reactNode = allSlideBoxes.get(i);
          if (reactNode && reactNode.props && reactNode.props.className === 'webpush-preview-slidebox') {
            handleClose = reactNode.props.handleClose;
            break;
          }
        } catch (e) {
          continue;
        }
      }
      
      act(() => {
        handleClose();
      });
      wrapper.update();
      expect(getSlideBoxShowState(wrapper)).toBe(false);
      
      // Open again
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      expect(getSlideBoxShowState(wrapper)).toBe(true);
    });

    it('should handle onClickShowInAllDevices that throws an error gracefully', () => {
      const mockOnClickShowInAllDevices = jest.fn(() => {
        throw new Error('Test error');
      });
      const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
      
      const wrapper = mountWithIntl(
        <WebPushPreview
          {...defaultProps}
          onClickShowInAllDevices={mockOnClickShowInAllDevices}
        />
      );
      const button = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      expect(() => {
        act(() => {
          button.prop('onClick')();
        });
      }).toThrow('Test error');
      wrapper.update();
      
      expect(mockOnClickShowInAllDevices).toHaveBeenCalledTimes(1);
      expect(getSlideBoxShowState(wrapper)).toBe(false);
      
      consoleErrorSpy.mockRestore();
    });

    it('should handle rapid clicks when onClickShowInAllDevices is provided', () => {
      const mockOnClickShowInAllDevices = jest.fn();
      const wrapper = mountWithIntl(
        <WebPushPreview
          {...defaultProps}
          onClickShowInAllDevices={mockOnClickShowInAllDevices}
        />
      );
      const button = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      // Rapid clicks
      act(() => {
        button.prop('onClick')();
        button.prop('onClick')();
        button.prop('onClick')();
      });
      wrapper.update();
      
      expect(mockOnClickShowInAllDevices).toHaveBeenCalledTimes(3);
      expect(getSlideBoxShowState(wrapper)).toBe(false);
    });

    it('should handle rapid clicks when onClickShowInAllDevices is not provided', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const button = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      // Rapid clicks
      act(() => {
        button.prop('onClick')();
        button.prop('onClick')();
        button.prop('onClick')();
      });
      wrapper.update();
      
      // Should be open after rapid clicks
      expect(getSlideBoxShowState(wrapper)).toBe(true);
    });

    it('should maintain correct behavior when props change from provided to not provided', () => {
      const mockOnClickShowInAllDevices = jest.fn();
      const wrapper = mountWithIntl(
        <WebPushPreview
          {...defaultProps}
          onClickShowInAllDevices={mockOnClickShowInAllDevices}
        />
      );
      const button = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      // First call with onClickShowInAllDevices provided
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      expect(mockOnClickShowInAllDevices).toHaveBeenCalledTimes(1);
      expect(getSlideBoxShowState(wrapper)).toBe(false);
      
      // Remove onClickShowInAllDevices prop
      act(() => {
        wrapper.setProps({ onClickShowInAllDevices: undefined });
      });
      wrapper.update();
      
      // Get the button again after props change
      const updatedButton = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      // Second call without onClickShowInAllDevices
      act(() => {
        updatedButton.prop('onClick')();
      });
      wrapper.update();
      // The mock should still have been called only once (from the first call)
      expect(mockOnClickShowInAllDevices).toHaveBeenCalledTimes(1);
      expect(getSlideBoxShowState(wrapper)).toBe(true); // Should open slidebox
    });

    it('should maintain correct behavior when props change from not provided to provided', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const button = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      // First call without onClickShowInAllDevices
      act(() => {
        button.prop('onClick')();
      });
      wrapper.update();
      expect(getSlideBoxShowState(wrapper)).toBe(true);
      
      // Close slidebox
      const allSlideBoxes = wrapper.find(CapSlideBox);
      let handleClose = null;
      for (let i = 0; i < allSlideBoxes.length; i++) {
        try {
          const reactNode = allSlideBoxes.get(i);
          if (reactNode && reactNode.props && reactNode.props.className === 'webpush-preview-slidebox') {
            handleClose = reactNode.props.handleClose;
            break;
          }
        } catch (e) {
          continue;
        }
      }
      
      act(() => {
        handleClose();
      });
      wrapper.update();
      expect(getSlideBoxShowState(wrapper)).toBe(false);
      
      // Add onClickShowInAllDevices prop
      const mockOnClickShowInAllDevices = jest.fn();
      act(() => {
        wrapper.setProps({ onClickShowInAllDevices: mockOnClickShowInAllDevices });
      });
      wrapper.update();
      
      // Get the button again after props change
      const updatedButton = wrapper.find('[data-test-id="webpush-preview-toggle"]').first();
      
      // Second call with onClickShowInAllDevices
      act(() => {
        updatedButton.prop('onClick')();
      });
      wrapper.update();
      expect(mockOnClickShowInAllDevices).toHaveBeenCalledTimes(1);
      expect(getSlideBoxShowState(wrapper)).toBe(false); // Should not open slidebox
    });
  });

  describe('Component Integration', () => {
    it('should update all child components when OS changes', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onOSChange')(OS_WINDOWS);
      });
      wrapper.update();
      
      const updatedControls = wrapper.find(PreviewControls);
      const previewContent = wrapper.find(PreviewContent);
      
      expect(updatedControls.prop('selectedOS')).toBe(OS_WINDOWS);
      expect(previewContent.prop('selectedOS')).toBe(OS_WINDOWS);
    });

    it('should update all child components when browser changes', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onBrowserChange')(BROWSER_FIREFOX);
      });
      wrapper.update();
      
      const updatedControls = wrapper.find(PreviewControls);
      const previewContent = wrapper.find(PreviewContent);
      
      expect(updatedControls.prop('selectedBrowser')).toBe(BROWSER_FIREFOX);
      expect(previewContent.prop('selectedBrowser')).toBe(BROWSER_FIREFOX);
    });

    it('should maintain state consistency across components', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onOSChange')(OS_MACOS);
        previewControls.prop('onBrowserChange')(BROWSER_SAFARI);
      });
      wrapper.update();
      
      const controls = wrapper.find(PreviewControls);
      const content = wrapper.find(PreviewContent);
      
      expect(controls.prop('selectedOS')).toBe(content.prop('selectedOS'));
      expect(controls.prop('selectedBrowser')).toBe(content.prop('selectedBrowser'));
    });
  });

  describe('Browser Options Filtering', () => {
    it('should filter Safari from Windows browser options', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onOSChange')(OS_WINDOWS);
      });
      wrapper.update();
      
      const browserOptions = wrapper.find(PreviewControls).prop('browserOptions');
      expect(browserOptions.some(opt => opt.value === BROWSER_SAFARI)).toBe(false);
    });

    it('should include Safari in macOS browser options', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onOSChange')(OS_MACOS);
      });
      wrapper.update();
      
      const browserOptions = wrapper.find(PreviewControls).prop('browserOptions');
      expect(browserOptions.some(opt => opt.value === BROWSER_SAFARI)).toBe(true);
    });

    it('should include Safari in iOS browser options', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onOSChange')(OS_IOS);
      });
      wrapper.update();
      
      const browserOptions = wrapper.find(PreviewControls).prop('browserOptions');
      expect(browserOptions.some(opt => opt.value === BROWSER_SAFARI)).toBe(true);
    });

    it('should include Safari in iPadOS browser options', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onOSChange')(OS_IPADOS);
      });
      wrapper.update();
      
      const browserOptions = wrapper.find(PreviewControls).prop('browserOptions');
      expect(browserOptions.some(opt => opt.value === BROWSER_SAFARI)).toBe(true);
    });

    it('should exclude Safari from Android Mobile browser options', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onOSChange')(OS_ANDROID_MOBILE);
      });
      wrapper.update();
      
      const browserOptions = wrapper.find(PreviewControls).prop('browserOptions');
      expect(browserOptions.some(opt => opt.value === BROWSER_SAFARI)).toBe(false);
    });

    it('should exclude Safari from Android Tablet browser options', () => {
      const wrapper = mountWithIntl(<WebPushPreview {...defaultProps} />);
      const previewControls = wrapper.find(PreviewControls);
      
      act(() => {
        previewControls.prop('onOSChange')(OS_ANDROID_TABLET);
      });
      wrapper.update();
      
      const browserOptions = wrapper.find(PreviewControls).prop('browserOptions');
      expect(browserOptions.some(opt => opt.value === BROWSER_SAFARI)).toBe(false);
    });
  });
});

