text: import { faLocationArrow } from "@fortawesome/free-solid-svg-icons";
  import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
  import axios from "axios";
  import { useEffect, useMemo, useRef, useState } from "react";
  import { useForm } from "react-hook-form";
  import { useSelector } from "react-redux";
  import useWebSocket, { ReadyState } from 'react-use-websocket';
  import { authHeader } from "../services/auth-header";
  import './Chatroom.css';
  
  
  const ChatRoom = () => {
  
      const { username, token } = useSelector(state => state.authUser);
  
      const messagesEnd = useRef();
      const [currentChatUser, setCurrentChatUser] = useState(null);
      const [currentChatMessages, setCurrentChatMessages] = useState([]);
  
      const violationMessage = 'Server: User has violated server policies and has been disconnected';
  
  
      const websocketUrl = process.env.NODE_ENV === 'development' ? 'ws://localhost:8080/chat' : 'wss://sni-backend.herokuapp.com/chat'
  
      const { sendJsonMessage, lastJsonMessage, readyState } = useWebSocket(websocketUrl, {
          protocols: token,
          onError: (e) => {
              console.log(e);
          },
          onReconnectStop: (e) => {
              console.log(e);
          },
          onClose: (e) => {
              console.log(e);
          }
      });
      const { register, handleSubmit, reset } = useForm();
  
      const [connectedUsers, setConntectedUsers] = useState([])
  
      const messageHistory = useRef({});
  
      messageHistory.current = useMemo(() => {
          if (lastJsonMessage != null && (lastJsonMessage.messageType === 'STANDARD' || lastJsonMessage.messageType === 'ABUSE')) {
              const senderId = lastJsonMessage.messageType === 'STANDARD' ? lastJsonMessage.senderId : lastJsonMessage.message;
              if (currentChatUser == null || currentChatUser.id !== senderId) {
                  let messages = messageHistory.current[senderId];
                  messages = messages == null ? [] : messages;
                  return {
                      ...messageHistory.current,
                      [senderId]: [...messages, lastJsonMessage]
                  }
              }
          }
          return messageHistory.current;
      }, [lastJsonMessage]);
  
  
      useEffect(() => {
          if (lastJsonMessage != null) {
              if (lastJsonMessage.messageType === 'CONNECTION') {
                  const newUser = JSON.parse(lastJsonMessage.message);
                  if (newUser.id !== username && !connectedUsers.some(u => u.id === newUser.id)) {
                      setConntectedUsers(users => [...users, newUser]);
                  }
              }
  
              if (lastJsonMessage.messageType === 'DISCONNECTION' || lastJsonMessage.messageType === 'ABUSE') {
                  setConntectedUsers(users => users.filter(u => u.id !== lastJsonMessage.message));
              }
          } else {
              axios.get('/api/connected', { headers: authHeader(token) }).then(response => {
                  setConntectedUsers(users => [...users, ...response.data.filter(u => u.id !== username)])
              });
          }
      }, [lastJsonMessage]);
  
      useEffect(() => {
          if (currentChatUser != null && lastJsonMessage && (lastJsonMessage.messageType === 'STANDARD' || lastJsonMessage.messageType === 'ABUSE')) {
              const senderId = lastJsonMessage.messageType === 'STANDARD' ? lastJsonMessage.senderId : lastJsonMessage.message;
              if (senderId === currentChatUser.id) {
                  setCurrentChatMessages(messages => [...messages, lastJsonMessage]);
              }
          }
      }, [lastJsonMessage]);
  
  
      const buildMessage = (content) => {
          return {
              senderId: username,
              receiverId: currentChatUser.id,
              messageType: 'STANDARD',
              message: content,
              timestamp: Date.now()
          }
      };
  
  
      const changeCurrentChat = (user) => {
          if (currentChatUser != null) {
              messageHistory.current[currentChatUser.id] = currentChatMessages;
          }
          setCurrentChatUser(user);
          const messages = messageHistory.current[user.id] == null ? [] : messageHistory.current[user.id];
          setCurrentChatMessages(messages)
      }
  
      const onClickSendMessage = (data) => {
          const newMessage = buildMessage(data.message);
          reset();
          setCurrentChatMessages(messages => [...messages, newMessage]);
          sendJsonMessage(newMessage);
      }
  
  
      useEffect(() => {
          messagesEnd.current.scrollIntoView({ behavior: 'smooth' });
      }, [currentChatMessages]);
  
  
      return (
          <div>
              <div className="container-fluid h-100">
                  <div className="row justify-content-center h-100">
                      <div className="col-md-5 col-xl-4 chat">
                          <div className="card mb-sm-3 mb-md-0 contacts_card">
                              <div className="card-body contacts_body">
                                  <ul className="contacts">
                                      {
                                          connectedUsers.map(user => {
  
                                              return (
                                                  <li className="active" onClick={_ => changeCurrentChat(user)} key={user.id}>
                                                      <div className="d-flex bd-highlight">
                                                          <div className="user_info">
                                                              <span>{user.displayName}</span>
                                                              <p>{user.displayName} is online</p>
                                                          </div>
                                                      </div>
                                                  </li>
                                              );
                                          })
                                      }
                                  </ul>
                              </div>
                              <div className="card-footer"></div>
                          </div>
                      </div>
                      <div className="col-md-10 col-xl-8 chat">
                          <div className="card">
                              <div className="card-header msg_head">
                                  <div className="d-flex bd-highlight">
                                      {currentChatUser != null && (
                                          <div className="user_info">
                                              <span>Chat with {currentChatUser.displayName}</span>
                                          </div>
  
                                      )}
                                  </div>
                              </div>
                              <div className="card-body msg_card_body">
                                  {currentChatUser != null && currentChatMessages.map(message => {
                                      const msgClass = username === message.senderId ? "d-flex justify-content-end mb-4" : "d-flex justify-content-start mb-4"
                                      const cotainerClass = username === message.senderId ? "msg_cotainer" : "msg_cotainer_other"
                                      return (
                                          <div className={msgClass} key={message.timestamp}>
                                              <div className={cotainerClass}>
                                                  {message.messageType === 'ABUSE' ? violationMessage : message.message}
                                                  <span className="msg_time">{new Date(message.timestamp).toUTCString()}</span>
                                              </div>
                                          </div>
                                      )
                                  })}
                                  <span ref={messagesEnd}></span>
                              </div>
                              <div className="card-footer">
                                  <form onSubmit={handleSubmit(onClickSendMessage)}>
                                      <div className="input-group">
                                          <input
                                              className="form-control type_msg"
                                              {...register("message", { required: true })} />
                                          <button
                                              type="submit" className="input-group-text send_btn"
                                              disabled={readyState !== ReadyState.OPEN || currentChatUser == null || !connectedUsers.includes(currentChatUser)}
                                          >
                                              <FontAwesomeIcon icon={faLocationArrow} />
                                          </button>
                                      </div>
                                  </form>
                              </div>
                          </div>
                      </div>
                  </div>
              </div>
  
          </div>
      )
  }
  
  
  
  export default ChatRoom;