<script setup lang="ts">
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import CustomLoading from './custom-loading.vue'
import MusicWavesLoading from './music-waves-loading.vue'
import MarkdownRender from '@/components/markdown-render/markdown-render.vue'
import { PersonalAppConfigState } from '@/store/types/personal-app-config'
import { useLayoutConfig } from '@/composables/useLayoutConfig'
import { useUserStore } from '@/store/modules/user'

interface Props {
  role: 'user' | 'assistant'
  messageItem: ConversationMessageItem
  agentApplicationConfig: PersonalAppConfigState
}

const { t } = useI18n()

const props = defineProps<Props>()

const emit = defineEmits<{
  audioPlay: []
  audioPause: []
}>()

const userStore = useUserStore()

const { isMobile } = useLayoutConfig()

const useAvatar = computed(() => {
  return userStore.userInfo.avatarUrl || 'https://gsst-poe-sit.gz.bcebos.com/data/20240910/1725952917468.png'
})

const assistantAvatar = computed(() => {
  return (
    props.agentApplicationConfig.baseInfo.agentAvatar ||
    'https://gsst-poe-sit.gz.bcebos.com/data/20240911/1726041369632.webp'
  )
})

const timbreEnabled = computed(() => {
  return !!props.agentApplicationConfig.voiceConfig.timbreId
})

const isShowAudioControl = computed(() => {
  return props.role === 'assistant' && !props.messageItem.isVoiceLoading && timbreEnabled.value
})

const isPlayableAudio = computed(() => {
  return isShowAudioControl.value && !!props.messageItem.voiceFragmentUrlList.length
})

const isShowWebVoiceLoading = computed(() => {
  return props.role === 'assistant' && !isMobile.value && props.messageItem.isVoiceLoading && timbreEnabled.value
})

const isShowMobileLoading = computed(() => {
  return (
    props.role === 'assistant' &&
    (props.messageItem.isAnswerResponseLoading ||
      (isMobile.value && props.messageItem.isVoiceLoading && timbreEnabled.value))
  )
})

function handleAudioControl() {
  if (!isPlayableAudio.value) {
    return
  }

  if (props.messageItem.isVoicePlaying) {
    emit('audioPause')
  } else {
    emit('audioPlay')
  }
}
</script>

<template>
  <div
    class="mb-5 flex last:mb-0"
    :class="[
      isMobile ? 'flex-row-reverse' : 'flex-row',
      role === 'assistant' && isMobile ? 'justify-end' : 'justify-start',
    ]"
  >
    <NImage
      v-show="!isMobile"
      :src="role === 'user' ? useAvatar : assistantAvatar"
      preview-disabled
      :width="32"
      :height="32"
      object-fit="cover"
      class="mr-2 mt-1.5 h-8 w-8 flex-shrink-0 rounded-full"
    />

    <div class="flex w-full flex-col" :class="isMobile && role === 'user' ? 'items-end' : 'items-start'">
      <div
        class="min-w-[80px] flex-wrap rounded-xl border border-[#e8e9eb] px-4 py-[11px]"
        :class="[
          role === 'user' ? 'bg-theme-color text-white' : 'bg-white text-[#333]',
          isMobile ? 'max-w-[calc(100%-20px)]' : 'max-w-full',
        ]"
      >
        <div v-if="messageItem.isTextContentLoading" class="py-1.5 pl-4">
          <CustomLoading />
        </div>

        <div v-else>
          <p class="break-all">
            <MarkdownRender
              :raw-text-content="
                messageItem.isEmptyContent
                  ? t('common_module.dialogue_module.empty_message_content')
                  : messageItem.textContent
              "
              :color="role === 'user' ? '#fff' : '#192338'"
            />
          </p>

          <div v-show="isShowMobileLoading" class="mb-[5px] mt-4 px-4">
            <CustomLoading />
          </div>
        </div>

        <div v-show="isShowAudioControl && isMobile" class="mt-[13px] flex items-center gap-2">
          <div
            class="h-[18px] w-[18px] cursor-pointer"
            :class="messageItem.isVoicePlaying ? 'bg-svg-pause' : 'bg-svg-play'"
            @click="handleAudioControl"
          />

          <MusicWavesLoading v-show="messageItem.isVoicePlaying && isPlayableAudio" bar-bg-color="#333" />

          <n-popover style="max-width: 310px">
            <template #trigger>
              <span v-show="!isPlayableAudio" class="text-[12px]"> {{ t('common_module.unplayable') }} </span>
            </template>
            {{ t('common_module.unplayable_tip') }}
          </n-popover>
        </div>
      </div>

      <div
        v-show="isShowAudioControl && !isMobile"
        class="text-font-color flex items-center gap-0.5"
        :class="isPlayableAudio ? 'hover:text-theme-color cursor-pointer hover:opacity-80' : 'cursor-not-allowed'"
        @click="handleAudioControl"
      >
        <i v-if="!messageItem.isVoicePlaying" class="iconfont icon-play text-[24px]" />
        <div v-else class="mx-1.5 my-3 h-[12px] w-[12px] bg-[url(@/assets/images/playing.gif)] bg-[length:100%_100%]" />

        <span
          v-show="isPlayableAudio"
          class="text-[12px]"
          :class="messageItem.isVoicePlaying ? 'text-theme-color' : ''"
        >
          {{ messageItem.isVoicePlaying ? t('common_module.stop_playing') : t('common_module.start_playing') }}
        </span>
        <n-popover style="max-width: 310px">
          <template #trigger>
            <span v-show="!isPlayableAudio" class="text-[12px]"> {{ t('common_module.unplayable') }} </span>
          </template>
          {{ t('common_module.unplayable_tip') }}
        </n-popover>
      </div>

      <div v-if="isShowWebVoiceLoading" class="py-3.5 pl-5">
        <CustomLoading />
      </div>
    </div>
  </div>
</template>
