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, PageType } from '@/constants/app';
import { CollectEventName } from '@/constants/event';
import { REFRESH_CHAT_LIST_TIME } from '@/constants/message';
import { MessageSubscribeIds, SubscribeTempId } from '@/constants/subscribe';
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 { collectEvent } from '@/utils/event';
import {
  postAddMessageTimes,
  requestMessageList,
  requestRemainPushTime,
  requestUnreadMessageCount,
} from '@/utils/message';
import { isSubscribeRefused, postSubscribe } from '@/utils/subscribe';
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 addMessageTimes = useCallback(async () => {
    await postAddMessageTimes('message_page');
    const remain = await requestRemainPushTime();
    setTimes(remain);
  }, []);

  const handleClickAddMessageTimes = useCallback(async () => {
    const [hasRefused, acceptIds] = await isSubscribeRefused(MessageSubscribeIds);
    if (hasRefused) {
      await Taro.showModal({
        title: '提示',
        content:
          '您未订阅消息提醒，不能及时获得招聘消息，请前往“设置”，将“新聊天消息”、“未读消息”“面试邀请”均设置为“接收”',
        showCancel: false,
        confirmText: '打开设置',
      });
      await Taro.openSetting({
        withSubscriptions: true,
      });
      const { subscriptionsSetting: { mainSwitch, itemSettings = {} } = {} } = await Taro.getSetting({
        withSubscriptions: true,
      });
      console.log('subscriptionsSetting:', mainSwitch, itemSettings);
      const successIds = mainSwitch
        ? MessageSubscribeIds.reduce<SubscribeTempId[]>((acc, id) => {
            if ((!itemSettings[id] || itemSettings[id] === 'accept') && !acceptIds.includes(id)) {
              acc.push(id);
            }
            return acc;
          }, [])
        : [];
      if (!successIds.length) {
        return;
      }
      console.log('successIds:', successIds);
      collectEvent(CollectEventName.MESSAGE_DEV_LOG, {
        action: 'subscribe_new_message_reminder',
        source: 'message_page',
        successIds,
      });
      await postSubscribe(MessageSubscribeIds, successIds);
    } else {
      await addMessageTimes();
    }
  }, [addMessageTimes]);

  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 type={PageType.Message}>
      <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>
  );
}
