/**
 * Tests for WhatsAppPreviewContent Component
 * 
 * Tests WhatsApp preview rendering with all states, media types, and edge cases
 */

import React from 'react';
import { render, screen } from '@testing-library/react';
import { IntlProvider, injectIntl } from 'react-intl';
import '@testing-library/jest-dom';
import WhatsAppPreviewContent from '../../UnifiedPreview/WhatsAppPreviewContent';
import { ANDROID, IOS } from '../../constants';
import messages from '../../messages';
// Mock utilities
// Jest resolves mocks from the test file location
// Path: ../../../../v2Containers/Whatsapp/utils
// jest.mock('../../../../v2Containers/Whatsapp/utils', () => ({
//   getWhatsappQuickReply: jest.fn(() => <div data-testid="quick-reply">Quick Reply</div>),
//   getWhatsappCarouselButtonView: jest.fn(() => <div data-testid="carousel-buttons">Carousel Buttons</div>),
// }));

// Path: ../../../../v2Containers/Whatsapp/constants
jest.mock('../../../../v2Containers/Whatsapp/constants', () => ({
  QUICK_REPLY: 'QUICK_REPLY',
  PHONE_NUMBER: 'PHONE_NUMBER',
  WHATSAPP_CATEGORIES: {
    authentication: 'authentication',
  },
  TEMPLATE_VARIABLE_REGEX: /\{\{.*?\}\}/,
}));

// Convert messages object to format expected by IntlProvider
const messagesForIntl = Object.keys(messages).reduce((acc, key) => {
  const message = messages[key];
  acc[message.id] = message.defaultMessage;
  return acc;
}, {});
        
// Wrap component with injectIntl - PreviewHeader doesn't need formatMessage, it uses FormattedMessage
// But we still need IntlProvider for FormattedMessage to work
const ComponentToRender = injectIntl(({ intl, ...props }) => (
  <WhatsAppPreviewContent {...props} formatMessage={intl.formatMessage} />
));
        
// Test wrapper - use IntlProvider with messages
const TestWrapper = ({ children }) => (
  <IntlProvider locale="en" messages={messagesForIntl}>
    {children}
  </IntlProvider>
);

