import { useRef, useEffect, useState, forwardRef, memo } from 'react';
import { App, Flex, List, Button,  } from 'antd';
import { LoadingOutlined } from '@ant-design/icons';
import { MessageBox } from 'react-chat-elements';
import { MESSAGE_PAGE_SIZE, fetchMessagesHistory } from '@/actions/ConversationActions';
import useFormStore from '@/stores/FormStore';
import { isEmpty, stringToColour, groupBy, isNotEmpty } from '@/utils/commons';
import { useShallow } from 'zustand/react/shallow';
import MergeConversationTo from './MergeConversationTo';

const BIG_PAGE_SIZE = MESSAGE_PAGE_SIZE * 100;
const MessagesList = ({ ...props }) => {
  const { message: appMessage } = App.useApp();

  const [formValues] = useFormStore((state) => [state.chatHistoryForm]);
  const [selectedConversation] = useFormStore((state) => [state.chatHistorySelectChat]);
  const [paramsForMsgList, setParamsForMsgList] = useFormStore((state) => [state.msgListParams, state.setMsgListParams]);
  const [selectMatch, setSelectedMatch] = useFormStore((state) => [state.msgHistorySelectMatch, state.setMsgHistorySelectMatch]);
  const [setImageAlbumList, setImagePreviewSrc] = useFormStore(useShallow((state) => [state.setImageAlbum, state.setImagePreviewSrc]));

  const [chatItemMessages, setChatItemMessages] = useState([]);
  const [messageListPreLoading, setMessageListPreLoading] = useState(false);
  const [messageListLoading, setMessageListLoading] = useState(false);

  const getMessagesPre = async (chatItem) => {
    setMessageListPreLoading(true);
    const data = await fetchMessagesHistory({ ...chatItem, lasttime: chatItem.pretime, pagedir: 'pre', pagesize: BIG_PAGE_SIZE });
    setMessageListPreLoading(false);
    // const prevChatItemMessages = chatItemMessages;
    // setChatItemMessages([].concat(data, prevChatItemMessages));
    setChatItemMessages((prevValue) => [].concat(data, prevValue));
    const loadPrePage = !(data.length === 0 || data.length < BIG_PAGE_SIZE);
    if (data.length > 0) {
      setParamsForMsgList({ loadPrePage, pretime: data[0].orgmsgtime });
    }
  };
  const getMessagesNext = async (chatItem) => {
    setMessageListLoading(true);
    const data = await fetchMessagesHistory({ ...chatItem, pagedir: 'next', pagesize: BIG_PAGE_SIZE });
    setMessageListLoading(false);
    // const prevChatItemMessages = chatItemMessages;
    // setChatItemMessages([].concat(prevChatItemMessages, data));
    setChatItemMessages((prevValue) => [].concat(prevValue, data));
    const loadNextPage = !(data.length === 0 || data.length < BIG_PAGE_SIZE);
    if (data.length > 0) {
      setParamsForMsgList({ loadNextPage, lasttime: data[data.length - 1].orgmsgtime });
    }
  };

  // 选择指定消息之后, 定位
  const scrollToSelectedMessage = (selected) => {
    const findIndex = chatItemMessages.findIndex((item) => item.id === selected.id);
    if (findIndex !== -1) {
      scrollToMessage(selected.id, findIndex);
    }
  };

  // 选中会话之后, 获取消息记录
  useEffect(() => {
    setChatItemMessages([]);
    setParamsForMsgList({});
    setSelectedMatch({});
    setFocusMsg('');
    if (isEmpty(selectedConversation.conversationid)) {
      return () => {};
    }
    const firstActionPageParams = { opisn: (selectedConversation.opi_sn || 0), whatsappid: selectedConversation.whatsapp_phone_number, loadNextPage: true };
    // if (isEmpty(selectedConversation.matchMsgList)) {
    if (!isEmpty(formValues?.from_date)) {
      firstActionPageParams.lasttime = formValues.from_date;
      firstActionPageParams.loadPrePage = true;
    }
    if (!isEmpty(formValues?.search) && !isEmpty(selectedConversation.matchMsgList)) {
      firstActionPageParams.pretime = selectedConversation.matchMsgList[0].orgmsgtime;
      firstActionPageParams.lasttime = selectedConversation.matchMsgList[0].orgmsgtime;
      firstActionPageParams.loadPrePage = true;
    }
    setParamsForMsgList(firstActionPageParams);
    async function getFirstNext() {
      await getMessagesNext(firstActionPageParams);
    }
    getFirstNext();

    return () => {};
  }, [selectedConversation.conversationid]);

  // 点击匹配的记录, 定位滚动
  useEffect(() => {
    async function getFirstPre(_params) {
      await getMessagesPre(_params);
    }

    const findIndex = chatItemMessages.findIndex((item) => item.id === selectMatch.id);
    if (findIndex === -1) {
      setMessageListLoading(true);
      getFirstPre({ ...paramsForMsgList });
      setMessageListLoading(false);
    }
    scrollToSelectedMessage(selectMatch);
    return () => {};
  }, [selectMatch.id]);

  // 更新是否需要显示上一页,下一页按钮
  useEffect(() => {
    if (chatItemMessages.length > 0) {
  //     setParamsForMsgList({ pretime: chatItemMessages[0].orgmsgtime, lasttime: chatItemMessages[chatItemMessages.length - 1].orgmsgtime });
      const album = chatItemMessages.filter((ele) => ele.whatsapp_msg_type === 'image').map((ele) => ele.data.uri);
      setImageAlbumList(album);
    }
    return () => {};
  }, [chatItemMessages]);

  const onLoadMore = () => {
    getMessagesNext(paramsForMsgList);
    // window.dispatchEvent(new Event('resize'));
  };
  const loadMore =
    !messageListLoading && paramsForMsgList.loadNextPage ? (
      <div className='text-center pt-3 mb-3 h-8 leading-8 border-dotted border-0 border-t border-slate-300'>
        <Button onClick={onLoadMore}>load more</Button>
      </div>
    ) : null;
  const onLoadMorePre = () => {
    getMessagesPre(paramsForMsgList);
    // window.dispatchEvent(new Event('resize'));
  };
  const loadMorePre =
    paramsForMsgList.loadPrePage && chatItemMessages.length > 0 ? (
      <div className='text-center h-8 leading-8 '>
        {messageListPreLoading ? <LoadingOutlined className='text-primary' /> : <Button onClick={onLoadMorePre}>load more previous </Button>}
      </div>
    ) : null;

  const messagesEndRef = useRef(null);
  const messageRefs = useRef([]);
  const [focusMsg, setFocusMsg] = useState('');
  const scrollToMessage = (id, index) => {
    const _i = index || chatItemMessages.findIndex((msg) => msg.id === id);
    if (_i >= 0) {
      messageRefs.current[_i].scrollIntoView({ behavior: 'smooth', block: 'start' });
      setFocusMsg(id);
    }
  };

  const RenderText = memo(function renderText({ str, className, template }) {
    let headerObj, footerObj, buttonsArr;
    if (!isEmpty(template) && !isEmpty(template.components)) {
      const componentsObj = groupBy(template.components, (item) => item.type);
      headerObj = componentsObj?.header?.[0];
      footerObj = componentsObj?.footer?.[0];
      buttonsArr = componentsObj?.buttons?.reduce((r, c) => r.concat(c.buttons), []);
    }

    const parts = str.split(/(https?:\/\/[^\s()]+|\p{Emoji_Presentation})/gmu).filter((s) => s !== '');
    const links = str.match(/https?:\/\/[^\s()]+/gi) || [];
    const emojis = str.match(/([\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF])/g) || [];
    const extraClass = isEmpty(emojis) ? '' : '';
    const objArr = parts.reduce((prev, curr, index) => {
      if (links.includes(curr)) {
        prev.push({ type: 'link', key: curr });
      } else if (emojis.includes(curr)) {
        prev.push({ type: 'emoji', key: curr });
      } else {
        prev.push({ type: 'text', key: curr });
      }
      return prev;
    }, []);
    return (
      <span className={`text-sm leading-5 emoji-text whitespace-pre-wrap ${className} ${extraClass} `} key={'msg-text'}>
        {headerObj ? (
          <div className='text-neutral-500 text-center'>
            {'text' === (headerObj?.parameters?.[0]?.type || '').toLowerCase() && <div>{headerObj.text}</div>}
            {'image' === (headerObj?.parameters?.[0]?.type || '').toLowerCase() && <img src={headerObj.parameters[0].image.link} height={100}></img>}
            {['document', 'video'].includes((headerObj?.parameters?.[0]?.type || '').toLowerCase()) && (
              <a href={headerObj.parameters[0][headerObj.parameters[0].type].link} target='_blank' key={headerObj.format} rel='noreferrer' className='text-sm'>
                [&nbsp;{headerObj.parameters[0].type}&nbsp;]
              </a>
            )}
          </div>
        ) : null}
        {(objArr || []).map((part, index) => {
          if (part.type === 'link') {
            return (
              <a href={part.key} target='_blank' key={`${part.key}${index}`} rel='noreferrer' className='text-sm'>
                {part.key}
              </a>
            );
          } else {
            return part.key;
          }
        })}
      </span>
    );
  });

  // eslint-disable-next-line react/display-name
  const MessageBoxWithRef = forwardRef((props, ref) => (
    <li ref={ref}>
      <MessageBox {...props} />
    </li>
  ));

  const handlePreview = (msg) => {
    switch (msg.whatsapp_msg_type) {
      case 'image':
        setImagePreviewSrc(msg.data.uri);
        return false;

      case 'document':
        window.open(msg.data.link || msg.data.uri, '_blank', 'noopener,noreferrer');
        return false;

      default:
        return false;
    }
  };

  return (
    <>
      <Flex vertical className='flex-1'>
        <Flex className='bg-white border-0 border-b border-slate-200' gap={8} justify={'space-between'}>
        <div className='px-2 py-1 text-primary '>
          {selectedConversation.whatsapp_name} {selectedConversation.whatsapp_phone_number}
        </div>
        {selectedConversation.whatsapp_phone_number && <MergeConversationTo currentWAID={selectedConversation.whatsapp_phone_number} opi_sn={selectedConversation.opi_sn} />}
        </Flex>

        <div style={{ height: 'calc(100% - 30px)' }} className='h-full flex-auto relative  border-dashed border-y-0 border-r-0 border-l border-slate-200' ref={messagesEndRef}>
          <List
            loading={messageListLoading}
            header={loadMorePre}
            loadMore={loadMore}
            className='h-full overflow-y-auto px-2 relative'
            itemLayout='vertical'
            dataSource={chatItemMessages}
            renderItem={(message, index) => (
              // <List.Item>
              //   <List.Item.Meta avatar={<Avatar src={item.avatarUrl} />} title={item.title} description={item.msgTime} />
              //   <div>{item.content}</div>
              // </List.Item>
              <MessageBoxWithRef
                ref={(el) => (messageRefs.current[index] = el)}
                key={message.id}
                {...message}
                // position={message.sender === 'me' ? 'right' : 'left'}
                position={'left'}
                replyButton={false}
                onReplyMessageClick={() => scrollToMessage(message.reply.id)}
                onOpen={() => handlePreview(message)}
                onTitleClick={() => handlePreview(message)}
                notch={false}
                title={message.whatsapp_msg_type === 'text' ? '' : message.title}
                text={<RenderText str={message?.text || ''} className={message.status === 'failed' ? 'line-through text-neutral-400' : ''} template={message.template} />}
                copiableDate={true}
                dateString={message.dateString || message.localDate}
                className={[
                  'whitespace-pre-wrap mb-2',
                  message.whatsapp_msg_type === 'sticker' ? 'bg-transparent' : '',
                  message.sender === 'me' ? 'whatsappme-container' : '',
                  focusMsg === message.id ? 'message-box-focus' : '',
                  message.status === 'failed' ? 'failed-msg' : '',
                ].join(' ')}
                style={{
                  backgroundColor: message.sender === 'me' ? '#ccd4ae' : '#fff',
                }}
                {...(message.type === 'meetingLink'
                  ? {
                      actionButtons: [
                        {
                          onClickButton: () => {
                            navigator.clipboard.writeText(message.text);
                            appMessage.success('复制成功😀');
                          },
                          Component: () => <div key='copy'>复制</div>,
                        },
                      ],
                    }
                  : {})}
                renderAddCmp={
                  <div key={'msg-prefix'} className='border-dashed border-0 border-t border-slate-300 text-slate-600 space-x-2 emoji'>
                    <span
                      className={`p-1 rounded-b ${message.msg_direction === 'outbound' ? 'text-white' : ''} `}
                      style={{ backgroundColor: message.msg_direction === 'outbound' ? stringToColour(message.senderName) : 'unset' }}>
                      {message.msg_direction === 'outbound' ? selectedConversation.OPI_Name : message.senderName}
                    </span>
                    <span>{message.dateString || message.localDate}</span>
                    <span>{message.statusCN}</span>
                  </div>
                }
                // date={null}
                // status={null}
              />
            )}
          />
        </div>
      </Flex>
    </>
  );
};
export default MessagesList;
