import * as React from 'react';
import { shallow, ShallowWrapper } from 'enzyme';
import expect from 'expect';
import { FormattedMessage } from 'react-intl';

import { createTestEvents } from 'mtest/chat/helpers/chatObjects';

import { ChatEvent } from 'mweb/chat/events/baseChatEvent';
import ChatPane from 'mweb/chat/components/chatPane';
import { ChatEmbedOptions } from 'mweb/chat/chatReducer';

describe('<ChatPane/>', () => {
  const EVENT_COUNT = 100;
  const testEventList = createTestEvents(EVENT_COUNT);

  function subject(
    chatMessages: ChatEvent[] = testEventList,
    chatEmbedOptions?: ChatEmbedOptions,
  ): ShallowWrapper<{}, {}> {
    return shallow(
      <ChatPane
        chatMessages={chatMessages}
        chatEmbedOptions={chatEmbedOptions}
      />,
    );
  }

  it('renders the basic component without messages or more messages button', () => {
    const chatPane = subject([]);
    expect(chatPane.hasClass('chat-pane')).toEqual(true);
    expect(chatPane.hasClass('chat-pane--embed')).toEqual(false);
    expect(chatPane.hasClass('te-embed-mw')).toEqual(false);
    expect(chatPane.state('autoscroll')).toEqual(true);
    expect((chatPane.instance() as ChatPane).userScroll).toEqual(true);

    const chatList = chatPane.childAt(0);
    expect(chatList.hasClass('chat-pane__chat-list')).toEqual(true);
    expect(chatList.children().length).toEqual(0);

    expect(chatPane.children().length).toEqual(1);
  });

  it('renders the component with messages', () => {
    const chatPane = subject();
    expect(chatPane.state('autoscroll')).toEqual(true);

    const chatList = chatPane.children();
    expect(chatList.children().length).toEqual(EVENT_COUNT);
  });

  it('shows more messages button on state change', () => {
    const chatPane = subject();
    expect(chatPane.state('autoscroll')).toEqual(true);
    expect(chatPane.children().length).toEqual(1);

    chatPane.setState({ autoscroll: false });

    expect(chatPane.children().length).toEqual(2);
    const moreMessages = chatPane.childAt(1);
    expect(moreMessages.hasClass('chat-pane__more-messages')).toEqual(true);

    const moreMessagesText = moreMessages.children();
    expect(moreMessagesText.type()).toEqual(FormattedMessage);
    expect(moreMessagesText.prop('id')).toEqual('chat--more-messages');
  });

  it('adds te-embed-mw class when in basic embed mode without other classes', () => {
    const chatPane = subject(testEventList, {});
    expect(chatPane.hasClass('chat-pane')).toEqual(true);
    expect(chatPane.hasClass('chat-pane--embed')).toEqual(true);
    expect(chatPane.hasClass('te-embed-mw')).toEqual(true);
    expect(chatPane.hasClass('te-embed-mw--fmedium')).toEqual(false);
    expect(chatPane.hasClass('te-embed-mw--flarge')).toEqual(false);
    expect(chatPane.hasClass('theme--dark')).toEqual(false);
  });

  it('adds theme--dark class when in theme set to dark', () => {
    const chatPane = subject(testEventList, { theme: 'dark' });
    expect(chatPane.hasClass('chat-pane')).toEqual(true);
    expect(chatPane.hasClass('chat-pane--embed')).toEqual(true);
    expect(chatPane.hasClass('te-embed-mw')).toEqual(true);
    expect(chatPane.hasClass('te-embed-mw--fmedium')).toEqual(false);
    expect(chatPane.hasClass('te-embed-mw--flarge')).toEqual(false);
    expect(chatPane.hasClass('theme--dark')).toEqual(true);
  });

  it('adds te-embed-mw--fmedium class when in fontSize set to medium', () => {
    const chatPane = subject(testEventList, { fontSize: 'medium' });
    expect(chatPane.hasClass('chat-pane')).toEqual(true);
    expect(chatPane.hasClass('chat-pane--embed')).toEqual(true);
    expect(chatPane.hasClass('te-embed-mw')).toEqual(true);
    expect(chatPane.hasClass('te-embed-mw--fmedium')).toEqual(true);
    expect(chatPane.hasClass('te-embed-mw--flarge')).toEqual(false);
    expect(chatPane.hasClass('theme--dark')).toEqual(false);
  });

  it('adds te-embed-mw--flarge class when in fontSize set to large', () => {
    const chatPane = subject(testEventList, { fontSize: 'large' });
    expect(chatPane.hasClass('chat-pane')).toEqual(true);
    expect(chatPane.hasClass('chat-pane--embed')).toEqual(true);
    expect(chatPane.hasClass('te-embed-mw')).toEqual(true);
    expect(chatPane.hasClass('te-embed-mw--fmedium')).toEqual(false);
    expect(chatPane.hasClass('te-embed-mw--flarge')).toEqual(true);
    expect(chatPane.hasClass('theme--dark')).toEqual(false);
  });

  it('adds both theme and fontSize classes', () => {
    const chatPane = subject(testEventList, {
      theme: 'dark',
      fontSize: 'large',
    });
    expect(chatPane.hasClass('chat-pane')).toEqual(true);
    expect(chatPane.hasClass('chat-pane--embed')).toEqual(true);
    expect(chatPane.hasClass('te-embed-mw')).toEqual(true);
    expect(chatPane.hasClass('te-embed-mw--fmedium')).toEqual(false);
    expect(chatPane.hasClass('te-embed-mw--flarge')).toEqual(true);
    expect(chatPane.hasClass('theme--dark')).toEqual(true);
  });

  it('does not respond to unknown theme or fontSize options', () => {
    const chatPane = subject(testEventList, {
      theme: 'red',
      fontSize: 'heavy',
    });
    expect(chatPane.hasClass('chat-pane')).toEqual(true);
    expect(chatPane.hasClass('chat-pane--embed')).toEqual(true);
    expect(chatPane.hasClass('te-embed-mw')).toEqual(true);
    expect(chatPane.hasClass('te-embed-mw--fmedium')).toEqual(false);
    expect(chatPane.hasClass('te-embed-mw--flarge')).toEqual(false);
    expect(chatPane.hasClass('theme--dark')).toEqual(false);
  });

  it('shows more messages in response to scroll event');
  it('hides more messages appropriately');
  it('goes through automated scrollToBottom functionality');
});
