<template>
  <div
    v-if="isShowEmojiReaction"
    ref="emojiDetailRef"
    class="emoji-container"
  >
    <div
      v-for="(emojiReactionItem, emojiReactionIndex) in props.message.reactionList"
      v-show="emojiReactionItem.totalUserCount > 0"
      :key="emojiReactionIndex"
      class="emoji-react-item"
      @click.stop="showReactionDetail(emojiReactionItem.reactionID, props.message.ID)"
    >
      <img
        class="emoji-react-item-icon"
        :src="showEmoji(emojiReactionItem.reactionID)"
      >
      <div class="emoji-react-item-line" />
      <div class="emoji-react-item-number">
        {{
          getReactContent(
            emojiReactionItem.partialUserList,
            emojiReactionItem.totalUserCount
          )
        }}
      </div>
    </div>
    <div
      v-if="isShowDetail"
      :class="{'emoji-container-h5': !isPC }"
      @click="closeDetail"
    >
      <div
        :class="[
          isPC ? 'emoji-detail-web' : 'emoji-detail-h5',
          props.message.flow === 'in' ? 'reverse' : '',
        ]"
      >
        <div class="emoji-detail-container">
          <div
            v-for="(emojiReactionItem, emojiReactionIndex) in props.message.reactionList"
            v-show="emojiReactionItem.totalUserCount > 0"
            :key="emojiReactionIndex"
            class="emoji-detail-item"
            :class="[ selectedReactionID === emojiReactionItem.reactionID ? 'emoji-selected-item': '']"
            @click.stop="getToggledEmojiDetail(emojiReactionItem.reactionID)"
          >
            <img
              class="emoji-detail-item-icon"
              :src="showEmoji(emojiReactionItem.reactionID)"
            >
            <div class="emoji-detail-item-number">
              {{ emojiReactionItem.totalUserCount }}
            </div>
          </div>
        </div>
        <div class="emoji-detail-item-line" />
        <div class="emoji-list-container">
          <div
            v-for="(userItem, index) in userListOfMessageReaction"
            :key="index"
            class="emoji-detail-list"
          >
            <img
              class="emoji-detail-avatar"
              :src="
                userItem.avatar ||
                  'https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png'
              "
              onerror="this.src='https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png'"
            >
            <div class="emoji-detail-nick">
              {{ userItem.nick || userItem.userID }}
            </div>
            <div
              class="emoji-del"
              @click="removeMessageReaction()"
            >
              <Icon
                v-if="selectedReactionID && userItem.reactedByMyself"
                :file="emojiDel"
                width="16px"
                height="16px"
              />
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
import vue from '../../adapter-vue';
import TUICore, { TUIConstants } from '@tencentcloud/tui-core-lite';
import {
  TUITranslateService,
  IMessageModel,
  TUIChatService,
  TUIStore,
  StoreName,
} from '@tencentcloud/chat-uikit-engine-lite';
import { isPC } from '../../utils/env';
import Icon from '../common/Icon.vue';
import emojiDel from '../assets/icon/emoji-del.svg';

interface Props {
  message: IMessageModel;
  emojiConfig: Record<string, any>;
}

const { ref, onMounted, computed } = vue;

