/**
 * Tests for InAppPreviewContent Component
 * 
 * Tests InApp preview rendering with all states, layouts, media types, and edge cases
 */

import React from 'react';
import { render, screen } from '@testing-library/react';
import { IntlProvider } from 'react-intl';
import InAppPreviewContent from '../../UnifiedPreview/InAppPreviewContent';
import { ANDROID, IOS, LAYOUT_TYPE_POPUP } from '../../constants';

// Mock messages
const mockMessages = {
  'app.v2Components.TestAndPreviewSlidebox.updatingPreview': {
    id: 'app.v2Components.TestAndPreviewSlidebox.updatingPreview',
    defaultMessage: 'Updating preview with the latest changes',
  },
  'app.components.CommonTestAndPreview.previewError': {
    id: 'app.components.CommonTestAndPreview.previewError',
    defaultMessage: 'Failed to load preview',
  },
  'app.components.CommonTestAndPreview.previewGenerated': {
    id: 'app.components.CommonTestAndPreview.previewGenerated',
    defaultMessage: 'Preview is being generated',
  },
};

// Test wrapper
const TestWrapper = ({ children }) => (
  <IntlProvider locale="en" messages={mockMessages}>
    {children}
  </IntlProvider>
);

describe('InAppPreviewContent', () => {
  const defaultProps = {
    content: {
      androidContent: {
        templateTitle: 'Android Title',
        templateMsg: 'Android Message',
        mediaPreview: {},
        ctaData: [],
        templateLayoutType: LAYOUT_TYPE_POPUP,
      },
      iosContent: {
        templateTitle: 'iOS Title',
        templateMsg: 'iOS Message',
        mediaPreview: {},
        ctaData: [],
        templateLayoutType: LAYOUT_TYPE_POPUP,
      },
    },
    device: ANDROID,
    isUpdating: false,
    error: null,
    formatMessage: jest.fn((msg) => msg.defaultMessage || msg.id),
    templateLayoutType: LAYOUT_TYPE_POPUP,
    showHeader: true,
  };

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

  describe('Loading State', () => {
    it('should render loading state when isUpdating is true', () => {
      const props = {
        ...defaultProps,
        isUpdating: true,
      };

      const { container } = render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      // The component renders the loading text using formatMessage
      // Check that formatMessage was called and component rendered
      expect(defaultProps.formatMessage).toHaveBeenCalled();
      const loadingContainer = container.querySelector('.sms-loading-container');
      expect(loadingContainer).toBeTruthy();
    });
  });

  describe('Error State', () => {
    it('should render error state when error is present', () => {
      const props = {
        ...defaultProps,
        error: 'Failed to load preview',
      };

      render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      expect(screen.getByText('Failed to load preview')).toBeTruthy();
    });
  });

  describe('Content Extraction', () => {
    it('should extract Android content for ANDROID device', () => {
      const props = {
        ...defaultProps,
        device: ANDROID,
        content: {
          androidContent: {
            templateTitle: 'Android Title',
            templateMsg: 'Android Message',
          },
          iosContent: {
            templateTitle: 'iOS Title',
            templateMsg: 'iOS Message',
          },
        },
      };

      render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      expect(screen.getByText('Android Title')).toBeTruthy();
      expect(screen.getByText('Android Message')).toBeTruthy();
    });

    it('should extract iOS content for IOS device', () => {
      const props = {
        ...defaultProps,
        device: IOS,
        content: {
          androidContent: {
            templateTitle: 'Android Title',
            templateMsg: 'Android Message',
          },
          iosContent: {
            templateTitle: 'iOS Title',
            templateMsg: 'iOS Message',
          },
        },
      };

      render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      expect(screen.getByText('iOS Title')).toBeTruthy();
      expect(screen.getByText('iOS Message')).toBeTruthy();
    });

    it('should use inAppPreviewContent as fallback', () => {
      const props = {
        ...defaultProps,
        content: {
          inAppPreviewContent: {
            templateTitle: 'Fallback Title',
            templateMsg: 'Fallback Message',
          },
        },
      };

      render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      expect(screen.getByText('Fallback Title')).toBeTruthy();
      expect(screen.getByText('Fallback Message')).toBeTruthy();
    });

    it('should use direct content object as fallback', () => {
      const props = {
        ...defaultProps,
        content: {
          templateTitle: 'Direct Title',
          templateMsg: 'Direct Message',
        },
      };

      render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      expect(screen.getByText('Direct Title')).toBeTruthy();
      expect(screen.getByText('Direct Message')).toBeTruthy();
    });
  });

  describe('Layout Types', () => {
    it('should apply POPUP layout class', () => {
      const props = {
        ...defaultProps,
        templateLayoutType: 'POPUP',
      };

      const { container } = render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      expect(container.querySelector('.inapp-message-container-POPUP')).toBeTruthy();
    });

    it('should apply FULLSCREEN layout class', () => {
      const props = {
        ...defaultProps,
        templateLayoutType: 'FULLSCREEN',
        content: {
          androidContent: {
            templateTitle: 'Title',
            templateMsg: 'Message',
            mediaPreview: {},
            ctaData: [],
            templateLayoutType: 'FULLSCREEN',
          },
          iosContent: {
            templateTitle: 'Title',
            templateMsg: 'Message',
            mediaPreview: {},
            ctaData: [],
            templateLayoutType: 'FULLSCREEN',
          },
        },
      };

      const { container } = render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      const fullscreenContainer = container.querySelector('.inapp-message-container-FULLSCREEN');
      expect(fullscreenContainer).toBeTruthy();
      expect(fullscreenContainer).not.toBeNull();
    });

    it('should use deviceLayoutType from content when available', () => {
      const props = {
        ...defaultProps,
        content: {
          androidContent: {
            templateTitle: 'Title',
            templateMsg: 'Message',
            templateLayoutType: 'FULLSCREEN',
          },
        },
      };

      const { container } = render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      expect(container.querySelector('.inapp-message-container-FULLSCREEN')).toBeTruthy();
    });
  });

  describe('Media Preview', () => {
    it('should render Android image when inAppImageSrcAndroid is present', () => {
      const props = {
        ...defaultProps,
        device: ANDROID,
        content: {
          androidContent: {
            templateTitle: 'Title',
            templateMsg: 'Message',
            mediaPreview: {
              inAppImageSrcAndroid: 'https://android-image.url',
            },
          },
        },
      };

      const { container } = render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      const image = container.querySelector('.inapp-image-POPUP');
      expect(image).toBeTruthy();
      expect(image.getAttribute('src')).toBe('https://android-image.url');
    });

    it('should render iOS image when inAppImageSrcIos is present', () => {
      const props = {
        ...defaultProps,
        device: IOS,
        content: {
          iosContent: {
            templateTitle: 'Title',
            templateMsg: 'Message',
            mediaPreview: {
              inAppImageSrcIos: 'https://ios-image.url',
            },
          },
        },
      };

      const { container } = render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      const image = container.querySelector('.inapp-image-POPUP');
      expect(image).toBeTruthy();
      expect(image.getAttribute('src')).toBe('https://ios-image.url');
    });

    it('should apply without-image class when no image is present', () => {
      const props = {
        ...defaultProps,
        content: {
          androidContent: {
            templateTitle: 'Title',
            templateMsg: 'Message',
            mediaPreview: {},
          },
        },
      };

      const { container } = render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      expect(container.querySelector('.without-image-title-POPUP')).toBeTruthy();
      expect(container.querySelector('.without-image-content-POPUP')).toBeTruthy();
    });
  });

  describe('CTA Buttons', () => {
    it('should render CTA button when ctaData is present', () => {
      const props = {
        ...defaultProps,
        content: {
          androidContent: {
            templateTitle: 'Title',
            templateMsg: 'Message',
            ctaData: [
              { text: 'Click Here' },
            ],
          },
        },
      };

      render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      expect(screen.getByText('Click Here')).toBeTruthy();
    });

    it('should use actionText as fallback for CTA text', () => {
      const props = {
        ...defaultProps,
        content: {
          androidContent: {
            templateTitle: 'Title',
            templateMsg: 'Message',
            ctaData: [
              { actionText: 'Action Text' },
            ],
          },
        },
      };

      render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      expect(screen.getByText('Action Text')).toBeTruthy();
    });

    it('should not render CTA when ctaData is empty', () => {
      const props = {
        ...defaultProps,
        content: {
          androidContent: {
            templateTitle: 'Title',
            templateMsg: 'Message',
            ctaData: [],
          },
        },
      };

      render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      // Should not have button
      expect(screen.queryByRole('button')).toBeFalsy();
    });

    it('should not render CTA when text is empty', () => {
      const props = {
        ...defaultProps,
        content: {
          androidContent: {
            templateTitle: 'Title',
            templateMsg: 'Message',
            ctaData: [
              { text: '' },
            ],
          },
        },
      };

      render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      expect(screen.queryByRole('button')).toBeFalsy();
    });
  });

  describe('Show Header', () => {
    it('should apply no-header class when showHeader is false and layout is FOOTER', () => {
      const props = {
        ...defaultProps,
        showHeader: false,
        templateLayoutType: 'FOOTER',
        content: {
          androidContent: {
            templateTitle: 'Title',
            templateMsg: 'Message',
            templateLayoutType: 'FOOTER',
          },
        },
      };

      const { container } = render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      expect(container.querySelector('.inapp-message-container-FOOTER-no-header')).toBeTruthy();
    });

    it('should apply inapp-content-overlay class when showHeader is false', () => {
      const props = {
        ...defaultProps,
        showHeader: false,
      };

      const { container } = render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      expect(container.querySelector('.inapp-content-overlay')).toBeTruthy();
    });
  });

  describe('Edge Cases', () => {
    it('should handle empty title', () => {
      const props = {
        ...defaultProps,
        content: {
          androidContent: {
            templateTitle: '',
            templateMsg: 'Message',
          },
        },
      };

      render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      expect(screen.getByText('Message')).toBeTruthy();
    });

    it('should handle empty message', () => {
      const props = {
        ...defaultProps,
        content: {
          androidContent: {
            templateTitle: 'Title',
            templateMsg: '',
          },
        },
      };

      render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      expect(screen.getByText('Title')).toBeTruthy();
    });

    it('should handle null content', () => {
      const props = {
        ...defaultProps,
        content: null,
      };

      const { container } = render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      // Should not crash - component should render device container
      const deviceContainer = container.querySelector('.sms-device-container');
      expect(deviceContainer).toBeTruthy();
    });

    it('should handle missing androidContent and iosContent', () => {
      const props = {
        ...defaultProps,
        content: {},
      };

      const { container } = render(
        <TestWrapper>
          <InAppPreviewContent {...props} />
        </TestWrapper>
      );

      // Should not crash - component should render device container
      const deviceContainer = container.querySelector('.sms-device-container');
      expect(deviceContainer).toBeTruthy();
    });
  });

  describe('Default Props', () => {
    it('should use default props when not provided', () => {
      const minimalProps = {
        formatMessage: jest.fn((msg) => msg.defaultMessage || msg.id),
      };

      const { container } = render(
        <TestWrapper>
          <InAppPreviewContent {...minimalProps} />
        </TestWrapper>
      );

      // Should render without crashing - component should render device container
      const deviceContainer = container.querySelector('.sms-device-container');
      expect(deviceContainer).toBeTruthy();
    });
  });

  describe('PropTypes Validation', () => {
    it('should accept all required props without warnings', () => {
      const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {});

      render(
        <TestWrapper>
          <InAppPreviewContent {...defaultProps} />
        </TestWrapper>
      );

      expect(consoleSpy).not.toHaveBeenCalled();
      consoleSpy.mockRestore();
    });
  });
});
