<template>
  <div>
    <div
      v-if="
        props.lastMessage.lastMessageState ===
        V2NIMConst.V2NIMLastMessageState.V2NIM_MESSAGE_STATUS_REVOKE
      "
    >
      {{ t('recall') }}
    </div>
    <div
      v-else-if="
        props.lastMessage.messageType ===
        V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_NOTIFICATION
      "
    >
      {{ t('conversationNotificationText') }}
    </div>
    <div
      v-else-if="
        props.lastMessage.sendingState ===
        V2NIMConst.V2NIMMessageSendingState.V2NIM_MESSAGE_SENDING_STATE_FAILED
      "
    >
      {{ t('conversationSendFailText') }}
    </div>

    <div
      v-else-if="
        props.lastMessage.messageType ===
        V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_FILE
      "
    >
      {{ translateMsg('fileMsgText') }}
    </div>
    <div
      v-else-if="
        props.lastMessage.messageType ===
        V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_IMAGE
      "
    >
      {{ translateMsg('imgMsgText') }}
    </div>
    <div
      v-else-if="
        props.lastMessage.messageType ===
        V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_CUSTOM
      "
    >
      {{ props.lastMessage.text || translateMsg('customMsgText') }}
    </div>
    <div
      v-else-if="
        props.lastMessage.messageType ===
        V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_AUDIO
      "
    >
      {{ translateMsg('audioMsgText') }}
    </div>
    <div
      v-else-if="
        props.lastMessage.messageType ===
        V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_CALL
      "
    >
      {{ translateMsg('callMsgText') }}
    </div>
    <div
      v-else-if="
        props.lastMessage.messageType ===
        V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_LOCATION
      "
    >
      {{ translateMsg('geoMsgText') }}
    </div>

    <div
      v-else-if="
        props.lastMessage.messageType ===
        V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_ROBOT
      "
    >
      {{ translateMsg('robotMsgText') }}
    </div>
    <div
      v-else-if="
        props.lastMessage.messageType ===
        V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_TIPS
      "
    >
      {{ translateMsg('tipMsgText') }}
    </div>
    <div
      v-else-if="
        props.lastMessage.messageType ===
        V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_VIDEO
      "
    >
      {{ translateMsg('videoMsgText') }}
    </div>
    <div
      v-else-if="
        props.lastMessage.messageType ===
        V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_TEXT
      "
      class="msg-conversation-text-wrap"
    >
      <template v-for="item in textArr" :key="item.key">
        <template v-if="item.type === 'text'">
          <span class="msg-conversation-text">{{ item.value }}</span>
        </template>
        <template v-else-if="item.type === 'emoji'">
          <span
            :class="
              isWxApp
                ? 'msg-conversation-text-emoji-wx'
                : 'msg-conversation-text-emoji'
            "
          >
            <Icon :type="EMOJI_ICON_MAP_CONFIG[item.value]" :size="16" />
          </span>
        </template>
      </template>
    </div>
  </div>
</template>

<script lang="ts" setup>
/** 会话列表Item 外漏消息组件 */
import { computed } from 'vue'
import Icon from '@/components/Icon.vue'
import { V2NIMConst } from '@/utils/im/nim'
import { t } from '@/utils/im/i18n'
import { V2NIMLastMessage } from 'nim-web-sdk-ng/dist/esm/nim/src/V2NIMConversationService'
import { EMOJI_ICON_MAP_CONFIG, emojiRegExp } from '@/utils/im/emoji'
import { isWxApp } from '@/utils/im/index'
const props = withDefaults(
  defineProps<{
    lastMessage: V2NIMLastMessage
  }>(),
  {}
)

/** 筛选出文本和表情 */
const parseTextWithEmoji = (text: string) => {
  if (!text) return []
  const matches: {
    type: 'emoji' | 'text'
    value: string
    index: number
  }[] = []
  let match
  const regexEmoji = emojiRegExp

  while ((match = regexEmoji.exec(text)) !== null) {
    matches.push({
      type: 'emoji',
      value: match[0],
      index: match.index,
    })
    const fillText = ' '.repeat(match[0].length)
    text = text.replace(match[0], fillText)
  }

  text = text.replace(regexEmoji, ' ')

  if (text) {
    text
      .split(' ')
      .filter((item) => item.trim())
      .map((item) => {
        const index = text?.indexOf(item)
        matches.push({
          type: 'text',
          value: item,
          index,
        })
        const fillText = ' '.repeat(item.length)
        text = text.replace(item, fillText)
      })
  }

  return matches
    .sort((a, b) => a.index - b.index)
    .map((item, index) => {
      return {
        ...item,
        key: index + item.type,
      }
    })
}

/** 解析的消息数组 */
const textArr = computed(() => {
  return parseTextWithEmoji(props.lastMessage.text as string)
})

/** 消息映射 */
const translateMsg = (key: string): string => {
  const text =
    {
      textMsgText: t('textMsgText'),
      customMsgText: t('customMsgText'),
      audioMsgText: t('audioMsgText'),
      videoMsgText: t('videoMsgText'),
      fileMsgText: t('fileMsgText'),
      callMsgText: t('callMsgText'),
      geoMsgText: t('geoMsgText'),
      imgMsgText: t('imgMsgText'),
      notiMsgText: t('notiMsgText'),
      robotMsgText: t('robotMsgText'),
      tipMsgText: t('tipMsgText'),
      unknowMsgText: t('unknowMsgText'),
    }[key] || ''
  return `[${text}]`
}
</script>

<style scoped lang="scss">
.wrapper {
  flex: 1;
  font-size: 13px;
  width: 100%;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.msg-conversation-text {
  font-size: 13px !important;
  height: 22px;
  line-height: 22px;
  width: 100%;
  display: inline;
}

.msg-conversation-text-wrap {
  width: 80%;
  line-height: 22px;
  height: 22px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: 14px;
  overflow: hidden;
}
.msg-conversation-text-emoji {
  display: inline-flex;
  width: 18px;
  height: 18px;
  box-sizing: border-box;
  align-items: center;
  justify-content: center;
}

.msg-conversation-text-emoji-wx {
  display: inline-flex;
  width: 18px;
  height: 18px;
  box-sizing: border-box;
  align-items: center;
  justify-content: center;
  position: relative;
  bottom: 4px;
}
</style>
