import { Button, Image } from '@tarojs/components';
import Taro, { NodesRef, useDidHide, useDidShow, useLoad } from '@tarojs/taro';

import { List } from '@taroify/core';
import { useCallback, useEffect, useRef, useState } from 'react';

import HomePage from '@/components/home-page';
import MessageCard from '@/components/message-card';
import { MessageHelpDialog, MessageNoTimesDialog } from '@/components/message-dialog';
import { APP_TAB_BAR_ID, EventName } from '@/constants/app';
import { REFRESH_CHAT_LIST_TIME } from '@/constants/message';
import useListHeight, { IUseListHeightProps } from '@/hooks/use-list-height';
import useRoleType from '@/hooks/user-role-type';
import { MainMessage } from '@/types/message';
import { logWithPrefix } from '@/utils/common';
import {
  postAddMessageTimes,
  requestMessageList,
  requestRemainPushTime,
  requestUnreadMessageCount,
} from '@/utils/message';

import './index.less';

const PREFIX = 'page-message';
const HEADER_CLASS = `${PREFIX}__header`;
const CALC_LIST_PROPS: IUseListHeightProps = {
  selectors: [`.${HEADER_CLASS}`, `#${APP_TAB_BAR_ID}`],
  calc: (rects: [NodesRef.BoundingClientRectCallbackResult, NodesRef.BoundingClientRectCallbackResult]) => {
    const [headerRect, tabBarRect] = rects;
    return tabBarRect.top - headerRect.bottom;
  },
};
const log = logWithPrefix(PREFIX);

export default function Message() {
  const roleType = useRoleType();
  const listHeight = useListHeight(CALC_LIST_PROPS);
  const [times, setTimes] = useState(0);
  const [messages, setMessages] = useState<MainMessage[]>([]);
  const [showHelp, setShowHelp] = useState(false);
  const [showTips, setShowTips] = useState(false);
  const pageVisibleRef = useRef(true);
  const refreshRef = useRef(async (needTips: boolean = false) => {
    try {
      const [list, remain] = await Promise.all([
        requestMessageList(),
        requestRemainPushTime(),
        requestUnreadMessageCount(),
      ]);
      setMessages(list);
      setTimes(Number(remain));
      needTips && remain >= 0 && remain <= 3 && setShowTips(true);
    } catch (e) {
      console.error(e);
    }
  });

  const handleClickHelp = useCallback(() => setShowHelp(true), []);

  const handleClickAddMessageTimes = useCallback(async () => {
    await postAddMessageTimes('message_page');
    const remain = await requestRemainPushTime();
    setTimes(remain);
  }, []);

  useDidHide(() => (pageVisibleRef.current = false));

  useDidShow(() => {
    pageVisibleRef.current = true;
    refreshRef.current();
  });

  useLoad(async () => {
    refreshRef.current(true);
  });

  useEffect(() => {
    const intervalId = setInterval(async () => {
      if (!pageVisibleRef.current) {
        log('ignore refresh message list by page hidden');
        return;
      }
      refreshRef.current();
    }, REFRESH_CHAT_LIST_TIME);
    return () => {
      clearInterval(intervalId);
    };
  }, []);

  useEffect(() => {
    const callback = () => refreshRef.current();
    Taro.eventCenter.on(EventName.EXIT_CHAT_PAGE, callback);
    return () => {
      Taro.eventCenter.off(EventName.EXIT_CHAT_PAGE, callback);
    };
  }, []);

  useEffect(() => {
    refreshRef.current();
  }, [roleType]);

  return (
    <HomePage>
      <div className={PREFIX}>
        <div className={HEADER_CLASS}>
          <div className={`${HEADER_CLASS}__times`}>
            消息通知次数还剩：
            <div className="highlight">{`${times}次`}</div>
            <Image
              className={`${HEADER_CLASS}__help-icon`}
              src={require('@/statics/svg/help.svg')}
              onClick={handleClickHelp}
            />
          </div>
          <Button className={`${HEADER_CLASS}__btn`} onClick={handleClickAddMessageTimes}>
            点击增加
          </Button>
        </div>
        <List className={`${PREFIX}__message-list`} style={{ height: `${listHeight}px` }} disabled fixedHeight>
          {messages.map(message => (
            <MessageCard key={message.toUserName} data={message} />
          ))}
        </List>
      </div>
      <div>
        <MessageHelpDialog open={showHelp} onClose={() => setShowHelp(false)} />
        <MessageNoTimesDialog
          times={times}
          open={showTips}
          onClose={() => setShowTips(false)}
          onClick={handleClickAddMessageTimes}
        />
      </div>
    </HomePage>
  );
}
