/**
 * Tests for RcsPreviewContent Component
 * 
 * Tests RCS preview rendering with all states, media types, suggestions, and edge cases
 */

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

// Mock constants
// Jest resolves mocks from the test file location
// Path: ../../../../v2Containers/Rcs/constants
jest.mock('../../../../v2Containers/Rcs/constants', () => ({
  RCS_BUTTON_TYPES: {
    QUICK_REPLY: 'QUICK_REPLY',
    CTA: 'CTA',
    PHONE_NUMBER: 'PHONE_NUMBER',
  },
}));

// 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 }) => (
  <RcsPreviewContent {...props} formatMessage={intl.formatMessage} />
));
  
// Test wrapper - use IntlProvider with messages
const TestWrapper = ({ children }) => (
  <IntlProvider locale="en" messages={messagesForIntl}>
    {children}
  </IntlProvider>
);

describe('RcsPreviewContent', () => {
  const defaultProps = {
    content: {
      templateHeader: 'RCS Title',
      templateMessage: 'RCS Description',
    },
    device: ANDROID,
    isUpdating: false,
    error: null,
    formatMessage: jest.fn((msg) => msg.defaultMessage || msg.id),
    senderId: 'RCS_SENDER',
  };

  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();
    });
  });

  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);
    });
  });

  describe('Text Preview Content', () => {
    it('should render templateHeader as title', () => {
      const props = {
        ...defaultProps,
        content: {
          templateHeader: 'RCS Title',
          templateMessage: 'RCS Description',
        },
      };

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

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

    it('should render templateMessage as description', () => {
      const props = {
        ...defaultProps,
        content: {
          templateHeader: 'RCS Title',
          templateMessage: 'RCS Description',
        },
      };

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

      expect(screen.getByText('RCS Description')).toBeTruthy();
    });

    it('should use rcsTitle as fallback for templateHeader', () => {
      const props = {
        ...defaultProps,
        content: {
          rcsTitle: 'Fallback Title',
          templateMessage: 'Description',
        },
      };

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

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

    it('should use rcsDesc as fallback for templateMessage', () => {
      const props = {
        ...defaultProps,
        content: {
          templateHeader: 'Title',
          rcsDesc: 'Fallback Description',
        },
      };

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

      expect(screen.getByText('Fallback Description')).toBeTruthy();
    });

    it('should render divider after title', () => {
      const props = {
        ...defaultProps,
        content: {
          templateHeader: 'Title',
          templateMessage: 'Description',
        },
      };

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

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

    it('should not render title when templateHeader and rcsTitle are missing', () => {
      const props = {
        ...defaultProps,
        content: {
          templateMessage: 'Description',
        },
      };

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

      expect(screen.queryByText(/Title/)).toBeFalsy();
    });
  });

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

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

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

    it('should render video preview when rcsVideoSrc is present', () => {
      const props = {
        ...defaultProps,
        content: {
          rcsVideoSrc: 'https://video.url',
          rcsThumbnailSrc: 'https://thumbnail.url',
        },
      };

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

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

    it('should use rcsVideoSrc as thumbnail when rcsThumbnailSrc is not provided', () => {
      const props = {
        ...defaultProps,
        content: {
          rcsVideoSrc: 'https://video.url',
        },
      };

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

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

    it('should render text content after media', () => {
      const props = {
        ...defaultProps,
        content: {
          rcsImageSrc: 'https://image.url',
          templateHeader: 'Title',
          templateMessage: 'Description',
        },
      };

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

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

  describe('RCS Suggestions', () => {
    it('should render QUICK_REPLY suggestion', () => {
      const props = {
        ...defaultProps,
        content: {
          templateHeader: 'Title',
          templateMessage: 'Description',
          suggestions: [
            { type: 'QUICK_REPLY', text: 'Yes' },
          ],
        },
      };

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

    it('should render CTA suggestion', () => {
      const props = {
        ...defaultProps,
        content: {
          templateHeader: 'Title',
          templateMessage: 'Description',
          suggestions: [
            { type: 'CTA', text: 'Visit Website' },
          ],
        },
      };

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

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

    it('should render PHONE_NUMBER suggestion', () => {
      const props = {
        ...defaultProps,
        content: {
          templateHeader: 'Title',
          templateMessage: 'Description',
          suggestions: [
            { type: 'PHONE_NUMBER', text: 'Call Us' },
          ],
        },
      };

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

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

    it('should render multiple suggestions', () => {
      const props = {
        ...defaultProps,
        content: {
          templateHeader: 'Title',
          templateMessage: 'Description',
          suggestions: [
            { type: 'QUICK_REPLY', text: 'Yes' },
            { type: 'CTA', text: 'Visit' },
            { type: 'PHONE_NUMBER', text: 'Call' },
          ],
        },
      };

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

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

    it('should render dividers between suggestions', () => {
      const props = {
        ...defaultProps,
        content: {
          templateHeader: 'Title',
          templateMessage: 'Description',
          suggestions: [
            { type: 'QUICK_REPLY', text: 'Yes' },
            { type: 'CTA', text: 'Visit' },
          ],
        },
      };

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

      const dividers = container.querySelectorAll('.whatsapp-divider');
      expect(dividers.length).toBeGreaterThan(0);
    });

    it('should not render suggestions when array is empty', () => {
      const props = {
        ...defaultProps,
        content: {
          templateHeader: 'Title',
          templateMessage: 'Description',
          suggestions: [],
        },
      };

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

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

    it('should handle suggestion without text', () => {
      const props = {
        ...defaultProps,
        content: {
          templateHeader: 'Title',
          templateMessage: 'Description',
          suggestions: [
            { type: 'QUICK_REPLY', text: null },
          ],
        },
      };

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

      // Should not crash
      expect(screen.getByText('Title')).toBeTruthy();
    });
  });

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

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

      expect(container.querySelector('.sms-device-image')).toBeTruthy();
    });

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

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

      expect(container.querySelector('.sms-device-image')).toBeTruthy();
    });
  });

  describe('Sender ID', () => {
    it('should display sender ID', () => {
      const props = {
        ...defaultProps,
        senderId: 'MY_SENDER_ID',
      };

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

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

    it('should display default sender ID when not provided', () => {
      const props = {
        ...defaultProps,
        senderId: null,
      };

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

      expect(screen.getByText('Sender ID')).toBeTruthy();
    });
  });

  describe('Timestamp', () => {
    it('should display timestamp', () => {
      render(
        <TestWrapper>
          <ComponentToRender {...defaultProps} />
        </TestWrapper>
      );

      // Timestamp format: "H:MM AM/PM"
      const timestamp = screen.getByText(/\d{1,2}:\d{2} (AM|PM)/);
      expect(timestamp).toBeTruthy();
    });
  });

  describe('Edge Cases', () => {
    it('should handle content with both image and video', () => {
      const props = {
        ...defaultProps,
        content: {
          rcsImageSrc: 'https://image.url',
          rcsVideoSrc: 'https://video.url',
        },
      };

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

      // Should prioritize video when both are present
      expect(container.querySelector('.video-preview')).toBeTruthy();
    });

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

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

      // Should render structure
      expect(screen.getByText('Today')).toBeTruthy();
    });

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

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

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

    it('should handle suggestion with unknown type', () => {
      const props = {
        ...defaultProps,
        content: {
          templateHeader: 'Title',
          templateMessage: 'Description',
          suggestions: [
            { type: 'UNKNOWN_TYPE', text: 'Unknown' },
          ],
        },
      };

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

      // Should not crash, but may not render the suggestion
      expect(screen.getByText('Title')).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('Today')).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();
    });
  });
});
