import React from 'react';

import { ConversationListItemWithDetails } from '../ConversationListItem';
import { RowRendererParamsType } from '../LeftPane';
import {
  SessionButton,
  SessionButtonColor,
  SessionButtonType,
} from './SessionButton';
import { AutoSizer, List } from 'react-virtualized';
import { ConversationType } from '../../state/ducks/conversations';
import {
  SessionClosableOverlay,
  SessionClosableOverlayType,
} from './SessionClosableOverlay';
import { ToastUtils } from '../../session/utils';
import { DefaultTheme } from 'styled-components';
import { LeftPaneSectionHeader } from './LeftPaneSectionHeader';
import { ConversationController } from '../../session/conversations';
import { PubKey } from '../../session/types';

export interface Props {
  directContacts: Array<ConversationType>;
  theme: DefaultTheme;
  openConversationExternal: (id: string, messageId?: string) => void;
}

interface State {
  showAddContactView: boolean;
  addContactRecipientID: string;
  pubKeyPasted: string;
}

export class LeftPaneContactSection extends React.Component<Props, State> {
  public constructor(props: Props) {
    super(props);
    this.state = {
      showAddContactView: false,
      addContactRecipientID: '',
      pubKeyPasted: '',
    };

    this.handleToggleOverlay = this.handleToggleOverlay.bind(this);
    this.handleOnAddContact = this.handleOnAddContact.bind(this);
    this.handleRecipientSessionIDChanged = this.handleRecipientSessionIDChanged.bind(
      this
    );
    this.closeOverlay = this.closeOverlay.bind(this);
  }

  public componentDidMount() {
    window.Whisper.events.on('calculatingPoW', this.closeOverlay);
  }

  public componentWillUnmount() {
    this.setState({ addContactRecipientID: '' });
    window.Whisper.events.off('calculatingPoW', this.closeOverlay);
  }

  public renderHeader(): JSX.Element | undefined {
    return (
      <LeftPaneSectionHeader
        label={window.i18n('contactsHeader')}
        theme={this.props.theme}
      />
    );
  }

  public render(): JSX.Element {
    return (
      <div className="left-pane-contact-section">
        {this.renderHeader()}
        {this.state.showAddContactView
          ? this.renderClosableOverlay()
          : this.renderContacts()}
      </div>
    );
  }

  public renderRow = ({
    index,
    key,
    style,
  }: RowRendererParamsType): JSX.Element | undefined => {
    const { directContacts } = this.props;
    const item = directContacts[index];

    return (
      <ConversationListItemWithDetails
        key={item.id}
        style={style}
        {...item}
        i18n={window.i18n}
        onClick={this.props.openConversationExternal}
      />
    );
  };

  private renderClosableOverlay() {
    return (
      <SessionClosableOverlay
        overlayMode={SessionClosableOverlayType.Contact}
        onChangeSessionID={this.handleRecipientSessionIDChanged}
        onCloseClick={this.handleToggleOverlay}
        onButtonClick={this.handleOnAddContact}
        theme={this.props.theme}
      />
    );
  }

  private closeOverlay({ pubKey }: { pubKey: string }) {
    if (this.state.addContactRecipientID === pubKey) {
      this.setState({ showAddContactView: false, addContactRecipientID: '' });
    }
  }

  private handleToggleOverlay() {
    this.setState((prevState: { showAddContactView: boolean }) => ({
      showAddContactView: !prevState.showAddContactView,
    }));
  }

  private handleOnAddContact() {
    const sessionID = this.state.addContactRecipientID.trim();
    const error = PubKey.validateWithError(sessionID, window.i18n);

    if (error) {
      ToastUtils.pushToastError('addContact', error);
    } else {
      void ConversationController.getInstance()
        .getOrCreateAndWait(sessionID, 'private')
        .then(() => {
          this.props.openConversationExternal(sessionID);
        });
    }
  }

  private handleRecipientSessionIDChanged(value: string) {
    this.setState({ addContactRecipientID: value });
  }

  private renderContacts() {
    return (
      <div className="left-pane-contact-content">
        {this.renderList()}
        {this.renderBottomButtons()}
      </div>
    );
  }

  private renderBottomButtons(): JSX.Element {
    const addContact = window.i18n('addContact');

    return (
      <div className="left-pane-contact-bottom-buttons">
        <SessionButton
          text={addContact}
          buttonType={SessionButtonType.SquareOutline}
          buttonColor={SessionButtonColor.Green}
          onClick={this.handleToggleOverlay}
        />
      </div>
    );
  }

  private renderList() {
    const { directContacts } = this.props;
    const length = Number(directContacts.length);

    const list = (
      <div className="module-left-pane__list" key={0}>
        <AutoSizer>
          {({ height, width }) => (
            <List
              className="module-left-pane__virtual-list"
              height={height}
              directContacts={directContacts} // needed for change in props refresh
              rowCount={length}
              rowHeight={64}
              rowRenderer={this.renderRow}
              width={width}
              autoHeight={false}
            />
          )}
        </AutoSizer>
      </div>
    );

    return [list];
  }
}
