import { memo, useCallback, useEffect, useRef, useState, forwardRef } from 'react';
import { Divider, Button, Input, Layout, DatePicker, Form, List, Spin, Flex } from 'antd';
import { LoadingOutlined } from '@ant-design/icons';
import { ChatItem, MessageBox } from 'react-chat-elements';
import { MESSAGE_PAGE_SIZE, fetchConversationsSearch, fetchMessagesHistory } from '@/actions/ConversationActions';
import { cloneDeep, flush, isEmpty, pick, stringToColour } from '@/utils/utils';
import useFormStore from '@/stores/FormStore';

import { fetchSalesAgent, fetchCustomerList } from '@/actions/CommonActions';
import SearchInput from '@/components/SearchInput';
import { isNotEmpty } from '@/utils/commons';

const { Sider, Content, Header, Footer } = Layout;
const { Search } = Input;
const { RangePicker } = DatePicker;

const BIG_PAGE_SIZE = MESSAGE_PAGE_SIZE * 100;

// https://media-xsp2-1.cdn.whatsapp.net/v/t61.24694-24/424735646_380563021285029_2962758854250800176_n.jpg?ccb=11-4&oh=01_AdTogiVdUE-ToI9uH-VQKTTLyDbP7bocXUQe1OETOeCgcg&oe=65F7C6AB&_nc_sid=e6ed6c&_nc_cat=104

// eslint-disable-next-line react/display-name
const SearchForm = memo(function ({ initialValues, onSubmit }) {
  const [form] = Form.useForm();
  function handleSubmit(values) {
    const multiAgents = (values?.agent || []).map(ele => ele.value).join(',');
    const multiCustomers = (values?.customer || []).map(ele => ele.value).join(',');
    onSubmit?.({
      ...values,
      opisn: multiAgents,
      whatsapp_id: multiCustomers,
      ...(isNotEmpty(values.msgDateRange) ? {
        from_date: values.msgDateRange[0].format('YYYY-MM-DD'),
        end_date: values.msgDateRange[1].format('YYYY-MM-DD'),
      } : {}),
    });
  }
  return (
    <Form
      layout={'inline'}
      form={form}
      initialValues={initialValues}
      onFinish={handleSubmit}
      style={{}}>
      <Form.Item label='顾问' name='agent' style={{ width: '200px' }} rules={[{required: true, message: '请选择顾问'}]}>
        <SearchInput placeholder='搜索顾问' fetchOptions={fetchSalesAgent} mode={'tags'} maxTagCount={0} />
      </Form.Item>
      <Form.Item label='客人' name='customer' style={{ width: '200px' }}>
        <SearchInput placeholder='搜索客人' fetchOptions={fetchCustomerList} mode={'tags'} maxTagCount={0} />
      </Form.Item>
      <Form.Item label='订单号' name='coli_id'>
        <Input placeholder='订单号' allowClear />
      </Form.Item>
      <Form.Item label='关键词' name='search'>
        <Input placeholder='关键词' allowClear />
      </Form.Item>
      <Form.Item label='日期' name='msgDateRange'>
        <RangePicker format={'YYYY-MM-DD'} />
      </Form.Item>
      <Form.Item>
        <Button type='primary' htmlType='submit'>
          搜索
        </Button>
      </Form.Item>
    </Form>
  );
});