export default {
  components: {
    Icon,
  },
  props: {
    message: {
      type: Object as () => IMessageModel,
      default: () => ({}),
    },
    emojiConfig: {
      type: Object as () => Record<string, any>,
      default: () => ({}),
    },
  },
  setup(props: Props) {
    const { message, emojiConfig } = props;
    const currentUserID = ref<string>('');
    const emojiDetailRef = ref<HTMLElement | null>();
    const isShowDetail = ref<boolean>(false);
    const selectedReactionID = ref<string>('');
    const selectedReactionMessageID = ref<string>('');
    const userListOfMessageReaction = ref<Array<Record<string, any>>>([]);
    const isShowEmojiReaction = computed(() => props.message?.reactionList.some(item => item.totalUserCount !== 0));
    const reactionList = ref<any[]>([]);
    TUIStore.watch(StoreName.USER, {
      userProfile: (profile: any) => {
        currentUserID.value = profile?.userID;
      },
    });
    onMounted(() => {
      TUIStore.watch(StoreName.CUSTOM, {
        selectedReactionMessageID: (messageID: string) => {
          isShowDetail.value = message.ID === messageID ? true : false;
        },
      });
      // watch current conversationID
      TUIStore.watch(StoreName.CONV, {
        currentConversationID: () => {
          TUIStore.update(StoreName.CUSTOM, 'selectedReactionMessageID', '');
        },
      });
    });
    // 展示表情回应详情
    const showReactionDetail = (reactionID: string, messageID: string) => {
      onClickOutside(emojiDetailRef?.value);
      TUICore.callService({
        serviceName: TUIConstants.TUIChat.SERVICE.NAME,
        method: TUIConstants.TUIChat.SERVICE.METHOD.CLOSE_MESSAGE_POP_MENU,
        params: {},
      });
      selectedReactionID.value = reactionID;
      TUIStore.update(StoreName.CUSTOM, 'selectedReactionMessageID', messageID);
      if (!isShowDetail.value) return;
      getAllUserListOfMessageReaction(reactionID);
    };

    // 获取切换的 emoji 详情
    const getToggledEmojiDetail = (reactionID: string) => {
      selectedReactionID.value = reactionID;
      getAllUserListOfMessageReaction(reactionID);
    };
    const showEmoji = (reactionID: string) => {
      return `${emojiConfig.emojiBaseUrl}${emojiConfig.emojiUrlMapping[reactionID]}`;
    };
    const getReactContent = (partialUserList: [], totalUserCount: number) => {
      // 同一个表情多人回复的时候，显示前 3 人
      const userList = partialUserList.slice(0, 3);
      const reactUserList = [];
      let reactContent = '';
      userList.forEach((item) => {
        let nick = item.nick || item.userID;
        if (nick.length > 10) {
          nick = `${nick.substring(0, 10)}...`;
        }
        reactUserList.push(nick);
      });

      reactContent = reactUserList.join(',');
      if (totalUserCount < 4) {
        return reactContent;
      }
      return `${reactContent}...${TUITranslateService.t('TUIChat.等')} ${totalUserCount} ${TUITranslateService.t('TUIChat.人')}`;
    };
    const removeMessageReaction = () => {
      const _message = TUIStore.getMessageModel(message.ID);
      TUIChatService.removeMessageReaction(_message, selectedReactionID.value);
      selectedReactionID.value = '';
    };

    const getAllUserListOfMessageReaction = async (reactionID: string) => {
      const options = {
        message: TUIStore.getMessageModel(message.ID),
        reactionID,
        nextSeq: 0,
        count: 100,
      };
      const allUserList = await TUIChatService.getAllUserListOfMessageReaction(options);
      userListOfMessageReaction.value = allUserList.data.userList;
      const reactionIndexByMe = userListOfMessageReaction.value.findIndex(
        item => item.userID === currentUserID.value,
      );
      if (reactionIndexByMe < 0) {
        return;
      }
      const reactionElement = userListOfMessageReaction.value.splice(reactionIndexByMe, 1)[0];
      reactionElement.reactedByMyself = true;
      userListOfMessageReaction.value = [
        reactionElement,
        ...userListOfMessageReaction.value,
      ];
    };

    // click outside
    let clickOutside = false;
    let clickInner = false;
    const onClickOutside = (component: any) => {
      document.addEventListener('mousedown', onClickDocument);
      component?.addEventListener && component?.addEventListener('mousedown', onClickTarget);
    };

    const removeClickListener = (component: any) => {
      document.removeEventListener('mousedown', onClickDocument);
      component?.removeEventListener && component?.removeEventListener('mousedown', onClickTarget);
    };

    const onClickDocument = () => {
      clickOutside = true;
      if (!clickInner && clickOutside) {
        isShowDetail.value = false;
        removeClickListener(emojiDetailRef?.value);
      }
      clickOutside = false;
      clickInner = false;
    };

    const onClickTarget = () => {
      clickInner = true;
    };

    const closeDetail = () => {
      if (!isPC) {
        isShowDetail.value = false;
      }
    };

    return {
      props,
      reactionList,
      currentUserID,
      emojiDetailRef,
      isShowDetail,
      selectedReactionID,
      selectedReactionMessageID,
      userListOfMessageReaction,
      isShowEmojiReaction,
      onClickTarget,
      onClickDocument,
      removeClickListener,
      getAllUserListOfMessageReaction,
      removeMessageReaction,
      showReactionDetail,
      getToggledEmojiDetail,
      getReactContent,
      showEmoji,
      closeDetail,
      isPC,
      emojiDel,
    };
  },
};

