/**
 * Tests for ViberPreviewContent Component
 * 
 * Tests Viber 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 ViberPreviewContent from '../../UnifiedPreview/ViberPreviewContent';
import { ANDROID, IOS } from '../../constants';
import messages from '../../messages';

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

describe('ViberPreviewContent', () => {
  const defaultProps = {
    content: {
      viberPreviewContent: {
        messageContent: 'Viber message text',
        imageURL: '',
        videoParams: {},
        buttonText: '',
      },
    },
    device: ANDROID,
    isUpdating: false,
    error: null,
    formatMessage: jest.fn((msg) => msg.defaultMessage || msg.id),
    accountName: 'Viber Account',
    brandName: 'Brand Name',
  };

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

  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 Content', () => {
    it('should render message content', () => {
      const props = {
        ...defaultProps,
        content: {
          viberPreviewContent: {
            messageContent: 'Hello, this is a Viber message',
          },
        },
      };

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

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

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

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

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

  describe('Video Content', () => {
    it('should render video preview when videoParams.viberVideoSrc is present', () => {
      const props = {
        ...defaultProps,
        content: {
          viberPreviewContent: {
            messageContent: 'Message',
            videoParams: {
              viberVideoSrc: 'https://video.url',
              viberVideoPreviewImg: 'https://preview.url',
            },
          },
        },
      };

      const { container } = render(
        <TestWrapper>
          <ComponentToRender {...props} />
        </TestWrapper>
      );
      expect(container.querySelector('.video-preview')).toBeTruthy();
    });

    it('should use viberVideoSrc as fallback for preview image', () => {
      const props = {
        ...defaultProps,
        content: {
          viberPreviewContent: {
            messageContent: 'Message',
            videoParams: {
              viberVideoSrc: 'https://video.url',
            },
          },
        },
      };

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

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

  describe('Button Content', () => {
    it('should render button when buttonText is present', () => {
      const props = {
        ...defaultProps,
        content: {
          viberPreviewContent: {
            messageContent: 'Message',
            buttonText: 'Click Here',
          },
        },
      };

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

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

  describe('Account and Brand Name', () => {
    it('should use brandName when provided', () => {
      const props = {
        ...defaultProps,
        brandName: 'My Brand',
        accountName: 'My Account',
      };

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

      expect(screen.getByText('My Brand')).toBeTruthy();
    });

    it('should use accountName as fallback when brandName is not provided', () => {
      const props = {
        ...defaultProps,
        brandName: null,
        accountName: 'My Account',
      };

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

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

    it('should use default "Viber" when neither is provided', () => {
      const props = {
        ...defaultProps,
        brandName: null,
        accountName: null,
      };

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

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

    it('should use first letter of account/brand name for icon', () => {
      const props = {
        ...defaultProps,
        brandName: 'Brand',
      };

      const { container } = render(
        <TestWrapper>
          <ComponentToRender {...props} />
        </TestWrapper>
      );
      expect(container.querySelector('.viber-account-icon')).toHaveTextContent('V');
    });

    it('should use "V" as default icon when no account/brand name', () => {
      const props = {
        ...defaultProps,
        brandName: null,
        accountName: null,
      };

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

      expect(container.querySelector('.viber-account-icon')).toHaveTextContent('V');
    });
  });

  describe('Device Handling', () => {
    it('should apply Android-specific classes for ANDROID device', () => {
      const props = {
        ...defaultProps,
        device: ANDROID,
        showHeader: false,
      };

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

      expect(container.querySelector('.viber-content-overlay')).toBeTruthy();
      expect(container.querySelector('.viber-navigation-bar')).toBeTruthy();
    });

    it('should apply iOS-specific classes for IOS device', () => {
      const props = {
        ...defaultProps,
        device: IOS,
      };

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

      expect(container.querySelector('.viber-message-container-ios')).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('No Content State', () => {
    it('should render no content message when hasContent is false', () => {
      const props = {
        ...defaultProps,
        content: {
          viberPreviewContent: {
            messageContent: '',
            imageURL: '',
            videoParams: {},
            buttonText: '',
          },
        },
      };

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

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

  describe('Edge Cases', () => {
    it('should handle content with only messageContent', () => {
      const props = {
        ...defaultProps,
        content: {
          viberPreviewContent: {
            messageContent: 'Text only',
          },
        },
      };

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

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

    it('should handle content with only image', () => {
      const props = {
        ...defaultProps,
        content: {
          viberPreviewContent: {
            imageURL: 'https://image.url',
          },
        },
      };

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

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

    it('should handle content with only video', () => {
      const props = {
        ...defaultProps,
        content: {
          viberPreviewContent: {
            videoParams: {
              viberVideoSrc: 'https://video.url',
            },
          },
        },
      };

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

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

    it('should handle content with only button', () => {
      const props = {
        ...defaultProps,
        content: {
          viberPreviewContent: {
            buttonText: 'Button Text',
          },
        },
      };

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

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

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

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

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

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

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

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

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

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

      expect(screen.getByText('No content available')).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('No content available')).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();
    });
  });
});
