import * as React from 'react';
import { FormattedMessage } from 'react-intl';

import ChatMessage from 'mweb/chat/components//chatMessage';
import { ChatEmbedOptions } from 'mweb/chat/chatReducer';
import { ChatEvent } from 'mweb/chat/events/baseChatEvent';

if (process.env.BROWSER) {
  require('./chatPane.sass');
}

// for embed functionality
const EMBED_BASE_CLASS = 'te-embed-mw';
const VALID_SIZES = ['medium', 'large'];
const VALID_THEMES = ['dark'];

interface ChatProps {
  chatMessages: ReadonlyArray<ChatEvent>;
  chatEmbedOptions?: ChatEmbedOptions;
}

interface ChatState {
  autoscroll: boolean;
}

const AUTOSCROLL_TRIGGER_ZONE_SIZE = 10;

export default class ChatPane extends React.Component<ChatProps, ChatState> {
  chatList: HTMLUListElement;
  userScroll: boolean;

  constructor(props: ChatProps) {
    super(props);
    this.userScroll = true;
    this.state = {
      autoscroll: true,
    };
  }

  componentDidUpdate(): void {
    if (this.state.autoscroll) {
      this.scrollToBottom();
    }
  }

  handleScroll = (event: React.UIEvent<HTMLUListElement>) => {
    event.stopPropagation();
    // differentiate between user scoll and auto scroll
    if (!this.userScroll) {
      this.userScroll = true;
    } else if (
      this.chatList.scrollTop + this.chatList.clientHeight >=
      this.chatList.scrollHeight - AUTOSCROLL_TRIGGER_ZONE_SIZE
    ) {
      if (!this.state.autoscroll) {
        this.setState({ autoscroll: true });
      }
    } else if (this.state.autoscroll) {
      this.setState({ autoscroll: false });
    }
  };

  moreMessages(): JSX.Element | false {
    return (
      !this.state.autoscroll && (
        <div
          className="chat-pane__more-messages"
          onClick={() =>
            this.setState({ autoscroll: true }, this.scrollToBottom)}
        >
          <FormattedMessage
            id="chat--more-messages"
            defaultMessage="More messages below."
          />
        </div>
      )
    );
  }

  scrollToBottom = () => {
    this.userScroll = false;
    this.chatList.scrollTop = this.chatList.scrollHeight;
  };

  getTopLevelClasses(): string {
    const classes = ['chat-pane'];

    const options = this.props.chatEmbedOptions;
    if (options) {
      classes.push('chat-pane--embed');
      classes.push(EMBED_BASE_CLASS);
      if (options.fontSize && VALID_SIZES.includes(options.fontSize)) {
        classes.push(`${EMBED_BASE_CLASS}--f${options.fontSize}`);
      }
      if (options.theme && VALID_THEMES.includes(options.theme)) {
        classes.push(`theme--${options.theme}`);
      }
    }

    return classes.join(' ');
  }

  render(): JSX.Element {
    return (
      <div className={this.getTopLevelClasses()}>
        <ul
          className="chat-pane__chat-list"
          ref={c => (this.chatList = c as HTMLUListElement)}
          onScroll={this.handleScroll}
        >
          {this.props.chatMessages.map(message => (
            <ChatMessage key={message.id} message={message} />
          ))}
        </ul>
        {this.moreMessages()}
      </div>
    );
  }
}