describe('WhatsAppPreviewContent', () => {
  const defaultProps = {
    content: {
      templateMsg: 'WhatsApp message text',
      accountName: 'Test Account',
    },
    device: ANDROID,
    isUpdating: false,
    error: null,
    formatMessage: jest.fn((msg) => msg.defaultMessage || msg.id),
    accountName: 'Test Account',
  };

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

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

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

      expect(screen.getByText('Updating preview with the latest changes')).toBeTruthy();
    });

    it('should show loading spinner', () => {
      const props = {
        ...defaultProps,
        isUpdating: true,
      };

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

      expect(container.querySelector('.ant-spin')).toBeTruthy();
    });

    it('should render WhatsApp structure in loading state', () => {
      const props = {
        ...defaultProps,
        isUpdating: true,
      };

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

      expect(container.querySelector('.whatsapp-preview-wrapper')).toBeTruthy();
      expect(container.querySelector('.shell-v2-whatsapp')).toBeTruthy();
    });
  });

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

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

      expect(screen.getAllByText('Failed to load preview')).toHaveLength(2);
    });

    it('should show error icon', () => {
      const props = {
        ...defaultProps,
        error: 'Error message',
      };

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

      expect(container.querySelector('.anticon-exclamation-circle')).toBeTruthy();
    });
  });

  describe('Normal State - Text Content', () => {
    it('should render template message', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Hello, this is a WhatsApp message',
        },
      };

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

      expect(screen.getByText('Hello, this is a WhatsApp message')).toBeTruthy();
    });

    it('should handle message with newlines', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Line 1\nLine 2\nLine 3',
        },
      };

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

      expect(screen.getByText(/Line 1/)).toBeTruthy();
    });

    it('should render template header', () => {
      const props = {
        ...defaultProps,
        content: {
          templateHeader: 'Header Text',
          templateMsg: 'Message',
        },
      };

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

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

    it('should render template footer', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          templateFooter: 'Footer Text',
        },
      };

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

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

  describe('Media Content', () => {
    it('should render image when whatsappImageSrc is present', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          whatsappImageSrc: 'https://image.url',
        },
      };

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

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

    it('should render placeholder when whatsappImageSrc is a template variable', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          whatsappImageSrc: '{{imageUrl}}',
        },
      };

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

      expect(container.querySelector('.whatsapp-image-url-placeholder')).toBeTruthy();
      expect(container.querySelector('.whatsapp-image-url-placeholder-icon')).toBeTruthy();
      expect(container.querySelector('.whatsapp-image-url-placeholder-text').textContent).toBe('{{imageUrl}}');
      expect(container.querySelector('img.whatsapp-image')).toBeFalsy();
    });

    it('should fall back to empty preview image when image fails to load', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          whatsappImageSrc: 'https://broken.url/image.jpg',
        },
      };

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

      const image = container.querySelector('img.whatsapp-image');
      expect(image).toBeTruthy();
      expect(image.getAttribute('src')).toBe('https://broken.url/image.jpg');

      // Trigger onError to swap src to fallback
      const errorEvent = new Event('error');
      image.dispatchEvent(errorEvent);

      expect(image.getAttribute('src')).not.toBe('https://broken.url/image.jpg');
    });

    it('should render video preview when whatsappVideoPreviewImg is present', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          whatsappVideoPreviewImg: 'https://video-preview.url',
        },
      };

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

      expect(container.querySelector('.video-preview')).toBeTruthy();
      expect(container.querySelector('.video-icon')).toBeTruthy();
    });

    it('should render document preview when docPreview is present', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          docPreview: <div data-testid="doc-preview">Document</div>,
        },
      };

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

      expect(screen.getByTestId('doc-preview')).toBeTruthy();
    });
  });

  describe('URL Preview', () => {
    it('should render URL preview when showUrlPreview is true', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          showUrlPreview: true,
          metaTagsDetails: {
            image: 'https://preview-image.url',
            title: 'URL Title',
            description: 'URL Description',
            url: 'https://example.com',
          },
        },
      };

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

      expect(screen.getByText('URL Title')).toBeTruthy();
      expect(screen.getByText('URL Description')).toBeTruthy();
      expect(screen.getByText('https://example.com')).toBeTruthy();
    });

    it('should not render URL preview when showUrlPreview is false', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          showUrlPreview: false,
          metaTagsDetails: {
            title: 'URL Title',
          },
        },
      };

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

      expect(screen.queryByText('URL Title')).toBeNull();
    });

    it('should handle URL preview with only image', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          showUrlPreview: true,
          metaTagsDetails: {
            image: 'https://preview-image.url',
          },
        },
      };

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

      expect(container.querySelector('.url-preview-image')).toBeTruthy();
    });

    it('should handle URL preview with only title', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          showUrlPreview: true,
          metaTagsDetails: {
            title: 'URL Title',
          },
        },
      };

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

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

  describe('CTA Buttons', () => {
    it('should render CTA buttons when ctaData is present', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          ctaData: [
            { type: 'PHONE_NUMBER', text: 'Call Us', ctaType: 'PHONE_NUMBER' },
            { type: 'DYNAMIC_URL', text: 'Visit Website', ctaType: 'DYNAMIC_URL' },
          ],
        },
      };

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

      expect(screen.getByText('Call Us')).toBeTruthy();
      expect(screen.getByText('Visit Website')).toBeTruthy();
    });

    it('should render phone number icon for PHONE_NUMBER type', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          ctaData: [
            { type: 'PHONE_NUMBER', text: 'Call', ctaType: 'PHONE_NUMBER' },
          ],
        },
      };

      const { container } = render(
        <TestWrapper>
          <ComponentToRender {...props} />
        </TestWrapper>
      );
      expect(container.querySelector('.cap-icon-v2-call')).toBeTruthy();
    });

    it('should render launch icon for non-phone CTA types', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          ctaData: [
            { type: 'DYNAMIC_URL', text: 'Visit', ctaType: 'DYNAMIC_URL' },
          ],
        },
      };

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

      expect(container.querySelector('.cap-icon-v2-launch')).toBeTruthy();
    });

    it('should not render icon for authentication type', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          ctaData: [
            { type: 'authentication', text: 'Authenticate', ctaType: 'authentication' },
          ],
        },
      };

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

      expect(container.querySelector('.anticon-call')).toBeFalsy();
      expect(container.querySelector('.anticon-launch')).toBeFalsy();
    });

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

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

      expect(screen.queryAllByText('')).toHaveLength(9);
    });

    it('should render divider before CTA buttons', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          ctaData: [
            { type: 'PHONE_NUMBER', text: 'Call', ctaType: 'PHONE_NUMBER' },
          ],
        },
      };

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

      expect(container.querySelector('.whatsapp-divider')).toBeTruthy();
    });
  });

  describe('Quick Reply Buttons', () => {
    it('should render quick reply buttons when quickReplyData is present', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          quickReplyData: [
            { text: 'Yes' },
            { text: 'No' },
          ],
        },
      };

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

      expect(screen.getByText('Yes')).toBeTruthy();
      expect(screen.getByText('No')).toBeTruthy();
    });

    it('should not render quick reply when quickReplyData is empty', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          quickReplyData: [],
        },
      };

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

      // getWhatsappQuickReply should not be called with empty array
      expect(screen.queryByTestId('quick-reply')).toBeFalsy();
    });
  });

  describe('Carousel Content', () => {
    it('should render carousel when carouselData is present', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          carouselData: [
            {
              bodyText: 'Carousel Item 1',
              imageSrc: 'https://image1.url',
            },
            {
              bodyText: 'Carousel Item 2',
              imageSrc: 'https://image2.url',
            },
          ],
        },
      };

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

      expect(screen.getByText('Carousel Item 1')).toBeTruthy();
      expect(screen.getByText('Carousel Item 2')).toBeTruthy();
    });

    it('should apply carousel classes when carouselData is present', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          carouselData: [
            { bodyText: 'Item 1' },
          ],
        },
      };

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

      expect(container.querySelector('.msg-container-carousel')).toBeTruthy();
      expect(container.querySelector('.message-pop-carousel')).toBeTruthy();
    });

    it('should render carousel with image media type', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          carouselMediaType: 'image',
          carouselData: [
            {
              bodyText: 'Item 1',
              imageSrc: 'https://image.url',
            },
          ],
        },
      };

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

      const image = container.querySelector('.whatsapp-image');
      expect(image).toBeTruthy();
    });

    it('should render carousel with video media type', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          carouselMediaType: 'video',
          carouselData: [
            {
              bodyText: 'Item 1',
              videoPreviewImg: 'https://video-preview.url',
            },
          ],
        },
      };

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

      expect(container.querySelector('.video-preview')).toBeTruthy();
    });

    it('should use updatedBodyText when isEditFlow is true', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          isEditFlow: true,
          carouselData: [
            {
              updatedBodyText: ['Updated', 'Text'],
              bodyText: 'Original Text',
            },
          ],
        },
      };

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

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

    it('should use bodyText when isEditFlow is false', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          isEditFlow: false,
          carouselData: [
            {
              bodyText: 'Original Text',
            },
          ],
        },
      };

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

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

    it('should render carousel buttons', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          carouselData: [
            {
              bodyText: 'Item 1',
              buttons: [{ text: 'Button 1' }],
            },
          ],
        },
      };

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

      expect(screen.getByText('Button 1')).toBeTruthy();
    });
  });

  describe('Account Name', () => {
    it('should display account name from content', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          accountName: 'Content Account',
        },
        accountName: 'Prop Account',
      };

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

      expect(screen.getByText('Prop Account')).toBeTruthy();
    });

    it('should display account name from prop when not in content', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
        },
        accountName: 'Prop Account',
      };

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

      expect(screen.getByText('Prop Account')).toBeTruthy();
    });

    it('should display empty string when account name is not provided', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
        },
        accountName: null,
      };

      const { container } = render(
        <TestWrapper>
          <ComponentToRender {...props} />
        </TestWrapper>
      );
      const brandName = container.querySelector('.whatsapp-brand-name');
      expect(brandName).toHaveTextContent('');
    });
  });

  describe('Device Handling', () => {
    it('should use Android device image for ANDROID device', () => {
      const props = {
        ...defaultProps,
        device: ANDROID,
      };

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

      const image = container.querySelector('.preview-image');
      expect(image).toBeTruthy();
    });

    it('should use iOS device image for IOS device', () => {
      const props = {
        ...defaultProps,
        device: IOS,
      };

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

      const image = container.querySelector('.preview-image');
      expect(image).toBeTruthy();
    });
  });

  describe('No Content State', () => {
    it('should render no content message when content is empty', () => {
      const props = {
        ...defaultProps,
        content: null,
      };

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

      expect(screen.getByText('No content available')).toBeTruthy();
    });

    it('should render no content message when content is empty object', () => {
      const props = {
        ...defaultProps,
        content: null,
      };

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

      expect(screen.getByText('No content available')).toBeTruthy();
    });
  });

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

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

      // Should still render structure
      expect(container.querySelector('.whatsapp-content')).toBeTruthy();
    });

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

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

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

    it('should handle message with only whitespace', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: '   \n   ',
        },
      };

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

      // Should render structure
      expect(container.querySelector('.whatsapp-content')).toBeTruthy();
    });

    it('should handle carousel with missing imageSrc', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          carouselMediaType: 'image',
          carouselData: [
            {
              bodyText: 'Item 1',
            },
          ],
        },
      };

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

      // Should use empty preview image
      const image = container.querySelector('.whatsapp-image');
      expect(image).toBeTruthy();
    });

    it('should handle carousel with missing videoPreviewImg', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          carouselMediaType: 'video',
          carouselData: [
            {
              bodyText: 'Item 1',
            },
          ],
        },
      };

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

      // Should use empty preview image
      const image = container.querySelector('.whatsapp-image');
      expect(image).toBeTruthy();
    });

    it('should handle CTA data with missing type', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          ctaData: [
            { text: 'Button Text' },
          ],
        },
      };

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

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

    it('should handle multiple CTAs', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMsg: 'Message',
          ctaData: [
            { type: 'PHONE_NUMBER', text: 'Call', ctaType: 'PHONE_NUMBER' },
            { type: 'DYNAMIC_URL', text: 'Visit', ctaType: 'DYNAMIC_URL' },
            { type: 'DYNAMIC_URL', text: 'Learn More', ctaType: 'DYNAMIC_URL' },
          ],
        },
      };

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

      expect(screen.getByText('Call')).toBeTruthy();
      expect(screen.getByText('Visit')).toBeTruthy();
      expect(screen.getByText('Learn More')).toBeTruthy();
    });
  });

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

      render(
        <TestWrapper>
          <ComponentToRender {...minimalProps} />
        </TestWrapper>
      );

      expect(screen.getByText('Business Account')).toBeTruthy();
    });
  });

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

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

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