import React, { useEffect, useState, useRef } from 'react';
import { Modal, ModalHeader, ModalBody, Row, Col, Button, ModalFooter } from 'reactstrap';
import { Scrollbar } from 'react-scrollbars-custom';
import TimeAgo from '../common/JKTimeAgo'
import JKProfileAvatar from './JKProfileAvatar';
import { useAuth } from '../../context/UserAuth';
import { useDispatch, useSelector } from 'react-redux';
import { fetchMessagesByReceiverId, postNewMessage } from '../../store/features/textMessagesSlice';
import { isIterableArray } from '../../helpers/utils';
import PropTypes from 'prop-types';

const JKMessageModal = props => {
  const { show, setShow, user } = props;
  const LIMIT = 10;

  const [fetching, setFetching] = useState(false);
  const [offset, setOffset] = useState(0);
  const [newMessage, setNewMessage] = useState('');
  const [messagesArrived, setMessagesArrived] = useState(false);

  const toggle = () => setShow(!show);

  const { currentUser } = useAuth();
  const dispatch = useDispatch();
  const scrollbar = useRef();
  const messageTextBox = useRef();
  const scrolledToBottom = useRef(false);

  const messages = useSelector(state =>
    state.textMessage.messages
      .filter(
        message =>
          (message.senderId === user.id && message.receiverId === window.currentUser.id) ||
          (message.senderId === window.currentUser.id && message.receiverId === user.id)
      )
      .sort((a, b) => {
        return new Date(a.createdAt) - new Date(b.createdAt);
      })
  );

  const fetchMessages = async () => {
    try {
      const options = { userId: user.id, offset: offset, limit: LIMIT };
      setFetching(true);
      await dispatch(fetchMessagesByReceiverId(options)).unwrap();
      if(messages.length < LIMIT){
        goToBottom();
      }
    } catch (err) {
      console.log('ERROR', err);
    } finally {
      setFetching(false);
    }
  };

  const sendMessage = () => {
    let msgData = {
      message: newMessage,
      target_user_id: user.id,
      source_user_id: currentUser.id
    };
    setNewMessage('');

    try {  
      dispatch(postNewMessage(msgData));
    } catch (err) {
      console.log('addNewMessage error', err);
    } finally {
    }
  };

  const handleOnKeyPress = event => {
    if (event.key === 'Enter' || event.key === 'NumpadEnter') {
      event.preventDefault();
      sendMessage();
      event.target.value = '';
    }
  };

  const scrollAtTop = () => {
    return scrollbar.current.scrollTop === 0;
  };

  const goToBottom = () => {
    if (scrollbar && scrollbar.current) {
      scrollbar.current.scrollToBottom();
    }
  };

  useEffect(() => {
    if (show) {
      fetchMessages();
    }
  }, [show]);


  useEffect(() => {
    if (scrollbar && scrollbar.current) {
      if (!fetching && !scrollAtTop()) {
        if (messages[messages.length - 1]['senderId'] !== currentUser.id) {
          if (!scrolledToBottom.current) {
            setMessagesArrived(true);
          } else {
            goToBottom();
          }
        } else {
          goToBottom();
        }
      }
    }
  }, [messages]);

  useEffect(() => {
    if (!messagesArrived) {
      setMessagesArrived(false);
      goToBottom();
    }
  }, [messagesArrived]);

  const handleScrollStop = scrollValues => {
    scrolledToBottom.current = false;
    if (scrollValues.scrollTop === 0) {
      setOffset(prev => prev + 1);
    } else if (scrollValues.scrollTop === scrollValues.scrollHeight - scrollValues.clientHeight) {
      scrolledToBottom.current = true;
      setMessagesArrived(false);
    }
  };

  useEffect(() => {
    if (offset !== 0) {
      fetchMessages();
    }
  }, [offset]);

  return (
    <>
      <Modal isOpen={show} toggle={toggle} data-testid="textMessageModal">
        <ModalHeader toggle={toggle}>Send Message to {user.name}</ModalHeader>
        <ModalBody>
          <Scrollbar
            ref={scrollbar}
            onScrollStop={handleScrollStop}
            style={{ width: '100%', height: 200 }}
            mobileNative={true}
            trackClickBehavior="step"
          >
            { isIterableArray(messages) && 
              messages.map((message, index) => (
                <div className="d-flex mb-3 mr-1 text-message-row" key={message.id}>
                  <div className="avatar avatar-2xl d-inline-block">
                    <JKProfileAvatar
                      url={message.receiverId === currentUser.id ? currentUser.photo_url : user.photo_url}
                    />
                  </div>
                  <div className="d-inline-block">
                    <div className="d-flex flex-column">
                      <div>
                        <strong>{message.senderName}</strong>
                        <time className="notification-time ml-2 t-1">
                          <TimeAgo date={message.createdAt} />
                        </time>
                      </div>
                      <div>{message.message}</div>
                    </div>
                  </div>
                </div>
              ))
            }
          </Scrollbar>
          {messagesArrived && (
            <Row>
              <Col className="d-flex justify-content-center">
                <Button color="info" size="sm" onClick={() => setMessagesArrived(prev => !prev)}>
                  New messages
                </Button>
              </Col>
            </Row>
          )}
          <Row>
            <Col>
              <textarea
                style={{ width: '100%' }}
                value={newMessage}
                onChange={e => setNewMessage(e.target.value)}
                onKeyPress={handleOnKeyPress}
                ref={messageTextBox}
              />
            </Col>
          </Row>
        </ModalBody>

        <ModalFooter>
          <Button onClick={toggle}>Cancel</Button>
          <Button color="primary" onClick={sendMessage} disabled={!newMessage}>
            Send Message
          </Button>
        </ModalFooter>
      </Modal>
    </>
  );
};

JKMessageModal.propTypes = {
  user: PropTypes.object.isRequired,
  show: PropTypes.bool.isRequired,
  setShow: PropTypes.func.isRequired
};

export default JKMessageModal;