</script>
<style lang="scss" scoped>
@import "../assets/styles/common";

.emoji-container {
  display: flex;
  position: relative;
  flex-wrap: wrap;
  padding-top: 10px;

  .emoji-react-item {
    cursor: pointer;
    background: rgba(0, 0, 0, 0.05);
    border-radius: 14px;
    padding: 2px 8px;
    margin: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    display: flex;
    font-size: 14px;
    align-items: center;

    .emoji-react-item-icon {
      width: 18px;
      height: 18px;
      padding: 1px;
    }

    .emoji-react-item-number {
      margin: 2px;
      font-size: 10px;
      color: #999;
    }
  }

  .emoji-react-item-line {
    height: 16px;
    width: 1px;
    margin: 2px 6px;
    background-color: #c0b9b9;
  }

  .emoji-selected-item {
    background-color: rgba(0, 0, 0, 0.05);
    border-radius: 15px;
    padding: 2px 6px;
  }

  .emoji-detail-item-line {
    height: 1px;
    width: 100%;
    margin: 3px 0;
    background-color: rgba(0, 0, 0, 0.05);
  }

  .emoji-list-container {
    overflow-y: auto;
    width: 100%;

    &::-webkit-scrollbar {
      display: none;
    }
  }

  .reverse {
    right: auto;
    left: 0;
  }

  .emoji-detail-list {
    display: flex;
    align-items: center;

    .emoji-detail-avatar {
      width: 24px;
      height: 24px;
      border-radius: 50%;
      padding: 5px;
    }

    .emoji-detail-nick {
      overflow: hidden;
      text-overflow: ellipsis;
      color: #999;
      width: 80%;
      font-size: 10px;
      white-space: nowrap;
    }
  }

  .emoji-detail-web {
    position: absolute;
    bottom: 0;
    right: 0;
    background: #fbfbfb;
    border-radius: 12px;
    padding: 6px 8px;
    overflow: hidden;
    max-width: 268px;
    max-height: 186px;
    min-width: 150px;
    z-index: 1;
    color: #fff;
    display: flex;
    flex-direction: column;
    align-items: center;
    transform: translateY(100%);
    box-sizing: border-box;
    border: 1px solid #e0e0e0;
    cursor: pointer;

    .emoji-detail-container {
      display: flex;
      width: 100%;
      margin: auto;
      flex-wrap: wrap;
      align-items: center;

      .emoji-detail-item {
        display: flex;
        padding: 2px 6px;
        justify-content: center;
        align-items: center;

        .emoji-detail-item-icon {
          width: 18px;
          height: 18px;
        }

        .emoji-detail-item-number {
          margin: 2px;
          font-size: 10px;
          color: #999;
        }
      }
    }
  }

  .emoji-container-h5 {
    position: fixed;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    background: rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: flex-end;
    z-index: 1;

    .emoji-detail-h5 {
      position: relative;
      background: #fff;
      flex: 1;
      padding: 18px;
      border-radius: 12px 12px 0 0;
      width: 80vw;
      display: flex;
      max-height: 275px;
      flex-direction: column;

      .emoji-detail-container {
        display: flex;
        width: 100%;
        margin: auto;
        flex-wrap: wrap;
        align-items: center;
        margin-bottom: 6px;

        .emoji-detail-item {
          display: flex;
          padding: 2px 6px;
          justify-content: center;
          align-items: center;
          margin: 0 2px;

          .emoji-detail-item-icon {
            width: 20px;
            height: 20px;
          }

          .emoji-detail-item-number {
            margin: 2px;
            font-size: 15px;
            color: #999;
          }
        }
      }

      .emoji-detail-list {
        .emoji-detail-avatar {
          width: 30px;
          height: 30px;
        }
      }
    }
  }
}
</style>
