<template>
  <div :class="['message-text-container', isPC && 'text-select']">
    <span v-for="(item, index) in processedContent" :key="index">
      <span
        v-if="item.name === 'text'"
        :style="{ 'font-size': `${fontSizeData}rpx` }"
        class="text"
      >
        {{ item.text }}
      </span>
      <span
        v-else-if="item.name === 'url'"
        :style="{ 'font-size': `${fontSizeData}rpx` }"
        class="url-link"
        @click="navigateToUrl(item.url)"
      >
        {{ item.text }}
      </span>
      <img v-else class="emoji" :src="item.src" :alt="item.emojiKey" />
    </span>
  </div>
</template>

<script lang="ts" setup>
  import { watch, ref } from '../../../../adapter-vue'
  import {
    TUIStore,
    IMessageModel,
    TUIReportService
  } from '@tencentcloud/chat-uikit-engine-lite'
  import {
    TUIGlobal,
    parseTextAndValidateUrls
  } from '@tencentcloud/universal-api'
  import {
    CUSTOM_BASIC_EMOJI_URL,
    CUSTOM_BASIC_EMOJI_URL_MAPPING
  } from '../../emoji-config'
  import { isPC, isUniFrameWork } from '../../../../utils/env'
  import { useAuthUser } from '../../../../../composables/useAuthUser'

  const { fontSizeData } = useAuthUser()

  interface IProps {
    content: Record<string, any>
    messageItem: IMessageModel
    enableURLHighlight?: boolean
  }

  interface TextItem {
    name: string
    text: string
    src?: string
    type?: string
    emojiKey?: string
    url?: string
  }

  interface URLSegment {
    type: string
    text: string
    url?: string
  }

  const props = withDefaults(defineProps<IProps>(), {
    content: () => ({}),
    messageItem: () => ({}) as IMessageModel,
    enableURLHighlight: false
  })

  const processedContent = ref<TextItem[]>([])

  const YXDIM_SCHEMA_REGEXP = /((https?|yxdim):\/\/[^\s]+)/g

  function splitYxdimSchema(text: string): URLSegment[] {
    if (!text) {
      return []
    }

    const result: URLSegment[] = []
    let lastIndex = 0
    const matches = text.matchAll(YXDIM_SCHEMA_REGEXP)

    for (const match of matches) {
      const matchedText = match[0]
      const startIndex = match.index ?? -1
      if (startIndex < 0) {
        continue
      }

      if (startIndex > lastIndex) {
        result.push({
          type: 'text',
          text: text.slice(lastIndex, startIndex)
        })
      }

      result.push({
        type: 'url',
        text: matchedText,
        url: matchedText
      })
      lastIndex = startIndex + matchedText.length
    }

    if (!result.length) {
      return [{ type: 'text', text }]
    }

    if (lastIndex < text.length) {
      result.push({
        type: 'text',
        text: text.slice(lastIndex)
      })
    }

    return result
  }

  function parseMessageTextWithLinks(text: string): URLSegment[] {
    if (!parseTextAndValidateUrls) {
      console.warn(
        'parseTextAndValidateUrls not found. Please update @tencentcloud/universal-api to 2.3.7 or higher.'
      )
      return splitYxdimSchema(text)
    }

    const segments = parseTextAndValidateUrls(text)
    if (!segments?.length) {
      return splitYxdimSchema(text)
    }

    return segments
      .map((segment: URLSegment) => {
        if (segment.type !== 'text') {
          return [segment]
        }
        return splitYxdimSchema(segment.text)
      })
      .flat()
  }

  watch(
    () => props.messageItem,
    (newValue: IMessageModel, oldValue?: IMessageModel) => {
      if (newValue?.ID === oldValue?.ID) {
        return
      }
      console.log('messageItem=========', newValue)
      if (props.enableURLHighlight) {
        TUIReportService.reportFeature(208)
      }

      if (props.messageItem.getMessageContent) {
        processedContent.value =
          props.messageItem.getMessageContent()?.text
      } else {
        processedContent.value = TUIStore.getMessageModel(
          props.messageItem.ID
        )?.getMessageContent()?.text
      }

      processedContent.value =
        processedContent.value || props.content?.text

      if (!processedContent.value?.length) {
        processedContent.value = []
        return
      }

      processedContent.value = processedContent.value
        .map((item: TextItem) => {
          // handle custom emoji
          if (item.name === 'img' && item?.type === 'custom') {
            if (!CUSTOM_BASIC_EMOJI_URL) {
              console.warn(
                'CUSTOM_BASIC_EMOJI_URL is required for custom emoji.'
              )
              return item
            }
            if (
              !item.emojiKey ||
              !CUSTOM_BASIC_EMOJI_URL_MAPPING[item.emojiKey]
            ) {
              console.warn('emojiKey is required for custom emoji.')
              return item
            }
            return {
              ...item,
              src:
                CUSTOM_BASIC_EMOJI_URL +
                CUSTOM_BASIC_EMOJI_URL_MAPPING[item.emojiKey]
            }
          }

          // handle url
          if (
            props.enableURLHighlight &&
            item.name === 'text' &&
            item.text
          ) {
            const segments = parseMessageTextWithLinks(item.text)
            console.log('segments=========', segments)
            if (segments.length) {
              return segments.map(segment => ({
                name: segment.type,
                text: segment.text,
                url: segment.url
              }))
            }
          }

          return item
        })
        ?.flat()
    },
    {
      deep: true,
      immediate: true
    }
  )

  // Function to handle navigation
  function navigateToUrl(url?: string) {
    if (url) {
      if (/^https?:\/\//i.test(url)) {
        TUIGlobal.open(url, '_blank')
        return
      }

      if (/^yxdim:\/\//i.test(url)) {
        if (isUniFrameWork) {
          const appPath = url.replace(/^yxdim:\/\//i, '/')
          TUIGlobal.navigateTo({
            url: appPath
          })
          return
        }

        TUIGlobal.open(url, '_self')
        return
      }

      if (isUniFrameWork) {
        TUIGlobal.navigateTo({
          url
        })
      } else {
        TUIGlobal.open(url, '_blank')
      }
    }
  }
</script>

<style lang="scss" scoped>
  .message-text-container {
    display: inline;
    font-size: 0;
    letter-spacing: -1px;
  }

  .text-select {
    -webkit-user-select: text;
    -moz-user-select: text;
    -ms-user-select: text;
    user-select: text;
  }

  .text,
  .emoji,
  .url-link {
    &::selection {
      background-color: #b4d5fe;
      color: inherit;
      cursor: text;
    }
  }

  .emoji {
    font-size: 0;
    vertical-align: bottom;
    width: 20px;
    height: 20px;
  }

  .text,
  .url-link {
    white-space: pre-wrap;
    word-break: break-all;
    letter-spacing: normal;
  }

  .url-link {
    color: #0366d6;
    text-decoration: none;
    word-break: break-all;
    cursor: text;

    &:hover:not(:active) {
      cursor: pointer;
    }

    &:visited {
      color: #0366d6;
    }
  }
</style>