function ChatHistory() {
  // const [formValues, setFormValues] = useState({});
  const [formValues, setFormValues] = useFormStore(((state) => [state.chatHistoryForm, state.setChatHistoryForm]));
  const [selectedConversation, setSelectedConversation] = useFormStore(((state) => [state.chatHistorySelectChat, state.setChatHistorySelectChat]));
  const [selectMatch, setSelectedMatch] = useFormStore(((state) => [state.msgHistorySelectMatch, state.setMsgHistorySelectMatch]));
  const [paramsForMsgList, setParamsForMsgList] = useFormStore(((state) => [state.msgListParams, state.setMsgListParams]));
  // { opisn, whatsappid, lasttime, pagesize, pagedir }

  const handleSubmit = useCallback((values) => {
    setFormValues({ ...values });
  }, []);

  const [conversationsListLoading, setConversationsListLoading] = useState(false);
  const [messageListPreLoading, setMessageListPreLoading] = useState(false);
  const [messageListLoading, setMessageListLoading] = useState(false);
  const [conversationsList, setConversationsList] = useState([]);
  const [chatItemMessages, setChatItemMessages] = useState([]);
  // const [paramsForMsgList, setParamsForMsgList] = useState({ loadNextPage: true, loadPrePage: true, }); // { opisn, whatsappid, lasttime, pagesize, pagedir }
  // const [selectMatch, setSelectedMatch] = useState({});

  const getConversationsList = async () => {
    const allEmpty = Object.values(cloneDeep(formValues)).every((val) => {
      return val === null || val === '' || val === undefined;
    });
    if (allEmpty) return;
    setConversationsListLoading(true);
    setChatItemMessages([]);
    setParamsForMsgList({});
    setSelectedMatch({});
    const params = flush(pick(formValues, ['opisn', 'whatsapp_id', 'search', 'from_date', 'end_date', 'coli_id']));
    const data = await fetchConversationsSearch(params);
    setConversationsListLoading(false);
    setConversationsList(data);
    if (data.length === 1) {
      setSelectedConversation(data[0]);
    }
  };

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

  // 选择指定消息之后, 定位
  const scrollToSelectedMessage = (selected) => {
    const findIndex = chatItemMessages.findIndex(item => item.id === selected.id);
    if (findIndex !== -1) {
      scrollToMessage(selected.id, findIndex);
    }
  }
  const handleMatchMsgClick = async (selected) => {
    const findIndex = chatItemMessages.findIndex(item => item.id === selected.id);
    if (findIndex === -1) {
      setMessageListLoading(true);
      await getMessagesPre({...paramsForMsgList });
      setMessageListLoading(false);
    }
    setSelectedMatch(selected);
  }
  // 选择指定消息之后, 定位
  useEffect(() => {
    if (selectMatch.sn) {
      scrollToSelectedMessage(selectMatch);
    }
    return () => {};
  }, [selectMatch.sn]);

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

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

  // 更新是否需要显示上一页,下一页按钮
  useEffect(() => {
    if (chatItemMessages.length > 0) {
      setParamsForMsgList({pretime: chatItemMessages[0].orgmsgtime, lasttime: chatItemMessages[chatItemMessages.length - 1].orgmsgtime });
    }
    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;

  useEffect(() => {
    getConversationsList();
    return () => {};
  }, [formValues]);

  const RenderText = memo(function renderText({ str, className }) {
    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-base leading-5 emoji-text ${className} ${extraClass} `}>
        {(objArr || []).map((part, index) => {
          if (part.type === 'link') {
            return (
              <a href={part.key} target='_blank' key={`${part.key}${index}`} rel='noreferrer' className='text-base'>
                {part.key}
              </a>
            );
          } else {
            return part.key;
          }
        })}
      </span>
    );
  });

  const handlePreview = (msg) => {
    switch (msg.whatsapp_msg_type) {
      case 'image':
      // eslint-disable-next-line no-fallthrough
      case 'document':
        window.open(msg.data.link || msg.data.uri, '_blank', 'noopener,noreferrer');
        return false;

      default:
        return false;
    }
  };

  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);
    }
  };
  // eslint-disable-next-line react/display-name
  const MessageBoxWithRef = forwardRef((props, ref) => (
    <li ref={ref} >
      <MessageBox {...props} />
    </li>
  ));
  return (
    <>
      <SearchForm onSubmit={handleSubmit} initialValues={formValues} />
      <Divider plain orientation='left' className='mb-0'></Divider>
      <Layout hasSider className='h-screen chathistory-wrapper chatwindow-wrapper' style={{ maxHeight: 'calc(100% - 279px)', height: 'calc(100% - 279px)' }}>
        <Sider width={240} theme={'light'} className='h-full overflow-y-auto overflow-x-hidden' style={{ maxHeight: 'calc(100vh - 279px)', height: 'calc(100vh - 279px)' }}>
          <Spin spinning={conversationsListLoading}>
            {conversationsList.map((item) => (
              <ChatItem
                {...item}
                key={item.conversationid}
                id={item.conversationid}
                letterItem={{ id: item.whatsapp_name || item.whatsapp_phone_number, letter: (item.whatsapp_name || item.whatsapp_phone_number).split(" ")[0] }}
                alt={`${item.whatsapp_name}`}
                title={item.whatsapp_name || item.whatsapp_phone_number}
                subtitle={item.coli_id}
                date={item.last_received_time}
                className={String(item.conversationid) === String(selectedConversation.conversationid) ? '__active text-primary bg-neutral-100' : ''}
                onClick={() => setSelectedConversation(item)}
              />
            ))}
          </Spin>
        </Sider>
        <Content style={{ maxHeight: 'calc(100vh - 279px)', height: 'calc(100vh - 279px)', minWidth: '360px' }}>
            <Flex className='h-full relative'>
              {(selectedConversation.matchMsgList || []).length > 1 && isNotEmpty(formValues.search) && <div className='w-80 overflow-y-auto overflow-x-hidden'>
                {(selectedConversation.matchMsgList).map((item) => (
                  <ChatItem
                    {...item}
                    key={item.sn}
                    id={item.sn}
                    letterItem={{ id: item.senderName, letter: (item.senderName).split(" ")[0] }}
                    alt={`${item.senderName}`}
                    title={item.senderName}
                    subtitle={item.originText}
                    date={item.msgtime}
                    // dateString={item.msgtime}
                    className={String(item.sn) === String(selectMatch?.sn) ? '__active text-primary bg-neutral-100' : ' bg-white'}
                    onClick={() => handleMatchMsgClick(item)}
                  />
                ))}
              </div>}
              <div className='h-full relative flex-1 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'}
                      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' : ''} />}
                      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' : '',
                      ].join(' ')}
                      style={{
                        backgroundColor: message.sender === 'me' ? '#ccd4ae' : '#fff',
                      }}
                      {...(message.type === 'meetingLink'
                        ? {
                            actionButtons: [
                              {
                                onClickButton: () => {
                                  navigator.clipboard.writeText(message.text);
                                },
                                Component: () => <div>复制</div>,
                              },
                            ],
                          }
                        : {})}
                      renderAddCmp={
                        <div 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.senderName}</span>
                          <span>{message.dateString || message.localDate}</span>
                          <span>{message.statusCN}</span>
                        </div>
                      }
                      // date={null}
                      // status={null}
                    />
                  )}
                />
              </div>
            </Flex>
        </Content>
      </Layout>
    </>
  );
}

export default ChatHistory;
