import React from 'react';
import { shallowWithIntl, mountWithIntl } from '../../../../../../helpers/intl-enzym-test-helpers';
import WindowsChromeExpanded from '../WindowsChromeExpanded';

describe('WindowsChromeExpanded', () => {
  const defaultProps = {
    icon: 'https://example.com/chrome-icon.png',
    brandIcon: 'https://example.com/brand-icon.png',
    enableBrandIconPreview: false,
    notificationTitle: 'Test Notification Title',
    notificationBody: 'Test notification body text',
    displayUrl: 'example.com',
    browserName: 'Google Chrome',
    mediaImageUrl: '',
    enableCtas: false,
    ctaButtons: [],
  };

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

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

    it('should render all required elements', () => {
      const wrapper = mountWithIntl(<WindowsChromeExpanded {...defaultProps} />);
      
      // Wrapper container
      expect(wrapper.find('.windows-chrome-expanded-wrapper').exists()).toBe(true);
      
      // Body container
      expect(wrapper.find('.windows-chrome-body').exists()).toBe(true);
      
      // Header row
      expect(wrapper.find('.windows-chrome-header-row').exists()).toBe(true);
      expect(wrapper.find('.windows-chrome-browser-icon').exists()).toBe(true);
      expect(wrapper.find('.windows-chrome-browser-title').exists()).toBe(true);
      expect(wrapper.find('.windows-chrome-header-actions').exists()).toBe(true);
      
      // Content row
      expect(wrapper.find('.windows-chrome-content-row').exists()).toBe(true);
      expect(wrapper.find('.windows-chrome-text-block').exists()).toBe(true);
      expect(wrapper.find('.windows-chrome-title').exists()).toBe(true);
      expect(wrapper.find('.windows-chrome-body-text').exists()).toBe(true);
      expect(wrapper.find('.windows-chrome-url').exists()).toBe(true);
    });

    it('should render browser icon with correct src and alt', () => {
      const wrapper = mountWithIntl(<WindowsChromeExpanded {...defaultProps} />);
      const icon = wrapper.find('.notification-icon');
      
      expect(icon.exists()).toBe(true);
      expect(icon.prop('src')).toBe(defaultProps.icon);
      expect(icon.prop('alt')).toBe('Chrome browser');
      expect(icon.prop('style')).toEqual({ width: '100%', height: '100%' });
    });

    it('should render browser name', () => {
      const wrapper = mountWithIntl(<WindowsChromeExpanded {...defaultProps} />);
      const browserTitle = wrapper.find('.windows-chrome-browser-title');
      
      expect(browserTitle.exists()).toBe(true);
      expect(browserTitle.text()).toBe(defaultProps.browserName);
    });

    it('should render notification title', () => {
      const wrapper = mountWithIntl(<WindowsChromeExpanded {...defaultProps} />);
      const title = wrapper.find('.windows-chrome-title');
      
      expect(title.exists()).toBe(true);
      expect(title.text()).toBe(defaultProps.notificationTitle);
    });

    it('should render notification body', () => {
      const wrapper = mountWithIntl(<WindowsChromeExpanded {...defaultProps} />);
      const body = wrapper.find('.windows-chrome-body-text');
      
      expect(body.exists()).toBe(true);
      expect(body.text()).toBe(defaultProps.notificationBody);
    });

    it('should render display URL', () => {
      const wrapper = mountWithIntl(<WindowsChromeExpanded {...defaultProps} />);
      const url = wrapper.find('.windows-chrome-url');
      
      expect(url.exists()).toBe(true);
      expect(url.text()).toBe(defaultProps.displayUrl);
    });

    it('should render menu and close icons', () => {
      const wrapper = mountWithIntl(<WindowsChromeExpanded {...defaultProps} />);
      const menuIcon = wrapper.find('.windows-chrome-menu-icon');
      const closeIcon = wrapper.find('.windows-chrome-close-icon');
      
      expect(menuIcon.exists()).toBe(true);
      expect(closeIcon.exists()).toBe(true);
      expect(menuIcon.prop('alt')).toBe('Menu');
      expect(closeIcon.prop('alt')).toBe('Close');
    });
  });

  describe('Browser Name', () => {
    it('should use default browser name when not provided', () => {
      const propsWithoutBrowserName = { ...defaultProps };
      delete propsWithoutBrowserName.browserName;
      
      const wrapper = mountWithIntl(<WindowsChromeExpanded {...propsWithoutBrowserName} />);
      const browserTitle = wrapper.find('.windows-chrome-browser-title');
      
      expect(browserTitle.text()).toBe('Google Chrome');
    });

    it('should render custom browser name', () => {
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded {...defaultProps} browserName="Microsoft Edge" />
      );
      const browserTitle = wrapper.find('.windows-chrome-browser-title');
      
      expect(browserTitle.text()).toBe('Microsoft Edge');
    });
  });

  describe('Brand Icon Display Logic', () => {
    it('should show brand icon when enableBrandIconPreview is true and brandIcon exists', () => {
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...defaultProps}
          enableBrandIconPreview={true}
          brandIcon="https://example.com/brand-icon.png"
        />
      );
      
      const brandIconContainer = wrapper.find('.notification-brand-icon-container.windows-chrome-brand-icon');
      expect(brandIconContainer.exists()).toBe(true);
      
      const brandIcon = wrapper.find('.notification-brand-icon');
      expect(brandIcon.exists()).toBe(true);
      expect(brandIcon.prop('src')).toBe('https://example.com/brand-icon.png');
      expect(brandIcon.prop('alt')).toBe('Brand icon');
    });

    it('should not show brand icon when enableBrandIconPreview is false', () => {
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...defaultProps}
          enableBrandIconPreview={false}
          brandIcon="https://example.com/brand-icon.png"
        />
      );
      
      const brandIconContainer = wrapper.find('.notification-brand-icon-container.windows-chrome-brand-icon');
      expect(brandIconContainer.exists()).toBe(false);
    });

    it('should not show brand icon when brandIcon is empty string', () => {
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...defaultProps}
          enableBrandIconPreview={true}
          brandIcon=""
        />
      );
      
      const brandIconContainer = wrapper.find('.notification-brand-icon-container.windows-chrome-brand-icon');
      expect(brandIconContainer.exists()).toBe(false);
    });

    it('should not show brand icon when brandIcon is null', () => {
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...defaultProps}
          enableBrandIconPreview={true}
          brandIcon={null}
        />
      );
      
      const brandIconContainer = wrapper.find('.notification-brand-icon-container.windows-chrome-brand-icon');
      expect(brandIconContainer.exists()).toBe(false);
    });

    it('should not show brand icon when brandIcon is undefined', () => {
      const propsWithoutBrandIcon = { ...defaultProps };
      delete propsWithoutBrandIcon.brandIcon;
      
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...propsWithoutBrandIcon}
          enableBrandIconPreview={true}
        />
      );
      
      const brandIconContainer = wrapper.find('.notification-brand-icon-container.windows-chrome-brand-icon');
      expect(brandIconContainer.exists()).toBe(false);
    });

    it('should handle Boolean(brandIcon) correctly for falsy values', () => {
      // Test with 0 (falsy but not empty string)
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...defaultProps}
          enableBrandIconPreview={true}
          brandIcon={0}
        />
      );
      
      const brandIconContainer = wrapper.find('.notification-brand-icon-container.windows-chrome-brand-icon');
      expect(brandIconContainer.exists()).toBe(false);
    });
  });

  describe('Media Image Display', () => {
    it('should render media image when mediaImageUrl is provided', () => {
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...defaultProps}
          mediaImageUrl="https://example.com/media-image.jpg"
        />
      );
      
      const banner = wrapper.find('.windows-chrome-banner');
      expect(banner.exists()).toBe(true);
      
      const bannerImage = wrapper.find('.windows-chrome-banner-image');
      expect(bannerImage.exists()).toBe(true);
      expect(bannerImage.prop('src')).toBe('https://example.com/media-image.jpg');
      expect(bannerImage.prop('alt')).toBe('Notification banner');
    });

    it('should not render media image when mediaImageUrl is empty string', () => {
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...defaultProps}
          mediaImageUrl=""
        />
      );
      
      const banner = wrapper.find('.windows-chrome-banner');
      expect(banner.exists()).toBe(false);
    });

    it('should not render media image when mediaImageUrl is not provided', () => {
      const propsWithoutMedia = { ...defaultProps };
      delete propsWithoutMedia.mediaImageUrl;
      
      const wrapper = mountWithIntl(<WindowsChromeExpanded {...propsWithoutMedia} />);
      
      const banner = wrapper.find('.windows-chrome-banner');
      expect(banner.exists()).toBe(false);
    });

    it('should not render media image when mediaImageUrl is null', () => {
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...defaultProps}
          mediaImageUrl={null}
        />
      );
      
      const banner = wrapper.find('.windows-chrome-banner');
      expect(banner.exists()).toBe(false);
    });

    it('should not render media image when mediaImageUrl is undefined', () => {
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...defaultProps}
          mediaImageUrl={undefined}
        />
      );
      
      const banner = wrapper.find('.windows-chrome-banner');
      expect(banner.exists()).toBe(false);
    });
  });

  describe('CTA Buttons', () => {
    it('should render CTA buttons when enableCtas is true and ctaButtons array has items', () => {
      const ctaButtons = [
        { id: '1', label: 'Button 1' },
        { id: '2', label: 'Button 2' },
      ];
      
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...defaultProps}
          enableCtas={true}
          ctaButtons={ctaButtons}
        />
      );
      
      const ctaContainer = wrapper.find('.windows-chrome-cta-container');
      expect(ctaContainer.exists()).toBe(true);
      
      const ctaButtonsElements = wrapper.find('.windows-chrome-cta-button');
      expect(ctaButtonsElements.length).toBe(2);
      
      expect(ctaButtonsElements.at(0).find('.windows-chrome-cta-button-text').text()).toBe('Button 1');
      expect(ctaButtonsElements.at(1).find('.windows-chrome-cta-button-text').text()).toBe('Button 2');
    });

    it('should not render CTA buttons when enableCtas is false', () => {
      const ctaButtons = [
        { id: '1', label: 'Button 1' },
      ];
      
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...defaultProps}
          enableCtas={false}
          ctaButtons={ctaButtons}
        />
      );
      
      const ctaContainer = wrapper.find('.windows-chrome-cta-container');
      expect(ctaContainer.exists()).toBe(false);
    });

    it('should not render CTA buttons when ctaButtons array is empty', () => {
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...defaultProps}
          enableCtas={true}
          ctaButtons={[]}
        />
      );
      
      const ctaContainer = wrapper.find('.windows-chrome-cta-container');
      expect(ctaContainer.exists()).toBe(false);
    });

    it('should not render CTA buttons when ctaButtons is null', () => {
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...defaultProps}
          enableCtas={true}
          ctaButtons={null}
        />
      );
      
      const ctaContainer = wrapper.find('.windows-chrome-cta-container');
      expect(ctaContainer.exists()).toBe(false);
    });

    it('should not render CTA buttons when ctaButtons is undefined', () => {
      const propsWithoutCtas = { ...defaultProps };
      delete propsWithoutCtas.ctaButtons;
      
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...propsWithoutCtas}
          enableCtas={true}
        />
      );
      
      const ctaContainer = wrapper.find('.windows-chrome-cta-container');
      expect(ctaContainer.exists()).toBe(false);
    });

    it('should apply single button class when only one CTA button is provided', () => {
      const ctaButtons = [
        { id: '1', label: 'Single Button' },
      ];
      
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...defaultProps}
          enableCtas={true}
          ctaButtons={ctaButtons}
        />
      );
      
      const ctaButton = wrapper.find('.windows-chrome-cta-button');
      expect(ctaButton.hasClass('windows-chrome-cta-button-single')).toBe(true);
    });

    it('should not apply single button class when multiple CTA buttons are provided', () => {
      const ctaButtons = [
        { id: '1', label: 'Button 1' },
        { id: '2', label: 'Button 2' },
      ];
      
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...defaultProps}
          enableCtas={true}
          ctaButtons={ctaButtons}
        />
      );
      
      const ctaButtonsElements = wrapper.find('.windows-chrome-cta-button');
      ctaButtonsElements.forEach((button) => {
        expect(button.hasClass('windows-chrome-cta-button-single')).toBe(false);
      });
    });

    it('should render CTA buttons with correct keys', () => {
      const ctaButtons = [
        { id: 'button-1', label: 'Button 1' },
        { id: 'button-2', label: 'Button 2' },
      ];
      
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...defaultProps}
          enableCtas={true}
          ctaButtons={ctaButtons}
        />
      );
      
      const ctaButtonsElements = wrapper.find('.windows-chrome-cta-button');
      expect(ctaButtonsElements.at(0).key()).toBe('button-1');
      expect(ctaButtonsElements.at(1).key()).toBe('button-2');
    });

    it('should handle CTA button with missing label', () => {
      const ctaButtons = [
        { id: '1' },
      ];
      
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...defaultProps}
          enableCtas={true}
          ctaButtons={ctaButtons}
        />
      );
      
      const ctaButton = wrapper.find('.windows-chrome-cta-button');
      expect(ctaButton.exists()).toBe(true);
      expect(ctaButton.find('.windows-chrome-cta-button-text').text()).toBe('');
    });
  });

  describe('Edge Cases and Optional Props', () => {
    it('should handle empty notification title', () => {
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded {...defaultProps} notificationTitle="" />
      );
      const title = wrapper.find('.windows-chrome-title');
      
      expect(title.exists()).toBe(true);
      expect(title.text()).toBe('');
    });

    it('should handle empty notification body', () => {
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded {...defaultProps} notificationBody="" />
      );
      const body = wrapper.find('.windows-chrome-body-text');
      
      expect(body.exists()).toBe(true);
      expect(body.text()).toBe('');
    });

    it('should handle empty display URL', () => {
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded {...defaultProps} displayUrl="" />
      );
      const url = wrapper.find('.windows-chrome-url');
      
      expect(url.exists()).toBe(true);
      expect(url.text()).toBe('');
    });

    it('should handle very long notification title', () => {
      const longTitle = 'A'.repeat(200);
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded {...defaultProps} notificationTitle={longTitle} />
      );
      const title = wrapper.find('.windows-chrome-title');
      
      expect(title.exists()).toBe(true);
      expect(title.text()).toBe(longTitle);
    });

    it('should handle very long notification body', () => {
      const longBody = 'B'.repeat(500);
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded {...defaultProps} notificationBody={longBody} />
      );
      const body = wrapper.find('.windows-chrome-body-text');
      
      expect(body.exists()).toBe(true);
      expect(body.text()).toBe(longBody);
    });

    it('should handle missing optional props gracefully', () => {
      const minimalProps = {
        icon: 'https://example.com/icon.png',
      };
      
      const wrapper = mountWithIntl(<WindowsChromeExpanded {...minimalProps} />);
      
      // Should still render all structural elements
      expect(wrapper.find('.windows-chrome-expanded-wrapper').exists()).toBe(true);
      expect(wrapper.find('.windows-chrome-title').exists()).toBe(true);
      expect(wrapper.find('.windows-chrome-body-text').exists()).toBe(true);
    });
  });

  describe('Component Structure', () => {
    it('should have correct DOM hierarchy', () => {
      const wrapper = mountWithIntl(<WindowsChromeExpanded {...defaultProps} />);
      
      // Wrapper should contain banner and body
      const wrapperDiv = wrapper.find('.windows-chrome-expanded-wrapper');
      expect(wrapperDiv.exists()).toBe(true);
      
      // Body should contain header row and content row
      const body = wrapper.find('.windows-chrome-body');
      expect(body.find('.windows-chrome-header-row').exists()).toBe(true);
      expect(body.find('.windows-chrome-content-row').exists()).toBe(true);
      
      // Text block should contain title, body, and URL
      const textBlock = wrapper.find('.windows-chrome-text-block');
      expect(textBlock.find('.windows-chrome-title').exists()).toBe(true);
      expect(textBlock.find('.windows-chrome-body-text').exists()).toBe(true);
      expect(textBlock.find('.windows-chrome-url').exists()).toBe(true);
    });

    it('should render brand icon in correct location when shown', () => {
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...defaultProps}
          enableBrandIconPreview={true}
          brandIcon="https://example.com/brand-icon.png"
        />
      );
      
      // Brand icon should be in the content row
      const contentRow = wrapper.find('.windows-chrome-content-row');
      const brandIconContainer = contentRow.find('.notification-brand-icon-container.windows-chrome-brand-icon');
      
      expect(brandIconContainer.exists()).toBe(true);
    });

    it('should render media image before body when provided', () => {
      const wrapper = mountWithIntl(
        <WindowsChromeExpanded
          {...defaultProps}
          mediaImageUrl="https://example.com/media.jpg"
        />
      );
      
      // Banner should be before body
      const wrapperDiv = wrapper.find('.windows-chrome-expanded-wrapper');
      const children = wrapperDiv.children();
      
      expect(children.at(0).hasClass('windows-chrome-banner')).toBe(true);
      expect(children.at(1).hasClass('windows-chrome-body')).toBe(true);
    });
  });

  describe('PropTypes Validation', () => {
    it('should require icon prop', () => {
      const propsWithoutIcon = { ...defaultProps };
      delete propsWithoutIcon.icon;
      
      // PropTypes validation happens at runtime, but we can verify the component handles missing props
      // In a real scenario, this would be caught by PropTypes in development mode
      expect(() => {
        mountWithIntl(<WindowsChromeExpanded {...propsWithoutIcon} />);
      }).not.toThrow();
    });
  });
});

