import React, { useState, useEffect, useRef } from 'react';
import classNames from 'classnames/bind';
import ModuleButton from 'components/items/ModuleButton';
import CustomIcon from 'components/items/CustomIcon';
import MessageForm from 'components/forms/MessageForm';
import { Form } from 'react-final-form';
import ManageRoom from 'components/items/ManageRoom';
import moment from 'moment';
import { detectLinkInText } from 'store/utils/helper';
import styleIdentifiers from './detail.scss';

const styles = classNames.bind(styleIdentifiers);

export interface StateProps {}

export interface DispatchProps {}

export interface OwnProps {}

export type DetailProps = StateProps & DispatchProps & OwnProps;

const Detail = (props: DetailProps) => {
  const {
    getRoom,
    getMessage,
    createMessage,
    cleanMessageRoom,
    roomSeen,
    room,
    message,
    profile,
    dialogShow,
    match: { params },
  } = props;

  const formRef = useRef(null);
  const messageContainerRef = useRef(null);
  const [formHeight, setFromHeight] = useState(null);
  const [loadingMessage, setLoadingMessage] = useState(false);

  const [messageList, _setMessageList] = React.useState([]);
  const messageListRef = useRef(messageList);

  function setMessageList(data) {
    messageListRef.current = data;
    _setMessageList(data);
  }

  useEffect(() => {
    getRoom({ id: params.id });
    getMessage({
      id: params.id,
      pagination: { sort: 'createdAt desc', skip: 0, limit: 50 },
    });
    return () => cleanMessageRoom();
  }, [params.id]);

  useEffect(() => {
    if (formRef && formRef.current) {
      setFromHeight(formRef.current.clientHeight);
    }
  }, [formRef]);

  useEffect(() => {
    if (room && room.data) {
      const unread = room.data.stats.unreadCounts.filter(e => e.accountId === profile.data._id);
      if (unread && unread[0] && unread[0].count !== 0) {
        roomSeen({ id: room.data._id });
      }
    }
  }, [room]);

  function managePeople() {
    dialogShow({
      id: 'custom',
      children: <ManageRoom profile={profile && profile.data} room={room && room.data} />,
    });
  }

  function renderRoomName(item) {
    if (item.getAccounts && profile.data) {
      const people = item.getAccounts.filter(e => e._id !== profile.data._id);
      if (people.length !== 0) {
        return (
          <div className={styles('room-item')}>
            {people.map((el, key) => (
              <span key={key}>
                {key !== 0 && ', '}
                {el.userName}
              </span>
            ))}
          </div>
        );
      }
    }
    return <div>Unknow</div>;
  }

  function handleSubmitForm(val, form) {
    const id = room && room.data && room.data._id;
    if (id) {
      messageContainerRef.current.scrollTop = messageContainerRef.current.scrollHeight;
      createMessage({
        data: {
          ...val.message,
          roomId: id,
        },
        callback: () => {
          form.reset();
          form.resetFieldState('message');
        },
      });
    }
  }

  function sendByMe(item) {
    if (item && item.sentBy) {
      const me = item.sentBy === profile.data._id;
      return me;
    }
    return false;
  }

  function getSendUser(item) {
    if (item && item.sentBy && room && room.data && room.data.getAccounts) {
      const user = room.data.getAccounts.find(e => e._id === item.sentBy);
      if (user) return user;
    }
    return 'Unknown';
  }

  function previousMessageSendByMe(item, index) {
    if (message && message.data) {
      const nextMessage = message.data[index + 1];
      if (nextMessage && item.sentBy === nextMessage.sentBy) return true;
    }
    return false;
  }

  function loadMoreData() {
    const result = messageListRef.current;
    if (result && result.hasMore) {
      setLoadingMessage(true);
    }
  }

  function handleScroll(e) {
    if (e.target.scrollTop <= 200 && !loadingMessage) {
      loadMoreData();
    }
  }

  function renderFileMessage(item) {
    const fileName = item.small || item.medium || item.large || null;
    if (fileName) {
      const extension = fileName.split('.').pop();
      if (extension === 'pdf') {
        return (
          <div className={styles('pdf-message')}>
            <a href={fileName} target="_blank" rel="noopener noreferrer">
              {fileName}
            </a>
          </div>
        );
      }
      return (
        <div className={styles('image-message')}>
          <img src={fileName} alt={fileName} />
        </div>
      );
    }
    return false;
  }

  function renderReadBy(item) {
    const roomUser = room && room.data && room.data.getAccounts;
    const views = [];

    if (item.readBy && roomUser) {
      for (let index = 0; index < item.readBy.length; index++) {
        const element = item.readBy[index];
        const viewBy = roomUser.find(e => e._id === element.accountId);
        if (viewBy) {
          views.push({
            userName: viewBy.userName || 'unknown',
            date: element.readAt,
          });
        }
      }
    }

    if (views.length !== 0) {
      return (
        <div className={styles('views-by')}>
          {views.map((elem, key) => (
            <div key={key}>
              {key !== 0 ? ', ' : 'Seen by '}
              <span>{elem.userName}</span>
              {views.length === 1 &&
                `, ${moment(elem.date)
                  .locale('en')
                  .fromNow()}`}
            </div>
          ))}
        </div>
      );
    }

    return false;
  }

  function renderDate(item, prev) {
    const date = moment(item.createdAt).format('DD - MM - YYYY');
    if (prev) {
      const prevDate = moment(prev.createdAt).format('DD - MM - YYYY');
      if (prevDate === date) return false;
    }

    return (
      <div className={styles('message-date')}>
        <div className={styles('line')} />
        <div className={styles('date')}>
          {moment(item.createdAt)
            .locale('en')
            .format('DD MMMM YYYY')}
        </div>
        <div className={styles('line')} />
      </div>
    );
  }

  useEffect(() => {
    if (loadingMessage) {
      getMessage({
        id: params.id,
        pagination: { sort: 'createdAt desc', skip: message.data.length, limit: 50 },
        callback: () => setLoadingMessage(false),
        noLoading: true,
      });
    }
  }, [loadingMessage]);

  useEffect(() => {
    if (messageContainerRef && messageContainerRef.current) {
      messageContainerRef.current.addEventListener('scroll', e => handleScroll(e));
    }
    return messageContainerRef.current.removeEventListener('scroll', e => handleScroll(e));
  }, [messageContainerRef]);

  useEffect(() => {
    setMessageList(message);
  }, [message]);

  return (
    <div
      className={styles('Detail', 'header')}
      style={
        formHeight && {
          paddingBottom: `${(formRef && formRef.current && formRef.current.clientHeight) || 0}px`,
        }
      }
    >
      <div className={styles('header')}>
        <h1>{room && room.data && renderRoomName(room.data)}</h1>
        <div className={styles('actions')}>
          <ModuleButton noMargin relative label="Manage People" action={managePeople} />
        </div>
      </div>

      <div className={styles('display-message')} ref={messageContainerRef}>
        {message &&
          message.data &&
          message.data.map((item, key) => (
            <div key={key} className={styles('message-container')}>
              {renderDate(item, message.data[key + 1])}
              <div
                className={styles(
                  'message-container-item',
                  sendByMe(item) && 'me',
                  previousMessageSendByMe(item, key) && 'prev-me',
                )}
              >
                {!previousMessageSendByMe(item, key) && (
                  <div
                    className={styles('message-picture')}
                    style={{
                      backgroundImage: `url(${getSendUser(item) &&
                        getSendUser(item).profilePicture &&
                        (getSendUser(item).profilePicture.small ||
                          getSendUser(item).profilePicture.medium ||
                          getSendUser(item).profilePicture.large)})`,
                    }}
                  >
                    {(!getSendUser(item) ||
                      (getSendUser(item) && !getSendUser(item).profilePicture)) && (
                      <CustomIcon icon="user" className={styles('circle')} />
                    )}
                  </div>
                )}
                <div className={styles('message-item')}>
                  {!previousMessageSendByMe(item, key) && (
                    <div className={styles('message-name')}>
                      {getSendUser(item) && getSendUser(item).userName}
                    </div>
                  )}
                  {detectLinkInText(item.message).map((text, keyText) => {
                    if (text.type === 'link')
                      return (
                        <a key={keyText} target="_blank" rel="noopener noreferrer" href={text.text}>
                          {text.text}
                        </a>
                      );
                    return <span key={keyText}>{text.text}</span>;
                  })}
                  {item.file && renderFileMessage(item.file)}
                </div>
              </div>
              {key === 0 && sendByMe(item) && renderReadBy(item)}
            </div>
          ))}
      </div>

      <Form
        component={MessageForm}
        forwardRef={formRef}
        onSubmit={handleSubmitForm}
        className={styles('form')}
      />
    </div>
  );
};

export default Detail;
