import { makeStyles } from "@material-ui/core/styles";
import { useState, useEffect, useCallback, useMemo } from "react";
import { useSelector,useDispatch } from "react-redux";

import ArrowBack from "./ArrowBack";
import SendMessage from "./SendMessage";
import UnpinBar from "./UnpinBar";
import MessageLeftText from './Messages/MessageLeftText'
import MessageLeftImage from './Messages/MessageLeftImage'
import MessageLeftAudio from './Messages/MessageLeftAudio'
import MessageLeftVideo from './Messages/MessageLeftVideo'
import MessageLeftFile from "./Messages/MessageLeftFile";
import MessageRightText from './Messages/MessageRightText'
import MessageRightImage from './Messages/MessageRightImage'
import MessageRightAudio from './Messages/MessageRightAudio'
import MessageRightVideo from './Messages/MessageRightVideo'
import MessageRightFile from "./Messages/MessageRightFile";
import MessageTime from "./Messages/MessageTime";
import AlertInfo from "../../../reusableComponents/AlertInfo";
import { getMessagesMemo } from '../../../../redux/messages/selector'
import { getNumber } from '../../../../redux/authorization/selector'
import { getChat } from '../../../../redux/chat/selector'
import { getScrollChat } from '../../../../redux/control/selector'
import { actionScrollChat } from '../../../../redux/control/action'
import { asyncGetMessagesById } from '../../../../redux/messages/operations'
import { asyncGetChatById } from "../../../../redux/chat/operations";
import { seenChat } from "../../../../api-data";
import { TPinnedMessages } from "../../../../typescript/redux/pinnedMessages/types";
import { timeStampFilter,prodAwsS3,refreshAppTime } from "../../../../helpers";
const debounce = require('lodash.debounce');

const useStyles = makeStyles({   
  container: {
      height: '93vh',
      width: "100%",
      display: "flex",
      alignItems: "center",
      alignContent:"center",
      flexDirection: "column",
      position: "relative",
    },
  messagesScroll: {
      paddingTop: 30,
      overflowY: "scroll",
      maxHeight: '83vh',
      width: "100%",
      display: "flex",
      justifyContent: 'center',
      '&::-webkit-scrollbar': {
        width: '0.4em'
       },
     '&::-webkit-scrollbar-track': {
       boxShadow: 'inset 0 0 6px rgba(0,0,0,0.00)',
       webkitBoxShadow: 'inset 0 0 6px rgba(0,0,0,0.00)',
       backgroundColor: '#eceeec',
      },
     '&::-webkit-scrollbar-thumb': {
       backgroundColor: '#ccc8c8',
      },
     "&::-webkit-scrollbar-thumb:focus": {
       backgroundColor: "#959595",
      },
      "&::-webkit-scrollbar-thumb:active": {
       backgroundColor: "#959595",
     },
  },
  messagesEmpty: {
      overflowY: "hidden",
      width: "100%",
      display: "flex",
      justifyContent: 'center',
      paddingTop: 30,
  },  
  messagesBody: {
      width: "60%",
  },   
});

interface IChatBar {
  chatDivRef: any | null,
  selectedArr: string[] | [],
  setSelectedArr: React.Dispatch<React.SetStateAction<string[] | []>>,
  isSomeSelected: boolean,
  setIsSomeSelected: React.Dispatch<React.SetStateAction<boolean>>,
  openPinned: boolean,
  pinnedMessagesMemo: TPinnedMessages,
  handleUnpinAll: () => void
}

