/**
 * Tests for ZaloPreviewContent Component
 * 
 * Tests Zalo preview rendering with external preview link
 */

import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import { injectIntl, IntlProvider } from 'react-intl';
import ZaloPreviewContent from '../../UnifiedPreview/ZaloPreviewContent';
import zaloMessages from '../../../../v2Containers/Zalo/messages';

// Mock handlePreviewInNewTab
// Component imports from '../../../utils/common' (relative to UnifiedPreview/ZaloPreviewContent.js)
// Test file is at: app/v2Components/CommonTestAndPreview/tests/UnifiedPreview/ZaloPreviewContent.test.js
// So we need to mock: ../../../../utils/common
jest.mock('../../../../utils/common', () => ({
  handlePreviewInNewTab: jest.fn(),
}));

// Convert zaloMessages object to format expected by IntlProvider
const zaloMessagesForIntl = Object.keys(zaloMessages).reduce((acc, key) => {
  const message = zaloMessages[key];
  acc[message.id] = message.defaultMessage;
  return acc;
}, {});

// Wrap component with injectIntl - extract formatMessage from intl and pass to component
const ComponentToRender = injectIntl(({ intl, ...props }) => (
  <ZaloPreviewContent {...props} formatMessage={intl.formatMessage} />
));

// Test wrapper - use IntlProvider with messages
const TestWrapper = ({ children }) => (
  <IntlProvider locale="en" messages={zaloMessagesForIntl}>
    {children}
  </IntlProvider>
);

describe('ZaloPreviewContent', () => {
  const defaultProps = {
    content: {
      templatePreviewUrl: 'https://preview.zalo.com/template/123',
    },
    fullMode: true,
    // formatMessage will be injected by injectIntl
  };

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

  describe('Rendering', () => {
    it('should render Zalo preview container', () => {
      const { container } = render(
        <TestWrapper>
          <ComponentToRender {...defaultProps} />
        </TestWrapper>
      );

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

    it('should apply creative mode class when fullMode is true', () => {
      const { container } = render(
        <TestWrapper>
          <ComponentToRender {...defaultProps} fullMode={true} />
        </TestWrapper>
      );

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

    it('should apply campaign mode class when fullMode is false', () => {
      const props = {
        ...defaultProps,
        fullMode: false,
      };

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

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

    it('should render preview head', () => {
      render(
        <TestWrapper>
          <ComponentToRender {...defaultProps} />
        </TestWrapper>
      );

      // Component uses formatMessage with defaultMessage 'Preview'
      expect(screen.getByText('Preview')).toBeTruthy();
    });

    it('should render preview text', () => {
      render(
        <TestWrapper>
          <ComponentToRender {...defaultProps} />
        </TestWrapper>
      );

      // Component uses formatMessage with defaultMessage 'Preview of the template is generated on the Zalo platform. Click on 'Open preview' to view it in a new tab'
      expect(screen.getByText(/Preview of the template is generated on the Zalo platform/i)).toBeTruthy();
    });

    it('should render preview link button', () => {
      render(
        <TestWrapper>
          <ComponentToRender {...defaultProps} />
        </TestWrapper>
      );

      expect(screen.getByText('Open Preview')).toBeTruthy();
    });
  });

  describe('Preview URL Handling', () => {
    it('should extract templatePreviewUrl from content', () => {
      const props = {
        ...defaultProps,
        content: {
          templatePreviewUrl: 'https://preview.zalo.com/template/123',
        },
      };

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

      const linkButton = screen.getByTestId('preview-link-button');
      expect(linkButton).toBeTruthy();
    });

    it('should extract previewUrl from content.template', () => {
      const props = {
        ...defaultProps,
        content: {
          template: {
            previewUrl: 'https://preview.zalo.com/template/456',
          },
        },
      };

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

      const linkButton = screen.getByTestId('preview-link-button');
      expect(linkButton).toBeTruthy();
    });

    it('should prioritize templatePreviewUrl over template.previewUrl', () => {
      const props = {
        ...defaultProps,
        content: {
          templatePreviewUrl: 'https://preview.zalo.com/template/123',
          template: {
            previewUrl: 'https://preview.zalo.com/template/456',
          },
        },
      };

      const { handlePreviewInNewTab } = require('../../../../utils/common');
      render(
        <TestWrapper>
          <ComponentToRender {...props} />
        </TestWrapper>
      );

      const linkButton = screen.getByTestId('preview-link-button');
      fireEvent.click(linkButton);

      expect(handlePreviewInNewTab).toHaveBeenCalledWith('https://preview.zalo.com/template/123');
    });

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

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

      const linkButton = screen.getByTestId('preview-link-button');
      expect(linkButton).toBeTruthy();
    });

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

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

      const linkButton = screen.getByTestId('preview-link-button');
      expect(linkButton).toBeTruthy();
    });

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

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

      const linkButton = screen.getByTestId('preview-link-button');
      expect(linkButton).toBeTruthy();
    });
  });

  describe('Preview Link Click', () => {
    it('should call handlePreviewInNewTab when preview link is clicked', () => {
      const { handlePreviewInNewTab } = require('../../../../utils/common');
      render(
        <TestWrapper>
          <ComponentToRender {...defaultProps} />
        </TestWrapper>
      );

      const linkButton = screen.getByTestId('preview-link-button');
      fireEvent.click(linkButton);

      expect(handlePreviewInNewTab).toHaveBeenCalledWith('https://preview.zalo.com/template/123');
    });

    it('should not call handlePreviewInNewTab when URL is empty', () => {
      const { handlePreviewInNewTab } = require('../../../../utils/common');
      const props = {
        ...defaultProps,
        content: {
          templatePreviewUrl: '',
        },
      };

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

      const linkButton = screen.getByTestId('preview-link-button');
      fireEvent.click(linkButton);

      expect(handlePreviewInNewTab).not.toHaveBeenCalled();
    });

    it('should not call handlePreviewInNewTab when URL is null', () => {
      const { handlePreviewInNewTab } = require('../../../../utils/common');
      const props = {
        ...defaultProps,
        content: {
          templatePreviewUrl: null,
        },
      };

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

      const linkButton = screen.getByTestId('preview-link-button');
      fireEvent.click(linkButton);

      expect(handlePreviewInNewTab).not.toHaveBeenCalled();
    });
  });

  describe('Full Mode', () => {
    it('should default to fullMode=true', () => {
      const props = {
        content: {},
        formatMessage: jest.fn((msg) => msg.defaultMessage || msg.id),
      };

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

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

    it('should use fullMode prop when provided', () => {
      const props = {
        ...defaultProps,
        fullMode: false,
      };

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

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

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

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

      expect(screen.getByText('Open Preview')).toBeTruthy();
    });

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

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

      expect(screen.getByText('Open Preview')).toBeTruthy();
    });

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

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

      expect(screen.getByText('Open Preview')).toBeTruthy();
    });

    it('should handle content with only template object', () => {
      const props = {
        ...defaultProps,
        content: {
          template: {
            previewUrl: 'https://preview.zalo.com/template/789',
          },
        },
      };

      const { handlePreviewInNewTab } = require('../../../../utils/common');
      render(
        <TestWrapper>
          <ComponentToRender {...props} />
        </TestWrapper>
      );

      const linkButton = screen.getByTestId('preview-link-button');
      fireEvent.click(linkButton);

      expect(handlePreviewInNewTab).toHaveBeenCalledWith('https://preview.zalo.com/template/789');
    });

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

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

      expect(screen.getByText('Open Preview')).toBeTruthy();
    });
  });

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

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

      expect(container.querySelector('.zalo-preview-container-creative')).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();
    });
  });
});
