<script lang="ts" setup>
import { AiAnswerProvideKey } from './type'
import AnswerLoading from './components/AnswerLoading/index.vue'
import { fetchQueryRecommendQuestion } from '@/api/answer'

const props = withDefaults(defineProps<Props>(), {
  animated: false,
  isShow: false,
  isLastAnswer: false,
  conversationId: '',
  recordId: '',
})

const emits = defineEmits([
  'onAnswerConcatEnd', // Answer的stream拼接完成
  'onAttachmentConcatEnd', // Attachment的stream拼接完成
  'onTypingEnd', // Answer打字机输出结束
  'onClickBoxProductItem', // 点击产品列表中的产品
  'onClickLikeItem', // 点击了猜你想问
  'onClickStop', // 点击停止生成
  'onFullEnd', // 所有内容输出完成
  'onClickReload', // 点击重新生成
  'onLastAnswer', // 上一条答案
  'onNextAnswer', // 下一条答案
])

const attachmentTypes = ['box', 'card-detail', 'card-calculation', 'card-nav', 'card-product-compare', 'card-plans']

interface Props {
  streamData: any[]
  animated?: boolean
  isShow?: boolean
  isLastAnswer?: boolean
  conversationId?: string
  recordId?: string
  answerList: any[]
  curIdx: number
}

// const isLoading = ref(true)

const isLoading = computed(() => {
  if (props.isShow)
    return false
  else if (props.streamData.length === 0)
    return true
  else
    return false
})

const recordId = ref('')

const isAnswerConcatEnd = ref(false)
const isAttachmentConcatEnd = ref(false)
const isTypingEnd = ref(false)

const streamAttachment = computed(() => {
  return props.streamData.map((item: any) => item.attachmentList || []).flat()
})

const streamAnswer = computed(() => {
  return props.streamData.map((item: any) => item.answer).join('') + streamAttachment.value.map((item: any) => attachmentTypes.includes(item.type) ? item.description : '').join('')
})

const spicAttachmentsLen = computed(() => streamAttachment.value.filter(item => attachmentTypes.includes(item.type)).length)

const collectionFlag = computed(() => {
  if (props.isShow)
    return props.streamData[0]?.collectionFlag || false

  return false
})

const terminateFlag = computed(() => {
  if (props.isShow)
    return props.streamData[0]?.terminateFlag || false

  return false
})

const likeFlag = computed(() => {
  if (props.isShow)
    return props.streamData[0]?.feedbackStatus === '01' || false
  return false
})

const unLikeFlag = computed(() => {
  if (props.isShow)
    return props.streamData[0]?.feedbackStatus === '02' || false
  return false
})

const productCode = computed(() => {
  if (props.isShow)
    return props.streamData[0]?.productCode || ''

  return ''
})

const isShowOperate = ref(false)

const isShowAttachment = ref(false)

const isShowGuessULike = ref(false)

function onTypingEnd(data: any) {
  emits('onTypingEnd')

  isTypingEnd.value = true
  // if (data && !data.isStop) {
  // isShowAttachment.value = true
  // getGuessULikeList()
  // isShowOperate.value = true
  // }
  // emits('onAnswerConcatEnd')
  if (data?.isStop) {
    isShowOperate.value = true
    emits('onAnswerConcatEnd')
  }
  else {
    isShowAttachment.value = true
    getGuessULikeList()
    isShowOperate.value = true
    emits('onAnswerConcatEnd')
  }
}

const guessULikeList = ref<string[]>([])
const guessULikeLoading = ref(false)
async function getGuessULikeList() {
  guessULikeLoading.value = true
  if (!props.conversationId && !props.isShow)
    return
  // 获取猜你喜欢列表
  const res = await fetchQueryRecommendQuestion(props.conversationId, props.recordId)
  if (res.data) {
    guessULikeList.value = res.data.questionList
    isShowGuessULike.value = true
  }

  guessULikeLoading.value = false

  emits('onFullEnd')
}

function onClickBoxProductItem(item: any) {
  emits('onClickBoxProductItem', item)
}

function onClickLikeItem(item: any) {
  emits('onClickLikeItem', item)
}

const isShowSourceFile = ref(false)
const sourceFileList = ref<any[]>([])

function onSourceFileParserEnd(data: string[]) {
  const referenceData = streamAttachment.value.find(item => item.type === 'reference')
  if (referenceData) {
    const trueData = referenceData.content.docList.filter((item: any) => data.includes(item.docName))
    if (trueData.length > 0) {
      sourceFileList.value = trueData
      isShowSourceFile.value = true
    }
  }
}

const answerParserRef = ref()

const isStop = ref(false)

function onClickStop() {
  isStop.value = true
  isAnswerConcatEnd.value = true
  answerParserRef.value?.onClickStop()
  if (props.streamData.length !== 0)
    isShowOperate.value = true

  emits('onClickStop')
}

function onClickReload() {
  emits('onClickReload')
}

watch(() => props.streamData, (newVal) => {
  if (newVal.length === 0)
    return
  if (newVal[newVal.length - 1]?.endAnswerFlag) {
    isAnswerConcatEnd.value = true
    emits('onAnswerConcatEnd')
  }
  if (newVal[newVal.length - 1]?.endAttachmentFlag) {
    isAttachmentConcatEnd.value = true
    emits('onAttachmentConcatEnd')
  }
  recordId.value = newVal[newVal.length - 1]?.recordId
}, {
  deep: true,
  immediate: true,
})

function onLastAnswer() {
  emits('onLastAnswer')
}
function onNextAnswer() {
  emits('onNextAnswer')
}