const ChatBar = ({chatDivRef,selectedArr,setSelectedArr,isSomeSelected,setIsSomeSelected,openPinned,pinnedMessagesMemo,handleUnpinAll}:IChatBar) => {
  const classes = useStyles();
  const dispatch = useDispatch()
  const messagesMemo = useSelector(getMessagesMemo)
  const userNumber = useSelector(getNumber)
  const { companionId,total,seen,mute } = useSelector(getChat)
  const scrollChat = useSelector(getScrollChat)
  const [isArrow, setIsArrow] = useState<boolean>(false)
  const [isNew, setIsNew] = useState<{new:number,mute:boolean}>({new:0,mute:false})
  let time: any
  const isSelected = (_id: string) => selectedArr.some((el: string) => el === _id)  
  const handleSelected = (_id: string) => {
    !isSomeSelected&&setIsSomeSelected(true)
    if (selectedArr.some((el: string) => el === _id)) 
      setSelectedArr(selectedArr.filter((el:string) => el !== _id))
     else setSelectedArr([...selectedArr,_id])
  }
  const handleScrollTo = useCallback(() => {
     chatDivRef.current&&chatDivRef.current.scrollTo({
     top: chatDivRef.current.scrollHeight,
     behavior: 'smooth'
     })
  },[chatDivRef])

  const handleScroll = useCallback(({ target:{scrollHeight,scrollTop,clientHeight}}: any) => {
    const different = scrollHeight - Math.floor(scrollTop)
    const reached = different - clientHeight
    if (total !== seen&&reached < 10 && !openPinned) seenChat(companionId)
    setIsArrow(different === clientHeight ? false : true)
  }, [total,seen, companionId,openPinned])
  
  const debouncedHandleScroll = debounce(handleScroll, 300)
  
  useEffect(() => {
    if (scrollChat) {
      dispatch(asyncGetMessagesById(companionId, handleScrollTo))
      dispatch(actionScrollChat(false))
    }
  }, [dispatch,handleScrollTo, scrollChat, companionId])
  
  useEffect(() => {
    const handleReset = () => {
      dispatch(asyncGetChatById(companionId))
      dispatch(asyncGetMessagesById(companionId, null))
    }
    handleReset()
    const idInterval = setInterval(handleReset, refreshAppTime);
    return () => clearInterval(idInterval);
  }, [dispatch, companionId]);
  
  useEffect(() => {
     setIsNew({ new:total-seen,mute})
  }, [total,seen,mute]); 

  useEffect(() => {
    const handleReset = () => {
      if (chatDivRef.current&&!openPinned) {
         const { scrollHeight, clientHeight } = chatDivRef.current
         if (total !== seen && scrollHeight === clientHeight) seenChat(companionId)
       }
    }
    const idInterval = setInterval(handleReset, refreshAppTime);
    return () => clearInterval(idInterval);
  }, [total, seen, chatDivRef, companionId,openPinned]);
  
  const renderArr = useMemo(() => {
    return !openPinned ? messagesMemo : pinnedMessagesMemo
  },[messagesMemo,pinnedMessagesMemo,openPinned])

  return (
    <div className={classes.container} >
      <ArrowBack isArrow={isArrow} isNew={isNew} handleScrollTo={handleScrollTo} openPinned={openPinned}/>
      <div id={companionId} ref={chatDivRef} onScroll={debouncedHandleScroll}
        className={messagesMemo.length > 0 ? classes.messagesScroll : classes.messagesEmpty}>
        <div className={classes.messagesBody}>
        {messagesMemo.length > 0 ? renderArr.map(({ message, name, lastName, color,pinned,
           createdAt,number, type,fullType,caption,emoji,emojiCompanion,_id }) => {
          let isTime
          if (!time) {
            isTime = true
            time = createdAt
          } else if (timeStampFilter(time) !== timeStampFilter(createdAt)) {
            time = createdAt
            isTime = true
          }
          const url = `${prodAwsS3}/${message}`
          if (number !== userNumber) {
            if (type === 'text') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}> 
              {isTime&&<MessageTime  message={timeStampFilter(createdAt)}/>}
               <MessageLeftText
               message={message}
               createdAt={createdAt}
               name={name}
               lastName={lastName}
               caption={caption}
               emoji={emoji}
               emojiCompanion={emojiCompanion}
               pinned={pinned}
               isSomeSelected={isSomeSelected}
               isSelected={isSelected}
               handleSelected={handleSelected}
               _id={_id}
                 /></div>)
            if (type === 'image') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
              {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
                <MessageLeftImage   
                url={url}
                createdAt={createdAt}
                color={color}
                fullType={fullType}
                caption={caption}
                emoji={emoji}
                emojiCompanion={emojiCompanion}
                pinned={pinned}
                isSomeSelected={isSomeSelected}
                isSelected={isSelected}
                handleSelected={handleSelected}                
                _id={_id}
                  /></div>)
            if (type === 'audio') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
              {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
                <MessageLeftAudio    
                url={url}
                createdAt={createdAt}
                fullType={fullType}
                caption={caption}
                emoji={emoji}
                emojiCompanion={emojiCompanion}
                pinned={pinned}
                isSomeSelected={isSomeSelected}
                isSelected={isSelected}
                handleSelected={handleSelected}                
                _id={_id}
                  /></div>)
            if (type === 'video') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
              {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
                <MessageLeftVideo    
                url={url}
                createdAt={createdAt}
                fullType={fullType}
                caption={caption}
                emoji={emoji}
                emojiCompanion={emojiCompanion}
                pinned={pinned}
                isSomeSelected={isSomeSelected}
                isSelected={isSelected}
                handleSelected={handleSelected}              
                _id={_id}
                  /></div>)
            if (type) return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
              {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
                <MessageLeftFile   
                url={url}
                createdAt={createdAt}
                type={type}
                caption={caption}
                emoji={emoji}
                emojiCompanion={emojiCompanion}
                pinned={pinned}
                isSomeSelected={isSomeSelected}
                isSelected={isSelected}
                handleSelected={handleSelected}              
                _id={_id}
                  /></div>)             
          } else {
            if (type === 'text') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
              {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
                <MessageRightText   
                message={message}
                createdAt={createdAt}
                name={name}
                lastName={lastName}
                caption={caption}
                emoji={emoji}
                emojiCompanion={emojiCompanion}
                pinned={pinned}
                isSomeSelected={isSomeSelected}
                isSelected={isSelected}
                handleSelected={handleSelected}                
                _id={_id}
                  /></div>)
            if (type === 'image') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
              {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
                <MessageRightImage   
                url={url}
                createdAt={createdAt}
                color={color}
                fullType={fullType}
                caption={caption}
                emoji={emoji}
                emojiCompanion={emojiCompanion}
                pinned={pinned}
                isSomeSelected={isSomeSelected}
                isSelected={isSelected}
                handleSelected={handleSelected}
                _id={_id}
                  /></div>)
            if (type === 'audio') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
              {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
                <MessageRightAudio    
                url={url}
                createdAt={createdAt}
                fullType={fullType}
                caption={caption}
                emoji={emoji}
                emojiCompanion={emojiCompanion}
                pinned={pinned}
                isSomeSelected={isSomeSelected}
                isSelected={isSelected}
                handleSelected={handleSelected}
                _id={_id}
                  /></div>)
            if (type === 'video') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
              {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
                 <MessageRightVideo  
                 url={url}
                 createdAt={createdAt}
                 fullType={fullType}
                 caption={caption}
                 emoji={emoji}
                 emojiCompanion={emojiCompanion}
                 pinned={pinned}
                 isSomeSelected={isSomeSelected}
                 isSelected={isSelected}
                 handleSelected={handleSelected}
                 _id={_id}
                   /></div>)
            if (type) return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
              {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
                 <MessageRightFile  
                 url={url}
                 createdAt={createdAt}
                 type={type}
                 caption={caption}
                 emoji={emoji}
                 emojiCompanion={emojiCompanion}
                 pinned={pinned}
                 isSomeSelected={isSomeSelected}
                 isSelected={isSelected}
                 handleSelected={handleSelected}
                 _id={_id}
                   /></div>)            
          }
        }) : <AlertInfo name='You do not have messages yet!' />}
        </div>
      </div>  
      {!openPinned ? <SendMessage isArrow={isArrow} /> :
      <UnpinBar pinnedMessagesMemo={pinnedMessagesMemo} handleUnpinAll={handleUnpinAll} />}
    </div>
  );
}

export default ChatBar