import React from 'react';
import { mountWithIntl, shallowWithIntl } from '../../../../helpers/intl-enzym-test-helpers';
import MessageSection from './MessageSection';
import CapInput from '@capillarytech/cap-ui-library/CapInput';
import CapRow from '@capillarytech/cap-ui-library/CapRow';
import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
import CapError from '@capillarytech/cap-ui-library/CapError';
import CapLabel from '@capillarytech/cap-ui-library/CapLabel';
import CapEmojiPicker from '@capillarytech/cap-ui-library/CapEmojiPicker';
import CapDivider from '@capillarytech/cap-ui-library/CapDivider';
import CapAskAira from '@capillarytech/cap-ui-library/CapAskAira';
import { MESSAGE_MAX_LENGTH, SHOW_CHARACTER_COUNT } from '../../constants';

describe('MessageSection', () => {
  const mockFormatMessage = jest.fn((message, values) => {
    if (values) {
      return `${values.currentLength}/${values.maxLength}`;
    }
    return message?.defaultMessage || message?.id || message;
  });
  const mockOnChange = jest.fn();
  const mockHandleMessageTextAreaRef = jest.fn();

  const mockMessages = {
    message: {
      id: 'app.webpush.message',
      defaultMessage: 'Message',
    },
    messagePlaceholder: {
      id: 'app.webpush.messagePlaceholder',
      defaultMessage: 'Enter message',
    },
    characterCount: {
      id: 'app.webpush.characterCount',
      defaultMessage: '{currentLength}/{maxLength}',
    },
  };

  const defaultProps = {
    value: 'Test Message',
    error: '',
    onChange: mockOnChange,
    formatMessage: mockFormatMessage,
    messages: mockMessages,
    tagList: null,
    messageCountRef: null,
    messageTextAreaRef: null,
    handleMessageTextAreaRef: mockHandleMessageTextAreaRef,
    isAiContentBotDisabled: true,
  };

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

  describe('Rendering', () => {
    it('should render correctly with default props', () => {
      const wrapper = shallowWithIntl(<MessageSection {...defaultProps} />);
      expect(wrapper).toMatchSnapshot();
    });

    it('should render main container with correct class', () => {
      const wrapper = mountWithIntl(<MessageSection {...defaultProps} />);
      const container = wrapper.find('.creatives-webpush-message');
      expect(container.exists()).toBe(true);
    });

    it('should render heading', () => {
      const wrapper = mountWithIntl(<MessageSection {...defaultProps} />);
      const heading = wrapper.find(CapHeading).find('.webpush-message');
      expect(heading.exists()).toBe(true);
    });

    it('should render CapEmojiPicker.Wrapper', () => {
      const wrapper = mountWithIntl(<MessageSection {...defaultProps} />);
      const emojiPicker = wrapper.find(CapEmojiPicker.Wrapper);
      expect(emojiPicker.exists()).toBe(true);
      expect(emojiPicker.prop('value')).toBe('Test Message');
    });

    it('should not render aiRA button when feature is disabled', () => {
      const wrapper = mountWithIntl(<MessageSection {...defaultProps} />);
      expect(wrapper.find(CapAskAira.ContentGenerationBot).exists()).toBe(false);
    });

    it('should render aiRA button when feature is enabled', () => {
      const wrapper = mountWithIntl(
        <MessageSection {...defaultProps} isAiContentBotDisabled={false} />
      );
      const airaBot = wrapper.find(CapAskAira.ContentGenerationBot);
      expect(airaBot.exists()).toBe(true);
      expect(airaBot.prop('text')).toBe('Test Message');
      expect(airaBot.prop('rootStyle')).toMatchObject({
        right: '2.5rem',
        left: 'auto',
      });
    });

    it('should render aiRA and emoji controls together', () => {
      const wrapper = mountWithIntl(
        <MessageSection {...defaultProps} isAiContentBotDisabled={false} />
      );
      expect(wrapper.find(CapAskAira.ContentGenerationBot).exists()).toBe(true);
      expect(wrapper.find(CapEmojiPicker.Wrapper).exists()).toBe(true);
    });

    it('should render CapInput.TextArea with correct props', () => {
      const wrapper = mountWithIntl(<MessageSection {...defaultProps} />);
      const textArea = wrapper.find(CapInput.TextArea);
      expect(textArea.exists()).toBe(true);
      expect(textArea.prop('id')).toBe('webpush-message-input');
      expect(textArea.prop('value')).toBe('Test Message');
      expect(textArea.prop('size')).toBe('default');
      expect(textArea.prop('isRequired')).toBe(true);
      expect(textArea.prop('autosize')).toEqual({ minRows: 3, maxRows: 5 });
    });

    it('should render placeholder correctly', () => {
      const wrapper = mountWithIntl(<MessageSection {...defaultProps} />);
      const textArea = wrapper.find(CapInput.TextArea);
      expect(textArea.exists()).toBe(true);
      expect(mockFormatMessage).toHaveBeenCalledWith(mockMessages.messagePlaceholder);
    });

    it('should render Divider', () => {
      const wrapper = mountWithIntl(<MessageSection {...defaultProps} />);
      const divider = wrapper.find(CapDivider).find('.webpush-message-divider');
      expect(divider.exists()).toBe(true);
    });
  });

  describe('Tag List', () => {
    it('should render tagList when provided', () => {
      const tagList = <div className="test-tag-list">Tag List</div>;
      const wrapper = mountWithIntl(
        <MessageSection {...defaultProps} tagList={tagList} />
      );
      const tagListContainer = wrapper.find('.webpush-message-taglist');
      expect(tagListContainer.exists()).toBe(true);
      expect(tagListContainer.contains(tagList)).toBe(true);
    });

    it('should render empty tagList container when tagList prop is not provided', () => {
      const wrapper = mountWithIntl(<MessageSection {...defaultProps} />);
      const tagListContainer = wrapper.find('.webpush-message-taglist');
      expect(tagListContainer.exists()).toBe(true);
      // Check that no tagList content is rendered (CapRow itself may have internal structure)
      expect(tagListContainer.find('.test-tag-list').exists()).toBe(false);
    });
  });

  describe('Error Handling', () => {
    it('should not render error when error is empty', () => {
      const wrapper = mountWithIntl(<MessageSection {...defaultProps} error="" />);
      const error = wrapper.find(CapError);
      expect(error.exists()).toBe(false);
    });

    it('should render error when error is provided', () => {
      const errorMessage = 'Message is required';
      const wrapper = mountWithIntl(
        <MessageSection {...defaultProps} error={errorMessage} />
      );
      const error = wrapper.find(CapError).find('.webpush-template-message-error');
      expect(error.exists()).toBe(true);
    });

    it('should pass error to CapInput.TextArea', () => {
      const errorMessage = 'Message is required';
      const wrapper = mountWithIntl(
        <MessageSection {...defaultProps} error={errorMessage} />
      );
      const textArea = wrapper.find(CapInput.TextArea);
      expect(textArea.prop('errorMessage')).toBeDefined();
    });

    it('should keep aiRA visible and anchored when error is present', () => {
      const errorMessage = 'Message is required';
      const wrapper = mountWithIntl(
        <MessageSection
          {...defaultProps}
          error={errorMessage}
          isAiContentBotDisabled={false}
        />
      );
      const airaBot = wrapper.find(CapAskAira.ContentGenerationBot);
      expect(airaBot.exists()).toBe(true);
      expect(airaBot.prop('rootStyle')).toMatchObject({
        right: '2.5rem',
        left: 'auto',
      });
    });
  });

  describe('Character Count', () => {
    it('should render character count when SHOW_CHARACTER_COUNT is true', () => {
      const messageCountRef = React.createRef();
      const wrapper = mountWithIntl(
        <MessageSection {...defaultProps} messageCountRef={messageCountRef} />
      );
      const characterCount = wrapper.find(CapLabel).find('.webpush-character-count');
      expect(characterCount.exists()).toBe(true);
    });

    it('should display correct character count', () => {
      const messageCountRef = React.createRef();
      const wrapper = mountWithIntl(
        <MessageSection
          {...defaultProps}
          value="Test Message"
          messageCountRef={messageCountRef}
        />
      );
      const characterCount = wrapper.find(CapLabel).find('.webpush-character-count');
      expect(characterCount.exists()).toBe(true);
      expect(mockFormatMessage).toHaveBeenCalledWith(mockMessages.characterCount, {
        currentLength: 12,
        maxLength: MESSAGE_MAX_LENGTH,
      });
    });

    it('should render character count span with ref', () => {
      const messageCountRef = React.createRef();
      const wrapper = mountWithIntl(
        <MessageSection {...defaultProps} messageCountRef={messageCountRef} />
      );
      const characterCount = wrapper.find(CapLabel).find('.webpush-character-count');
      expect(characterCount.exists()).toBe(true);
    });
  });

  describe('TextArea Ref Handling', () => {
    it('should call handleMessageTextAreaRef with setInputRef', () => {
      const wrapper = mountWithIntl(<MessageSection {...defaultProps} />);
      const textArea = wrapper.find(CapInput.TextArea);
      expect(textArea.prop('setInputRef')).toBe(mockHandleMessageTextAreaRef);
    });

    it('should pass messageTextAreaRef to CapEmojiPicker.Wrapper', () => {
      const messageTextAreaRef = React.createRef();
      const wrapper = mountWithIntl(
        <MessageSection {...defaultProps} messageTextAreaRef={messageTextAreaRef} />
      );
      const emojiPicker = wrapper.find(CapEmojiPicker.Wrapper);
      expect(emojiPicker.prop('textAreaRef')).toBe(messageTextAreaRef);
    });
  });

  describe('User Interactions', () => {
    it('should call onChange when textarea value changes', () => {
      const wrapper = mountWithIntl(<MessageSection {...defaultProps} />);
      const textArea = wrapper.find(CapInput.TextArea);
      const event = { target: { value: 'New Message' } };
      textArea.prop('onChange')(event);
      expect(mockOnChange).toHaveBeenCalledWith(event);
    });

    it('should call onChange from CapEmojiPicker.Wrapper', () => {
      const wrapper = mountWithIntl(<MessageSection {...defaultProps} />);
      const emojiPicker = wrapper.find(CapEmojiPicker.Wrapper);
      emojiPicker.prop('onChange')('New Message');
      expect(mockOnChange).toHaveBeenCalledWith('New Message');
    });

    it('should call onChange when aiRA returns generated text', () => {
      const wrapper = mountWithIntl(
        <MessageSection {...defaultProps} isAiContentBotDisabled={false} />
      );
      const airaBot = wrapper.find(CapAskAira.ContentGenerationBot);
      airaBot.prop('setText')('Generated by aiRA');
      expect(mockOnChange).toHaveBeenCalledWith('Generated by aiRA');
    });
  });

  describe('Default Props', () => {
    it('should use default error when not provided', () => {
      const wrapper = mountWithIntl(
        <MessageSection
          value="Test"
          onChange={mockOnChange}
          formatMessage={mockFormatMessage}
          messages={mockMessages}
          handleMessageTextAreaRef={mockHandleMessageTextAreaRef}
        />
      );
      const error = wrapper.find(CapError);
      expect(error.exists()).toBe(false);
    });

    it('should use default tagList when not provided', () => {
      const wrapper = mountWithIntl(
        <MessageSection
          value="Test"
          onChange={mockOnChange}
          formatMessage={mockFormatMessage}
          messages={mockMessages}
          handleMessageTextAreaRef={mockHandleMessageTextAreaRef}
        />
      );
      const tagListContainer = wrapper.find('.webpush-message-taglist');
      expect(tagListContainer.exists()).toBe(true);
    });
  });

  describe('Edge Cases', () => {
    it('should handle empty value', () => {
      const wrapper = mountWithIntl(<MessageSection {...defaultProps} value="" />);
      const textArea = wrapper.find(CapInput.TextArea);
      expect(textArea.prop('value')).toBe('');
    });

    it('should handle long value', () => {
      const longValue = 'A'.repeat(100);
      const wrapper = mountWithIntl(
        <MessageSection {...defaultProps} value={longValue} />
      );
      const textArea = wrapper.find(CapInput.TextArea);
      expect(textArea.prop('value')).toBe(longValue);
    });
  });

  describe('InputWrapper', () => {
    it('should render the wrapper div with correct class', () => {
      const wrapper = mountWithIntl(<MessageSection {...defaultProps} />);
      const inputWrapper = wrapper.find('.webpush-message-input-wrapper');
      expect(inputWrapper.exists()).toBe(true);
    });

    it('should render children inside InputWrapper', () => {
      const wrapper = mountWithIntl(<MessageSection {...defaultProps} />);
      const inputWrapper = wrapper.find('.webpush-message-input-wrapper');
      expect(inputWrapper.find(CapEmojiPicker.Wrapper).exists()).toBe(true);
    });

    it('should not render aiRA bot inside InputWrapper when disabled', () => {
      const wrapper = mountWithIntl(<MessageSection {...defaultProps} isAiContentBotDisabled />);
      const inputWrapper = wrapper.find('.webpush-message-input-wrapper');
      expect(inputWrapper.find(CapAskAira.ContentGenerationBot).exists()).toBe(false);
    });

    it('should render aiRA bot inside InputWrapper when enabled', () => {
      const wrapper = mountWithIntl(
        <MessageSection {...defaultProps} isAiContentBotDisabled={false} />
      );
      const inputWrapper = wrapper.find('.webpush-message-input-wrapper');
      expect(inputWrapper.find(CapAskAira.ContentGenerationBot).exists()).toBe(true);
    });
  });
});