const stopAnswerCount = inject('stopAnswerCount')

watch(() => stopAnswerCount, () => {
  if (!props.isShow && !isTypingEnd.value)
    onClickStop()
}, {
  deep: true,
})

provide(AiAnswerProvideKey, {
  animated: props.animated,
  productCode,
  collectionFlag,
  likeFlag,
  unLikeFlag,
  isShow: props.isShow,
})

defineExpose({
  onClickStop,
})
</script>

<template>
  <div class="ai-answer-wrap">
    <div class="ai-answer-inner" :style="{ width: (isTypingEnd || props.isShow) ? '100%' : 'fit-content' }">
      <!-- <img class="arrow" src="@/assets/images/msgArrow-ai.png" alt=""> -->
      <!--  -->
      <div v-if="isLoading && !isStop" class="loading">
        <AnswerLoading />
        <!-- <img src="@/assets/images/askLoading.gif" alt=""> -->
      </div>
      <div class="ai-answer__inner">
        <div class="answer-content">
          <AnswerParser v-if="!props.isShow" ref="answerParserRef" :is-end="isAnswerConcatEnd" :stream-answer="streamAnswer" @on-source-file-parser-end="onSourceFileParserEnd" @on-typing-end="onTypingEnd" />
          <AnswerShower v-if="props.isShow" :stream-answer="streamAnswer" @on-source-file-parser-end="onSourceFileParserEnd" />
        </div>
        <div v-if="isShowAttachment || isShow" class="attachment-content">
          <AttachmentParser :stream-attachment="streamAttachment" @on-click-box-product-item="onClickBoxProductItem" />
        </div>
        <!-- <div v-if="sourceFileList.length !== 0">
          <ItemReference :data="sourceFileList" />
        </div> -->
        <div v-if="(isShowOperate || isShow) && spicAttachmentsLen === 0" class="answer-operate">
          <!-- 操作栏 -->
          <OperateBar :is-last-answer="props.isLastAnswer" :stream-answer="streamAnswer" :record-id="recordId" @on-click-reload="onClickReload" />
        </div>
      </div>

      <div v-if="props.answerList?.length !== 1 && (isTypingEnd || props.isShow)" class="pagination-wrap">
        <SvgIcon :style="{ opacity: props.curIdx === 0 ? 0.3 : 1 }" size="10px" name="arrowGreen" @click="onLastAnswer" />
        <span>{{ props.curIdx + 1 }}/{{ props.answerList?.length }}</span>
        <SvgIcon :style="{ opacity: curIdx === props.answerList?.length - 1 ? 0.3 : 1 }" style="transform: rotate(180deg);" size="10px" name="arrowGreen" @click="onNextAnswer" />
      </div>
    </div>
    <!-- <div v-if="!props.isShow && !isTypingEnd" class="stop-btn" @click="onClickStop">
      <div>
        <img src="@/assets/images/stop-icon.png" alt="">
        <span>停止生成</span>
      </div>
    </div> -->
    <div v-if="(!props.isShow && isTypingEnd && isStop) || terminateFlag" class="stopped-text">
      已停止生成
    </div>
    <!-- && !isShow -->
    <div class="answer-guess">
      <div class="answer-guess-loading">
        <AnswerLoading v-if="guessULikeLoading" />
      </div>
      <GuessULike v-if="isShowGuessULike" :question-list="guessULikeList" @on-click-like-item="onClickLikeItem" />
    </div>
  </div>
</template>

<style lang="scss" scoped>
.answer-guess-loading {
  padding-left: 24px;
  margin-top: 16px;
  display: flex;
}
.pagination-wrap {
  font-family: alir, AlibabaPuHuiTi_2_55_Regular;
  font-size: 12px;
  color: rgba(57, 61, 70, 0.7);
  line-height: 16px;
  text-align: left;
  font-style: normal;
  position: absolute;
  right: 12px;
  bottom: 22px;
  display: flex;
  align-items: center;
  > span {
    margin: 0 6px;
  }
}
.stopped-text {
  font-family:
    PingFangSC,
    PingFang SC;
  font-weight: 400;
  font-size: 12px;
  color: #b2b8c1;
  line-height: 16px;
  text-align: left;
  font-style: normal;
  margin-top: 12px;
}
.stop-btn {
  margin-top: 12px;
  display: flex;
  align-items: center;
  font-weight: 400;
  font-size: 12px;
  color: #74d8c9;
  line-height: 16px;
  text-align: left;
  font-style: normal;
  > div {
    display: flex;
    align-items: center;
  }
  img {
    width: 12px;
    height: 12px;
    margin-right: 4px;
    margin-left: 12px;
  }
}
.answer-operate {
  display: flex;
  align-items: center;
}
.ai-answer-inner {
  background: #ffffff;
  border-radius: 12px;
  font-family:
    alir,
    PingFangSC,
    PingFang SC;
  font-weight: 400;
  font-size: 14px;
  color: #393d46;
  line-height: 22px;
  text-align: justify;
  font-style: normal;
  box-sizing: border-box;
  padding: 12px;
  position: relative;

  background: #ffffff;
  box-shadow: 0px 2px 4px 0px rgba(236, 242, 248, 0.3);
  border-radius: 0px 16px 16px 16px;
  border: 1px solid #ffffff;
  .loading {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    img {
      width: 20px;
      height: 20px;
    }
  }
  .arrow {
    position: absolute;
    width: 8px;
    height: 14px;
    left: -8px;
    top: 12px;
  }
}
</style>
