import { useState, useEffect,useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import Tab from '@mui/material/Tab';
import Tabs from '@mui/material/Tabs';
import Box from '@mui/material/Box';
import { makeStyles } from '@material-ui/core'
import { styled } from '@mui/material/styles';

import ChatListRecent from './ChatListRecent'
import FilesList from './FilesList';
import MediaList from './MediaList';
import TextList from './TextList';
import AudioList from './AudioList'
import VideoList from './VideoList';
import { asyncGetAllMessages } from '../../../../redux/allMessages/operations';
import { asyncGetChats } from '../../../../redux/chats/operations';
import { getStateMemo } from '../../../../redux/chats/selector';
import { getAllMessagesMemo } from '../../../../redux/allMessages/selector';
import { getState } from '../../../../redux/control/selector';
import { sortByRecent,filterBy,filteredMessages,handleSort,timeStampFilter,refreshAppTime } from '../../../../helpers';
import { asyncStartChatById } from '../../../../redux/chat/operations';
import { getPinnedMessagesMemo } from '../../../../redux/pinnedMessages/selector';
import { actionLeftIsOpen,actionRightIsOpen,actionOpenPinned } from '../../../../redux/control/action';
import { TMessage } from '../../../../typescript/redux/messages/types';

const useStyles = makeStyles({
  container: {
    height: '5vh',
    display: "flex",
    alignContent: "end",
    alignItems: "end",
    width:'100%',
    borderBottom: 'solid 2px #dddddd',
  },
})

interface StyledTabsProps {
  children?: React.ReactNode;
  value: number;
  onChange: (event: React.SyntheticEvent, newValue: number) => void;
}

const StyledTabs = styled((props: StyledTabsProps) => (
  <Tabs
    {...props}
    TabIndicatorProps={{ children: <span className="MuiTabs-indicatorSpan" /> }}
  />
))({
  '& .MuiTabs-flexContainer': {
    display: "flex",
    width: '100%',
    padding:'0px 10px',
    justifyContent: "space-between"
  },
  '& .MuiTabs-indicator': {
    height: 0,
    backgroundColor: 'transparent',
    borderBottom: '3px solid #1976d2',
    borderLeft: '3px solid transparent',
    borderRight: '3px solid transparent',
  },
});

const StyledTab = styled((props:{label: string}) => <Tab disableRipple {...props} />)({
    fontSize: '1rem',
    fontWeight: 550,
    textTransform: 'none',
    minWidth: 'auto',
  },
);

interface ISearchLists {
  value: string,
  setValue: React.Dispatch<string>
  sort: boolean,
  date: any,
  setDate: React.Dispatch<any>,
  setDisabled: React.Dispatch<boolean>,
  chatDivRef: any | null
}

const SearchLists = ({ value,setValue,sort,date,setDate,setDisabled,chatDivRef}: ISearchLists) => {
    const classes = useStyles()
    const dispatch = useDispatch()
    const { chats, total } = useSelector(getStateMemo)
    const messagesMemo = useSelector(getAllMessagesMemo)
    const pinnedMessagesMemo = useSelector(getPinnedMessagesMemo)
    const { leftIsOpen,rightIsOpen,openPinned } = useSelector(getState)
    const [isActive, setIsActive] = useState<number>(0)
    const handleIsActive = (_e:any,newValue: number): void => {
      setIsActive(newValue)
      value && setValue('')
      date&&setDate('')
    } 

    const handleListItemClick = (companionId: string) => {
      rightIsOpen && dispatch(actionRightIsOpen(''))
      openPinned&&dispatch(actionOpenPinned(false))
      dispatch(asyncStartChatById(companionId))
    }
  
    const scrollTo = (nodeRef: any,id:string) => {
      const childNodes = nodeRef.current.childNodes[0].childNodes
      let toScrollNode = [...childNodes].find((el: any) => el.id === id)
      if (toScrollNode) {
        toScrollNode = [...toScrollNode.childNodes].slice(-1)[0]
        toScrollNode.style.backgroundColor = 'rgba(70, 70, 70, 0.4)'
        toScrollNode.style.boxShadow = '0px 0px 6px 0px #ffffff'
        toScrollNode.scrollIntoView({ behavior: 'smooth' })
        setTimeout(() => {
          toScrollNode.style.backgroundColor = 'unset'
          toScrollNode.style.boxShadow = 'unset'
        }, 2000)
      }
    }
  
  const handleScrollToTheMessage = (_id: string, companionId: string) => {
      if (openPinned && !pinnedMessagesMemo.some((el) => (el._id === _id && el.companionId === companionId))) {
        dispatch(actionOpenPinned(false)) 
      }
      if (chatDivRef.current && chatDivRef.current.id === companionId) {
         scrollTo(chatDivRef,_id)
      } else if (chatDivRef.current && chatDivRef.current.id !== companionId) {
        rightIsOpen&&dispatch(actionRightIsOpen(''))
        dispatch(asyncStartChatById(companionId))
        setTimeout(() => {
          if(chatDivRef.current) scrollTo(chatDivRef,_id)
        }, 3000)        
      } else if (!chatDivRef.current) {
        rightIsOpen&&dispatch(actionRightIsOpen(''))
        dispatch(asyncStartChatById(companionId))
        setTimeout(() => {
          if(chatDivRef.current) scrollTo(chatDivRef,_id)
      }, 3000)
      }
    }  
  
    useEffect(() => {
       setDate('')
    }, [setDate])
  
    useEffect(() => {
      if (isActive === 0) {
          dispatch(actionLeftIsOpen('searchChats'))
      } else {
        dispatch(actionLeftIsOpen('searchAllMessages'))
        }
    }, [isActive,dispatch])  
  
    useEffect(() => {
        if (isActive === 0) setDisabled(total === '0'?true:false)
    }, [isActive,total,setDisabled])
  
    useEffect(() => {
      const handleReset = () => {
        if (leftIsOpen === 'searchChats') {
          dispatch(asyncGetChats())
        } else if (leftIsOpen === 'searchAllMessages') {
          dispatch(asyncGetAllMessages())
        }
      }
      handleReset()
      const idInterval = setInterval(handleReset, refreshAppTime);
      return () => clearInterval(idInterval);
    }, [leftIsOpen,dispatch]);
    
  
  const filteredAndSortedChats = useMemo(() => {
      return sortByRecent(chats,sort).filter((el) => {
      const credentials = el.name + ' ' + el.lastName
      if (!date) {
         return credentials.toLowerCase().includes(value.toLowerCase())
      } else if (credentials.toLowerCase().includes(value.toLowerCase())
        &&timeStampFilter(date) === timeStampFilter(el.lastMessageCreatedAt ?
        el.lastMessageCreatedAt : el.createdAt)) {
        return el
      } else return undefined
    })
  }, [chats, date, value, sort])

  const filteredAndSortedMessages = useMemo(() => {
    const filtered = messagesMemo.filter((el:TMessage) => filterBy[isActive === 0?0:isActive-1].includes(el.type))
    if(isActive > 0) setDisabled(filtered.length > 0?false:true) 
     return filteredMessages(handleSort('createdAt', filtered, sort), date, value)
  }, [messagesMemo, date, isActive, sort, value,setDisabled])

    return (
      <>
        <Box className={classes.container}>
          <StyledTabs sx={{width:'100%'}}  onChange={handleIsActive} value={isActive} aria-label="wrapped label tabs example">
            <StyledTab label='Chats' />
            <StyledTab label='Files' />
            <StyledTab label='Media' />
            <StyledTab label='Text' />
            <StyledTab label='Audio' />
            <StyledTab label='Video' />
          </StyledTabs>
        </Box>
        {isActive === 0 && <ChatListRecent value={value} date={date}
          filteredAndSortedChats={filteredAndSortedChats} handleListItemClick={handleListItemClick} />}
        {isActive === 1 && <FilesList filteredAndSortedMessages={filteredAndSortedMessages} value={value} date={date} handleScrollToTheMessage={handleScrollToTheMessage}/>}
        {isActive === 2 && <MediaList filteredAndSortedMessages={filteredAndSortedMessages} value={value} date={date} handleScrollToTheMessage={handleScrollToTheMessage}/>}
        {isActive === 3 && <TextList  filteredAndSortedMessages={filteredAndSortedMessages} value={value} date={date} handleScrollToTheMessage={handleScrollToTheMessage}/>}
        {isActive === 4 && <AudioList filteredAndSortedMessages={filteredAndSortedMessages} value={value} date={date} handleScrollToTheMessage={handleScrollToTheMessage}/>}
        {isActive === 5 && <VideoList filteredAndSortedMessages={filteredAndSortedMessages} value={value} date={date} handleScrollToTheMessage={handleScrollToTheMessage}/>}
    </>      
    )
}

export default SearchLists