<script setup lang="ts">
import { message } from 'ant-design-vue'
import ChatItem from './components/ChatItem.vue'
import DefaultChatItem from './components/DefaultChatItem.vue'
import { buildUUID } from '../utils/uuid'
import { onMounted, ref, nextTick, unref, onUnmounted, computed,onBeforeUnmount, reactive } from 'vue'
import { MRTCService } from '../utils/MRTCService'
import { getUserIdByAuthCode, OperateTheRoom, pictureLocal } from '../api/auth.js'
import { useRoomStore } from '../stores'
// 引入swiper
import { register } from 'swiper/element/bundle'
import InitModal from './components/InitModal.vue'
import ImageCompressor from 'js-image-compressor'
register()

const roomStore = useRoomStore()
let swiper = ref(null)  // 引用 swiper 实例
const value = ref('')
const keyboardOpen = ref(false)
const voiceOpen = ref(false)
const cameraOpen = ref(false)
const activeIndex = ref(0)
const swiperFirstContainer = ref(null)
const swiperSecondContainer = ref(null)

const initRef = ref(null)
const connectionStatus = ref(true)
const introducedStatus = ref(false)

let userId = ref('')
const fileInput = ref(null)
let imageSrc = ref('')
const openCamera = ref(false)

// 翻页
const spaceBetween = 10
const onProgress = (e) => {
  const [ swiper, progress ] = e.detail
  // console.log( progress)
  if (progress === 0 || progress === 1) {
    activeIndex.value = progress
    // 初次加载时滚动到底部
    scrollToBottom()
  }
}

function useDebounce(fn, delay) {
  let timeoutId = null
  return function(...args) {
    clearTimeout(timeoutId)
    timeoutId = setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}
function useThrottle(func, wait) {
  let timeout // 定义一个计时器变量，用于限制函数调用频率
  return function (...args) { // 返回一个包装后的函数
    const context = this // 保存函数执行上下文对象
    if (!timeout) { // 如果计时器不存在
      func.apply(context, args) // 执行函数
      timeout = setTimeout(() => {
        timeout = null // 清空计时器变量
      }, wait) // 创建计时器，在指定时间后重置计时器变量
    }
  }
}

const scrollToBottom = useThrottle(function() {
  // 获取容器的 DOM 节点并滚动到底部
  nextTick(() => {
    const swiperContainer = unref(activeIndex) === 0 ? unref(swiperFirstContainer) : unref(swiperSecondContainer)
    swiperContainer.scrollTop = swiperContainer?.scrollHeight || 0  // 设置scrollTop为scrollHeight，滚动到最底部
  })
}, 250)

const authCode = ref('')

let voiceMap = ref(new Map())
let newVoice = reactive({
  sessionId: '', // 最新的一条问答id
  queryId: '', // 最新的一条queryId
  isQuestionLoading: false, // 是否已经语音识别中
  isAnswerStart: false, // 是否已经回答开始
  isAnswerEnd: false, // 是否已经回答结束
  interrupted: false, //是否被打断
  answerList: []
})
const answeringObj = ref({}) // 正在播放
const answerEndMap = reactive(new Map()) // 结束播放
const answerWaitMap = reactive(new Map()) // 等待播放
const answerDisplayedTextMap = reactive(new Map()) // 已播放的文本map
const timerArr = ref([])

const answerDisplayedTextMapStr = computed(() => {
  // 将 Map 的键值对转换为数组，并按键进行排序
  return Array.from(answerDisplayedTextMap.entries()).map(([ key, item ], index)=>{
    return item
  }).join('')
})

const voiceMapEntries = computed(() => {
  return [ ...unref(voiceMap) ]
})

const lastVoiceObj = computed(() => {
  const lastSessionId = [ ...unref(voiceMap).keys() ].pop()
  console.log(lastSessionId, unref(voiceMap).get(lastSessionId))
  return unref(voiceMap).get(lastSessionId)
})

function add(code) {
  if (code == 'asrChange') {
    onCallback('asrChange', {
      asrChange: {
        text: '讲讲南宋。。。。'
      }
    })
  }
  if (code == 'asrEnd') {
    onCallback('asrEnd', {
      asrEnd: {
        text: '讲讲南宋的故事'
      }
    })
  }
  if (code == 'subtitle1') {
    onCallback('subtitle',
        {
          'duration': 4087,
          'finalRequest': false,
          'wholeEnglish': false,
          'timelines': [
            {
              'data': '南',
              'endIndex': 1,
              'endTime': 542,
              'sentence': false,
              'startIndex': 0,
              'startTime': 402
            },
            {
              'data': '宋',
              'endIndex': 2,
              'endTime': 723,
              'sentence': false,
              'startIndex': 1,
              'startTime': 583
            },
            {
              'data': '的',
              'endIndex': 3,
              'endTime': 784,
              'sentence': false,
              'startIndex': 2,
              'startTime': 723
            },
            {
              'data': '故',
              'endIndex': 4,
              'endTime': 904,
              'sentence': false,
              'startIndex': 3,
              'startTime': 844
            },
            {
              'data': '事',
              'endIndex': 5,
              'endTime': 1125,
              'sentence': false,
              'startIndex': 4,
              'startTime': 1025
            },
            {
              'data': '同',
              'endIndex': 6,
              'endTime': 1427,
              'sentence': false,
              'startIndex': 5,
              'startTime': 1226
            },
            {
              'data': '样',
              'endIndex': 7,
              'endTime': 1628,
              'sentence': false,
              'startIndex': 6,
              'startTime': 1447
            },
            {
              'data': '精',
              'endIndex': 8,
              'endTime': 1789,
              'sentence': false,
              'startIndex': 7,
              'startTime': 1648
            },
            {
              'data': '彩',
              'endIndex': 9,
              'endTime': 1970,
              'sentence': false,
              'startIndex': 8,
              'startTime': 1809
            },
            {
              'data': '纷',
              'endIndex': 10,
              'endTime': 2131,
              'sentence': false,
              'startIndex': 9,
              'startTime': 2010
            },
            {
              'data': '呈',
              'endIndex': 11,
              'endTime': 2352,
              'sentence': false,
              'startIndex': 10,
              'startTime': 2171
            },
            {
              'data': '你',
              'endIndex': 12,
              'endTime': 2613,
              'sentence': false,
              'startIndex': 11,
              'startTime': 2552
            },
            {
              'data': '想',
              'endIndex': 13,
              'endTime': 2835,
              'sentence': false,
              'startIndex': 12,
              'startTime': 2673
            },
            {
              'data': '了',
              'endIndex': 14,
              'endTime': 2935,
              'sentence': false,
              'startIndex': 13,
              'startTime': 2855
            },
            {
              'data': '解',
              'endIndex': 15,
              'endTime': 3137,
              'sentence': false,
              'startIndex': 14,
              'startTime': 3036
            },
            {
              'data': '哪',
              'endIndex': 16,
              'endTime': 3258,
              'sentence': false,
              'startIndex': 15,
              'startTime': 3198
            },
            {
              'data': '个',
              'endIndex': 17,
              'endTime': 3399,
              'sentence': false,
              'startIndex': 16,
              'startTime': 3339
            },
            {
              'data': '方',
              'endIndex': 18,
              'endTime': 3581,
              'sentence': false,
              'startIndex': 17,
              'startTime': 3440
            },
            {
              'data': '面',
              'endIndex': 19,
              'endTime': 3763,
              'sentence': false,
              'startIndex': 18,
              'startTime': 3601
            },
            {
              'data': '的',
              'endIndex': 20,
              'endTime': 3803,
              'sentence': false,
              'startIndex': 19,
              'startTime': 3763
            },
            {
              'data': '呢',
              'endIndex': 21,
              'endTime': 3924,
              'sentence': false,
              'startIndex': 20,
              'startTime': 3843
            },
            {
              'endIndex': 21,
              'endTime': 4087,
              'sentence': true,
              'startIndex': 0,
              'startTime': 0
            }
          ],
          'sourceType': 'reply',
          'sortId': 0,
          'oriText': '南宋的故事同样精彩纷呈，你想了解哪个方面的呢？',
          'textIndex': 0,
          'command': 'subtitle',
          'queryId': '90ad25a1d33845ed83e22a3c81bf663d_c',
          'order': 0
        },)
  }
  if (code == 'subtitle2') {
    onCallback('subtitle',
        {
          'duration': 5214,
          'finalRequest': false,
          'wholeEnglish': false,
          'timelines': [
            {
              'data': '是',
              'endIndex': 1,
              'endTime': 261,
              'sentence': false,
              'startIndex': 0,
              'startTime': 160
            },
            {
              'data': '关',
              'endIndex': 2,
              'endTime': 482,
              'sentence': false,
              'startIndex': 1,
              'startTime': 341
            },
            {
              'data': '于',
              'endIndex': 3,
              'endTime': 562,
              'sentence': false,
              'startIndex': 2,
              'startTime': 502
            },
            {
              'data': '那',
              'endIndex': 4,
              'endTime': 683,
              'sentence': false,
              'startIndex': 3,
              'startTime': 623
            },
            {
              'data': '些',
              'endIndex': 5,
              'endTime': 844,
              'sentence': false,
              'startIndex': 4,
              'startTime': 763
            },
            {
              'data': '英',
              'endIndex': 6,
              'endTime': 1065,
              'sentence': false,
              'startIndex': 5,
              'startTime': 924
            },
            {
              'data': '勇',
              'endIndex': 7,
              'endTime': 1246,
              'sentence': false,
              'startIndex': 6,
              'startTime': 1105
            },
            {
              'data': '的',
              'endIndex': 8,
              'endTime': 1346,
              'sentence': false,
              'startIndex': 7,
              'startTime': 1266
            },
            {
              'data': '抗',
              'endIndex': 9,
              'endTime': 1748,
              'sentence': false,
              'startIndex': 8,
              'startTime': 1447
            },
            {
              'data': '金',
              'endIndex': 10,
              'endTime': 1929,
              'sentence': false,
              'startIndex': 9,
              'startTime': 1788
            },
            {
              'data': '名',
              'endIndex': 11,
              'endTime': 2130,
              'sentence': false,
              'startIndex': 10,
              'startTime': 1969
            },
            {
              'data': '将',
              'endIndex': 12,
              'endTime': 2351,
              'sentence': false,
              'startIndex': 11,
              'startTime': 2170
            },
            {
              'data': '还',
              'endIndex': 13,
              'endTime': 2632,
              'sentence': false,
              'startIndex': 12,
              'startTime': 2471
            },
            {
              'data': '是',
              'endIndex': 14,
              'endTime': 2794,
              'sentence': false,
              'startIndex': 13,
              'startTime': 2713
            },
            {
              'data': '那',
              'endIndex': 15,
              'endTime': 2894,
              'sentence': false,
              'startIndex': 14,
              'startTime': 2834
            },
            {
              'data': '些',
              'endIndex': 16,
              'endTime': 3035,
              'sentence': false,
              'startIndex': 15,
              'startTime': 2955
            },
            {
              'data': '流',
              'endIndex': 17,
              'endTime': 3257,
              'sentence': false,
              'startIndex': 16,
              'startTime': 3116
            },
            {
              'data': '传',
              'endIndex': 18,
              'endTime': 3519,
              'sentence': false,
              'startIndex': 17,
              'startTime': 3317
            },
            {
              'data': '千',
              'endIndex': 19,
              'endTime': 3821,
              'sentence': false,
              'startIndex': 18,
              'startTime': 3600
            },
            {
              'data': '古',
              'endIndex': 20,
              'endTime': 4003,
              'sentence': false,
              'startIndex': 19,
              'startTime': 3902
            },
            {
              'data': '的',
              'endIndex': 21,
              'endTime': 4184,
              'sentence': false,
              'startIndex': 20,
              'startTime': 4103
            },
            {
              'data': '诗',
              'endIndex': 22,
              'endTime': 4506,
              'sentence': false,
              'startIndex': 21,
              'startTime': 4386
            },
            {
              'data': '词',
              'endIndex': 23,
              'endTime': 4688,
              'sentence': false,
              'startIndex': 22,
              'startTime': 4587
            },
            {
              'data': '歌',
              'endIndex': 24,
              'endTime': 4829,
              'sentence': false,
              'startIndex': 23,
              'startTime': 4748
            },
            {
              'data': '赋',
              'endIndex': 25,
              'endTime': 5030,
              'sentence': false,
              'startIndex': 24,
              'startTime': 4930
            },
            {
              'endIndex': 25,
              'endTime': 5214,
              'sentence': true,
              'startIndex': 0,
              'startTime': 0
            }
          ],
          'sourceType': 'reply',
          'sortId': 1,
          'oriText': '是关于那些英勇的抗金名将，还是那些流传千古的诗词歌赋，',
          'textIndex': 1,
          'command': 'subtitle',
          'queryId': '90ad25a1d33845ed83e22a3c81bf663d_c',
          'order': 0
        })
  }
  if (code == 'subtitle3') {
    onCallback('subtitle',
        {
          'duration': 4749,
          'finalRequest': false,
          'wholeEnglish': false,
          'timelines': [
            {
              'data': '或',
              'endIndex': 1,
              'endTime': 120,
              'sentence': false,
              'startIndex': 0,
              'startTime': 60
            },
            {
              'data': '者',
              'endIndex': 2,
              'endTime': 261,
              'sentence': false,
              'startIndex': 1,
              'startTime': 180
            },
            {
              'data': '是',
              'endIndex': 3,
              'endTime': 542,
              'sentence': false,
              'startIndex': 2,
              'startTime': 442
            },
            {
              'data': '那',
              'endIndex': 4,
              'endTime': 663,
              'sentence': false,
              'startIndex': 3,
              'startTime': 602
            },
            {
              'data': '些',
              'endIndex': 5,
              'endTime': 844,
              'sentence': false,
              'startIndex': 4,
              'startTime': 763
            },
            {
              'data': '繁',
              'endIndex': 6,
              'endTime': 1125,
              'sentence': false,
              'startIndex': 5,
              'startTime': 984
            },
            {
              'data': '华',
              'endIndex': 7,
              'endTime': 1326,
              'sentence': false,
              'startIndex': 6,
              'startTime': 1225
            },
            {
              'data': '的',
              'endIndex': 8,
              'endTime': 1467,
              'sentence': false,
              'startIndex': 7,
              'startTime': 1406
            },
            {
              'data': '都',
              'endIndex': 9,
              'endTime': 1668,
              'sentence': false,
              'startIndex': 8,
              'startTime': 1567
            },
            {
              'data': '市',
              'endIndex': 10,
              'endTime': 1869,
              'sentence': false,
              'startIndex': 9,
              'startTime': 1788
            },
            {
              'data': '生',
              'endIndex': 11,
              'endTime': 2110,
              'sentence': false,
              'startIndex': 10,
              'startTime': 1949
            },
            {
              'data': '活',
              'endIndex': 12,
              'endTime': 2251,
              'sentence': false,
              'startIndex': 11,
              'startTime': 2150
            },
            {
              'data': '告',
              'endIndex': 13,
              'endTime': 2753,
              'sentence': false,
              'startIndex': 12,
              'startTime': 2552
            },
            {
              'data': '诉',
              'endIndex': 14,
              'endTime': 2934,
              'sentence': false,
              'startIndex': 13,
              'startTime': 2834
            },
            {
              'data': '我',
              'endIndex': 15,
              'endTime': 3096,
              'sentence': false,
              'startIndex': 14,
              'startTime': 3015
            },
            {
              'data': '更',
              'endIndex': 16,
              'endTime': 3559,
              'sentence': false,
              'startIndex': 15,
              'startTime': 3277
            },
            {
              'data': '多',
              'endIndex': 17,
              'endTime': 3740,
              'sentence': false,
              'startIndex': 16,
              'startTime': 3639
            },
            {
              'data': '细',
              'endIndex': 18,
              'endTime': 4042,
              'sentence': false,
              'startIndex': 17,
              'startTime': 3901
            },
            {
              'data': '节',
              'endIndex': 19,
              'endTime': 4264,
              'sentence': false,
              'startIndex': 18,
              'startTime': 4123
            },
            {
              'data': '吧',
              'endIndex': 20,
              'endTime': 4425,
              'sentence': false,
              'startIndex': 19,
              'startTime': 4324
            },
            {
              'endIndex': 20,
              'endTime': 4749,
              'sentence': true,
              'startIndex': 0,
              'startTime': 0
            }
          ],
          'sourceType': 'reply',
          'sortId': 2,
          'oriText': '或者是那些繁华的都市生活？告诉我更多细节吧！',
          'textIndex': 2,
          'command': 'subtitle',
          'queryId': '90ad25a1d33845ed83e22a3c81bf663d_c',
          'order': 0
        })
  }
  if (code == 'feedText-START') {
    onCallback('feedText', {
      paramMap: {
        type: 'START'
      }
    })
  }
  if (code == 'feedText-END') {
    onCallback('feedText', {
      paramMap: {
        type: 'END'
      }
    })
  }
}

function initConnected(isFirst) {
  console.log('【initConnected】',roomStore.sessionId)
  if (!roomStore.roomId) {
    OperateTheRoom(
        {
          'cmdType': 'createRoom',
          'queryId': buildUUID(),
          'userId': unref(userId)
        }).then(async res => {
      console.log(res)
      let resultRes = res?.data || {}
      let resultData = resultRes?.resultData || {}
      roomStore.setRoomInfo({
        bizName: resultData.bizName,
        sign: resultData.sign,
        subBiz: resultData.subBiz,
        token: resultData.token,
        userId: resultData.userId,
        roomId: resultData.roomId,
        sessionId: resultRes.sessionId,
        queryId: resultRes.queryId
      })
      let mrtc = new MRTCService({
        bizName: resultData.bizName,
        sign: resultData.sign,
        subBiz: resultData.subBiz,
        token: resultData.token,
        userId: resultData.userId,
        roomId: resultData.roomId,
        sessionId: resultRes.sessionId,
        queryId: resultRes.queryId
      }, onCallback)
      mrtc.onConnect()
      onChangeVoice(false)
      if(isFirst){
        newVoice.sessionId = buildUUID()
        voiceMap.value.set(newVoice.sessionId, {
          sessionId: newVoice.sessionId,
          question: '',
          isQuestionLoading: false, // 是否已经语音识别中
          isAnswerStart: true, // 是否已经回答开始
          isAnswerEnd: true, // 是否已经回答结束
          sysDefault: true, // 系统默认发送
          answer: [
            {
              textIndex: 0,
              oriText: '我叫瑶瑶，是一个导游语音机器人，可以带你了解馆内展品的故事哦~'
            }
          ]
        })
        console.log('【Lynn-Hello】 voiceMap.value.set',JSON.stringify(newVoice.sessionId), JSON.stringify(unref(voiceMap)))
      }
      roomStore.setMrtcService(mrtc)
    })
  }
}

async function onCallback(type, res = {}) {
  let newSub = unref(voiceMap).get(newVoice.sessionId)
  console.log('【Lynn-Hello】 onCallbackonCallback',newVoice.sessionId, unref(voiceMap), newSub)
  if (type === 'asrChange') {
    let result = res?.asrChange
    if(!newVoice.isQuestionLoading) {
      playingEmpty()
      newVoice.sessionId = buildUUID()
      newVoice.isQuestionLoading = true
    }
    console.log('【Lynn-Hello】 onCallback',type, res)
    voiceMap.value.set(newVoice.sessionId, {
      sessionId: newVoice.sessionId,
      question: result?.text,
      isQuestionLoading: true, // 是否已经语音识别中
    })
    console.log('【Lynn-Hello】 voiceMap.value.set',JSON.stringify(newVoice.sessionId), JSON.stringify(unref(voiceMap)))
  }
  if (type === 'asrEnd') {
    console.log('【Lynn-Hello】 onCallback',type, res)
    let result = res?.asrEnd
    onChangeVoice(false)
    newVoice.isQuestionLoading = false
    console.log('【Lynn-Hello】 sessionIdsessionIdsessionId',newVoice.sessionId)
    voiceMap.value.set(newVoice.sessionId, {
      ...newSub,
      question: result?.text,
      isQuestionLoading: false, // 是否已经语音识别中
    })
    console.log('【Lynn-Hello】 voiceMap.value.set',JSON.stringify(newVoice.sessionId), JSON.stringify(unref(voiceMap)))
  }
  if (type === 'subtitle') {
    console.log('【Lynn-Hello】 onCallback',type, res)
    newVoice.answerList = (newVoice.answerList || []).concat([ res || {} ])
    let answerArr = [ res || {} ]
    let queryId = newSub?.queryId
    if (newSub.answer && (newSub.answer || []).length > 0){
      answerArr = (newSub.answer || []).concat([ res || {} ])
    } else {
      queryId = (res || {})?.queryId || ''
      newVoice.queryId = queryId
    }
    console.log('【Lynn-Hello】 newVoice.answerList',newVoice.answerList)
    if((res || {})?.queryId || '' == queryId){
      answerWaitMap.set((res?.textIndex || ''), res)
      voiceMap.value.set(newVoice.sessionId, {
        ...newSub,
        answer: answerArr,
        queryId: (res || {})?.queryId || '',
        interrupted: false // 是否被打断
      })
      console.log('【Lynn-Hello】 voiceMap.value.set',JSON.stringify(newVoice.sessionId), JSON.stringify(unref(voiceMap)))
      if (newVoice.isAnswerStart) {
        voiceParagraph()
      }
    }
  }
  if(newVoice.queryId == (res || {})?.queryId || ''){
    if (type === 'feedText') {
      let { paramMap } = res
      if (paramMap.type === 'START') {
        console.log('【Lynn-Hello】 onCallback START',type, res)
        newVoice.isAnswerStart = true
        voiceMap.value.set(newVoice.sessionId, {
          ...newSub,
          isAnswerStart: true// 是否已经回答开始
        })
        console.log('【Lynn-Hello】 voiceMap.value.set',JSON.stringify(newVoice.sessionId), JSON.stringify(unref(voiceMap)))
        voiceParagraph()
      }
      if (paramMap.type === 'END') {
        console.log('【Lynn-Hello】 onCallback END',type, res)
        newVoice.isAnswerEnd = true
        voiceMap.value.set(newVoice.sessionId, {
          ...newSub,
          isAnswerEnd: true // 是否已经回答结束
        })
        console.log('【Lynn-Hello】 voiceMap.value.set',JSON.stringify(newVoice.sessionId), JSON.stringify(unref(voiceMap)))
        playingEmpty()
      }
    }
  }
  // 图片问题
  if (type === 'imageParseStatus') {
    console.log('【Lynn-Hello】 onCallback',type, res)
    let status = res?.imageParseStatus?.status
    if (status === 'ok') {
      if (newVoice.sessionId && newVoice.sessionId !== ''){
        newVoice.isQuestionLoading = false
        console.log('【Lynn-Hello】 sessionIdsessionIdsessionId',newVoice.sessionId)
        voiceMap.value.set(newVoice.sessionId, {
          ...newSub,
          isQuestionLoading: false, // 是否已经语音识别中
        })
        console.log('【Lynn-Hello】 voiceMap.value.set',JSON.stringify(newVoice.sessionId), JSON.stringify(unref(voiceMap)))
      }
    }
  }

  if (type === 'OnConnectClose') {
    console.log('【Lynn】退出房间 postMessage')
    // await closeConnected()
    // 网页中向小程序发送消息
    // window.postMessage({
    //   data: {
    //     leaveRoom: true
    //   }
    // }, '*')
    // window.postMessage({
    //   action: 'setData',
    //   data: {
    //     leaveRoom: true
    //   }
    // }, '*')
  }

  if (type == 'OnParticipantLeaveRoom') {
    // 退出页面 直接断开
    // 网页中向小程序发送消息
    // window.postMessage({
    //   data: {
    //     leaveRoom: true
    //   }
    // }, '*')
    await closeConnected()
    // 重新连接
    await initConnected(false)
  }
  scrollToBottom()
  console.log('【Lynn-Hello】 onCallback voiceMap', unref(voiceMap))
}


async function voiceParagraph() {
  console.log('【Lynn-Hello】voiceParagraph',answerWaitMap)
  // 按照键（数字）升序排序
  const sortedByKeyAsc = new Map(
      [ ...answerWaitMap ].sort(([ keyA ], [ keyB ]) => keyA - keyB) // 按数字键升序排序
  )
  for (const smallestKey of sortedByKeyAsc.keys()) {
    // 等待播放 && 没有结束播放 && 没有正在播放
    if (answerWaitMap.has(smallestKey) && !answerEndMap.has(smallestKey) && unref(answeringObj)?.textIndex !== smallestKey) {
      console.log('【Lynn-Hello】voiceParagraph', answerWaitMap, answerEndMap, answeringObj)
      answeringObj.value = answerWaitMap.get(smallestKey)
      answerWaitMap.delete(smallestKey)
      let nowObj = JSON.parse(JSON.stringify(unref(answeringObj)))
      let tItem = nowObj?.timelines || []
      for (let j = 0; j < tItem.length; j++) {
        let timeItem = tItem[j]
        if (timeItem.data && timeItem.data !== '') {
          let otherD = newVoice.answerList.filter(v => v.textIndex < nowObj.textIndex).reduce((sum, item) => sum + item.duration, 0)
          const delay = otherD + timeItem.endTime
          console.log('【Lynn-Hello】 answerDisplayedTextMap2', delay, (answerDisplayedTextMap.get(nowObj.textIndex) || '') + timeItem.data)
          let aaa = setTimeout(() => {
            if (!newVoice.interrupted||newVoice.isAnswerEnd) {
              answerDisplayedTextMap.set(nowObj.textIndex, (answerDisplayedTextMap.get(nowObj.textIndex) || '') + timeItem.data)
            }
            scrollToBottom()
          }, delay) // 每个字延时
          timerArr.value.push(aaa)
          if (newVoice.interrupted) {
            break
          }
        } else {
          let delay = newVoice.answerList.filter(v => v.textIndex <= nowObj.textIndex).reduce((sum, item) => sum + item.duration, 0)
          console.log('【Lynn-Hello】', delay, nowObj?.oriText)
          let hhh = setTimeout(() => {
            if (!newVoice.interrupted||newVoice.isAnswerEnd) {
              answerDisplayedTextMap.set(nowObj.textIndex, nowObj?.oriText)
              console.log('【Lynn-Hello】 answerDisplayedTextMap3', answerDisplayedTextMap, nowObj?.oriText)
              answerEndMap.set(nowObj?.textIndex, nowObj)
            }
          }, delay) // 每个字延时
          timerArr.value.push(hhh)
        }
      }

    }
  }
}

async function closeConnected() {
  let { queryId, sessionId, mrtcService } = unref(roomStore)
  console.log(unref(roomStore))
  try {
    if (mrtcService) {
      await mrtcService.onLeaveRoom()
      await OperateTheRoom(
          {
            'cmdType': 'hangUpRoom',
            // 'queryId': buildUUID(),
            'userId': unref(userId),
            'queryId': queryId,
            'sessionId': sessionId
          }).then(async res => {
        console.log(res)
        voiceMap.value.clear()
        playingEmpty()
        roomStore.reset()
      })
    }
  } catch (e){
    roomStore.reset()
  }
}

const pagination = {
  el: '.custom-pagination',
  clickable: true,
  type: 'custom',  // 自定义分页
}

const goToPage = (index) => {
  // 使用Swiper的slideTo方法跳转到指定页
  if (unref(swiper)) {
    unref(swiper).swiper.slideTo(index)
  }
}

/**
 * 打断的回调
 * @param mapKey
 * @param displayedText
 */
function onInterrupted(mapKey, displayedText) {
  new Promise((resolve, reject) => {
    let interruptedItem = unref(voiceMap).get(mapKey)
    voiceMap.value.set(mapKey, {
      ...interruptedItem,
      displayedText,
      interrupted: true // 是否被打断
    })
    console.log('【Lynn-Hello】 voiceMap.value.set',JSON.stringify(newVoice.sessionId), JSON.stringify(unref(voiceMap)))
    console.log('【Lynn-Hello】 onInterrupted 打断的回调', mapKey, displayedText, interruptedItem, unref(voiceMap))
    let { mrtcService } = unref(roomStore)
    mrtcService?.onSendTextMsg('{"interrupt" : "userInterrupt"}')
    resolve()
  }).then(()=>{
    playingEmpty()
  })
}

const localStream = ref(null) // 用于存储媒体流

/**
 * 获取用户麦克风媒体流
 */
const getMedia = async () => {
  try {
    localStream.value = await navigator.mediaDevices.getUserMedia({ audio: true })
    console.log('【Lynn-Hello】 麦克风媒体流获取成功', localStream.value)
  } catch (error) {
    console.error('【Lynn-Hello】 麦克风获取媒体流失败', error)
  }
}

function onChangeKeyboard(keyboardStatus) {
  keyboardOpen.value = keyboardStatus
  // 语音正在听的话-->先打断
  if(
      unref(keyboardStatus)
      && unref(voiceOpen)
      && (
          (unref(lastVoiceObj)?.isAnswerStart && !unref(lastVoiceObj)?.isAnswerEnd)
          || unref(lastVoiceObj)?.isQuestionLoading
          || (!unref(lastVoiceObj)?.isAnswerStart && !unref(lastVoiceObj)?.isAnswerEnd && !unref(lastVoiceObj)?.interrupted)
      ) ){
    // 关闭麦克风
    onChangeVoice(false)
    console.log(`【Lynn-Hello】 ${unref(keyboardOpen) ? '打开' : '关闭'}键盘 语音正在听的话-->先打断`)
  } else {
    console.log(`【Lynn-Hello】 ${unref(keyboardOpen) ? '打开' : '关闭'}键盘`)
  }
}

/**
 * 打开摄像头
 */
function onChangeCamera() {
  let { mrtcService } = unref(roomStore)
  cameraOpen.value = !unref(cameraOpen)
  console.log(`【Lynn-Hello】 ${unref(cameraOpen) ? '打开' : '关闭'}摄像头`, '')
  // console.log(mrtcService, unref(cameraOpen), unref(cameraOpen) ? 1 : 0)
  // mrtcService?.onTurnOnTheCamera(unref(cameraOpen) ? 1 : 0)

  if (
      (
          (unref(lastVoiceObj)?.isAnswerStart && !unref(lastVoiceObj)?.isAnswerEnd)
          || unref(lastVoiceObj)?.isQuestionLoading
          || (!unref(lastVoiceObj)?.isAnswerStart && !unref(lastVoiceObj)?.isAnswerEnd && !unref(lastVoiceObj)?.interrupted)
      )
      && newVoice.sessionId && newVoice.sessionId !== ''
  ) {
    onInterrupted(unref(lastVoiceObj).sessionId, JSON.parse(JSON.stringify(unref(answerDisplayedTextMapStr))))
  }
  fileInput.value.click() // 点击按钮时触发 input 的点击事件
  openCamera.value = true
}

/**
 * 切换麦克风状态
 */
function onChangeVoice(voiceStatus) {
  if (voiceStatus) {
    keyboardOpen.value = false
    value.value = ''
  }
  let { mrtcService } = unref(roomStore)
  voiceOpen.value = voiceStatus
  mrtcService?.onTurnOnTheMicrophone(unref(voiceOpen) ? 1 : 0)
  if (
      voiceStatus
      && (
          (
              unref(lastVoiceObj)?.isAnswerStart && !unref(lastVoiceObj)?.isAnswerEnd)
          || unref(lastVoiceObj)?.isQuestionLoading
          || (!unref(lastVoiceObj)?.isAnswerStart && !unref(lastVoiceObj)?.isAnswerEnd && !unref(lastVoiceObj)?.interrupted
          )
      )
      && newVoice.sessionId && newVoice.sessionId !== ''
  ) {
    onInterrupted(unref(lastVoiceObj).sessionId, JSON.parse(JSON.stringify(unref(answerDisplayedTextMapStr))))
  }
}

function playingEmpty() {
  newVoice = {
    sessionId: '', // 最新的一条问答id
    queryId: '', // 最新的一条问答id
    isQuestionLoading: false, // 是否已经语音识别中
    isAnswerStart: false, // 是否已经回答开始
    isAnswerEnd: false, // 是否已经回答结束
    interrupted: false, //是否被打断
    answerList: []
  }
  answeringObj.value = {}
  answerWaitMap.clear()
  answerEndMap.clear()
  answerDisplayedTextMap.clear();
  (timerArr.value||[]).forEach(timerId => clearTimeout(timerId))
  timerArr.value = []
  console.log('【Lynn-Hello】playingEmpty', timerArr)
}

function onSendTextMsg() {
  if (unref(value) && unref(value) !== ''){
    // !unref(lastVoiceObj)?.interrupted
    console.log('【onSendTextMsgonSendTextMsgonSendTextMsg】',unref(lastVoiceObj),((unref(lastVoiceObj)?.isAnswerStart && !unref(lastVoiceObj)?.isAnswerEnd) || unref(lastVoiceObj)?.isQuestionLoading))
    if (
        (unref(lastVoiceObj)?.isAnswerStart && !unref(lastVoiceObj)?.isAnswerEnd)
        || unref(lastVoiceObj)?.isQuestionLoading
        || (!unref(lastVoiceObj)?.isAnswerStart && !unref(lastVoiceObj)?.isAnswerEnd && !unref(lastVoiceObj)?.interrupted)
    ) {
      onInterrupted(unref(lastVoiceObj).sessionId, JSON.parse(JSON.stringify(unref(answerDisplayedTextMapStr))))
    }
    setTimeout(()=>{
      let { mrtcService } = unref(roomStore)
      console.log(mrtcService, unref(value))
      newVoice.sessionId = buildUUID()
      newVoice.isQuestionLoading = false
      voiceMap.value.set(newVoice.sessionId, {
        sessionId: newVoice.sessionId,
        question: unref(value),
        isQuestionLoading: false, // 是否已经语音识别中
      })
      console.log('【Lynn-Hello】 voiceMap.value.set',JSON.stringify(newVoice.sessionId), JSON.stringify(unref(voiceMap)))
      let msgParams = {
        text: unref(value)
      }
      mrtcService?.onSendTextMsg(JSON.stringify(msgParams))
      value.value = '' // 键盘文字清空
    },500)
  }
}

async function onInit() {
  await getMedia()
  await initConnected(true)
  unref(initRef).handleCancel()
  connectionStatus.value = false
  introducedStatus.value = true
}

function onEnd() {
  introducedStatus.value = false
}

onMounted(() => {
  ap.onPause(function(){
    handlePopstate()
  })
  window.addEventListener('beforeunload', handleBeforeUnload)
/*  userId.value = '2088912229263556'
  // return
  // 获取 URL 参数的方法
  // const urlParams = new URLSearchParams(window.location.search)
  // const userId = urlParams.get('userId')
  // console.log('userId', userId)
  // 页面初始化时，滚动容器滚动到底部
  scrollToBottom()
  let { mrtcService } = unref(roomStore)
  if (!mrtcService) {
    connectionStatus.value = true
  } else {
    connectionStatus.value = false
    introducedStatus.value = false
  }*/
  nextTick(async () => {
    let { queryId, sessionId, mrtcService } = unref(roomStore)
    if (sessionId) {
      roomStore.reset()
    }
    console.log('ssssssss',ap)
    ap.getAuthCode({
      appId: '2021005110683593' ,
      // scopes: [ 'auth_user' ],
      scopes: [ 'auth_base' ],
    },function(res){
      authCode.value = res?.authCode
      console.log('getAuthCode',JSON.stringify(res))
      // ap.alert (JSON.stringify(res))
      if (res?.error =='11') {
        message.error(res?.errorMessage || '其他异常')
        return
      } else if(res?.error) {
        message.error(res?.errorMessage || '其他异常')
        return
      }
      if (unref(authCode)) {
        getUserIdByAuthCode({
          authCode: unref(authCode)
        }).then(res=>{
          userId.value = res?.data?.userId || ''
          // return
          // 获取 URL 参数的方法
          // const urlParams = new URLSearchParams(window.location.search)
          // const userId = urlParams.get('userId')
          // console.log('userId', userId)
          // 页面初始化时，滚动容器滚动到底部
          scrollToBottom()
          let { mrtcService } = unref(roomStore)
          if (!mrtcService) {
            connectionStatus.value = true
          } else {
            connectionStatus.value = false
            introducedStatus.value = false
          }
        })
      }
    })
  })
})

onUnmounted(() => {
  // 组件销毁前移除事件监听
  window.removeEventListener('beforeunload', handleBeforeUnload)
})

function handleBeforeUnload() {
  // 在这里处理页面关闭逻辑
  closeConnected()
  if (localStream.value) {
    localStream.value.getTracks().forEach((track) => track.stop())
  }
}

function handlePopstate() {
  if (!unref(openCamera)) {
    // 在这里处理页面关闭逻辑
    closeConnected()
    if (localStream.value) {
      localStream.value.getTracks().forEach((track) => track.stop())
    }
    ap.popWindow()
  }
}

function compressionImage(file) {
  return new Promise((resolve, reject) => {
    // eslint-disable-next-line no-new
    new ImageCompressor({
      file: file,
      quality: 0.7,
      maxWidth: 1500,
      maxHeight: 1500,
      redressOrientation: false,

      // 压缩前回调
      beforeCompress: function (result) {
        console.log('压缩之前图片尺寸大小: ', result.size)
        console.log('mime 类型: ', result.type)
      },

      success: function (result) {
        console.log('压缩之后图片尺寸大小: ', result.size)
        console.log('压缩之后图片尺寸大小: ', result.size)
        console.log('mime 类型: ', result.type)
        console.log('实际压缩率： ', ((file.size - result.size) / file.size * 100).toFixed(2) + '%')
        // 将Blob对象转换为File对象
        const compressedImageFile = new File([ result ], file.name, {
          type: 'image/jpeg',
        })
        let reader = new FileReader()
        reader.readAsDataURL(result)
        reader.onload = function (e) {
          let base64 = e.target.result
          resolve({
            compressedImageFile,
            base64
          })
        }
      },
      error (e) {
        reject(e)
      }
    })
  })
}

function handleFileChange(event) {
  const oragFile = event.target.files[0]
  openCamera.value = false
  console.log('【Lynn-file】handleFileChange', event, oragFile)
  if (oragFile) {
    compressionImage(oragFile).then(({ compressedImageFile, base64 })=>{
      let file = compressedImageFile
      console.log('【Lynn-file】compressionImage', file, base64)
      imageSrc.value = base64 // 设置图片源
      if (
          (
              (unref(lastVoiceObj)?.isAnswerStart && !unref(lastVoiceObj)?.isAnswerEnd)
              || unref(lastVoiceObj)?.isQuestionLoading
              || (!unref(lastVoiceObj)?.isAnswerStart && !unref(lastVoiceObj)?.isAnswerEnd && !unref(lastVoiceObj)?.interrupted)
          )
          && newVoice.sessionId && newVoice.sessionId !== ''
      ) {
        onInterrupted(unref(lastVoiceObj).sessionId, JSON.parse(JSON.stringify(unref(answerDisplayedTextMapStr))))
      }
      let avatarFile = new FormData()
      avatarFile.append('file', file)
      pictureLocal(avatarFile).then((res) => {
        imageSrc.value = res.data
        let { mrtcService } = unref(roomStore)
        console.log(mrtcService, unref(value))
        let msgParams = {
          fileUpload:  {
            'fileName': 'test_img',
            'fileUrl': unref(imageSrc),
            // 配置IMAGE
            'fileType': 'IMAGE',
            /**
             *  @param fileSource
             *  USER_UPLOAD：   用户上传
             *  SYSTEM_CONVERT：视频抽帧
             */
            'fileSource': 'USER_UPLOAD',
            // ms级别时间戳
            'operateTime': (new Date()).getTime(),
            'query': '帮我查一下这件展品的信息。'
          }
        }
        newVoice.sessionId = buildUUID()
        newVoice.isQuestionLoading = false
        voiceMap.value.set(newVoice.sessionId, {
          sessionId: newVoice.sessionId,
          questionType: 'img', //
          img: unref(imageSrc),
          question: '帮我查一下这件展品的信息。',
          isQuestionLoading: true, // 是否已经语音识别中
        })
        scrollToBottom()
        console.log('【Lynn-Hello】 voiceMap.value.set',JSON.stringify(newVoice.sessionId), JSON.stringify(unref(voiceMap)))
        mrtcService?.onSendTextMsg(JSON.stringify(msgParams))
        imageSrc.value = '' // 键盘文字清空
      })
    })
  }
}
</script>

<template>
  <!--  v-show="authCode && authCode != ''"-->
  <div
    class="digital_human_content"
  >
    <div
      class="top_btn_area"
      style="z-index: 997"
    >
      <!--      <img
        src="../../src/assets/mute.png"
      >-->
      <!--      <span @click="initConnected(true)">导游瑶瑶{{ !!roomStore.sessionId }}</span>-->
      <div />
    </div>
    <InitModal
      v-show="connectionStatus || introducedStatus"
      ref="initRef"
      :visible="connectionStatus"
      :introduced="introducedStatus"
      @init="onInit"
      @end="onEnd"
    />
    <div
      v-show="!connectionStatus && !introducedStatus"
      class="digital_human_text"
    >
      <!--      :initial-slide="2"-->
      <swiper-container
        ref="swiper"
        class="scroll_nav"
        :space-between="spaceBetween"
        :centered-slides="true"
        :active-index="activeIndex"
        :pagination="pagination"
        @swiperprogress="onProgress"
        @slide-change="goToPage"
      >
        <swiper-slide class="swiper_box">
          <div
            class="first_box"
            :style="`padding: ${lastVoiceObj ? '10px':''};`"
          >
            <div
              ref="swiperFirstContainer"
              class="first_box_content"
            >
              <!--              我叫瑶瑶，是一个导游语音机器人，可以带你了解馆内展品的故事哦~-->
              <DefaultChatItem
                v-if="lastVoiceObj"
                :key="`voice_${lastVoiceObj?.queryId}_${newVoice?.sessionId}`"
                :item="lastVoiceObj"
                :answer-str="answerDisplayedTextMapStr"
                @interrupted="onInterrupted"
              />
            </div>
          </div>
        </swiper-slide>
        <swiper-slide class="swiper_box">
          <div class="second_box">
            <div class="second_box_bg" />
            <div
              ref="swiperSecondContainer"
              class="second_box_content"
            >
              <ChatItem
                v-for="([key, item], index) in voiceMapEntries"
                :key="`voice_${item.queryId}_${key}`"
                :new-session-id="newVoice.sessionId"
                :map-key="key"
                :item="item"
                :answer-str="answerDisplayedTextMapStr"
                @interrupted="onInterrupted"
              />
            </div>
          </div>
        </swiper-slide>
      </swiper-container>
      <!-- 自定义分页器 -->
      <div class="custom-pagination">
        <div
          :class="['custom-bullet', activeIndex === 0 ? 'swiper-pagination-bullet-active' : '']"
          @click="goToPage(0)"
        />
        <div
          :class="['custom-bullet', activeIndex === 1 ? 'swiper-pagination-bullet-active' : '']"
          @click="goToPage(1)"
        />
      </div>
    </div>
    <div
      v-show="!connectionStatus && !introducedStatus"
      class="digital_human_video"
    >
      <div class="digital_human_video_bg" />
      <img src="../../src/assets/digital_humans.png">
      <!--      <label
        id="publish_streamId1"
        class="css-text-color hiddenForMobile"
        type="text"
      />-->
      <video
        id="digital_human_video-player"
        class="digital_human_video-player"
        autoplay
        muted
      />
      <audio
        id="digital_human_audio-player"
        class="digital_human_audio-player"
        controls
      />
    </div>
    <!--    <div style="position: absolute;top: 80px;z-index: 9999;background: #fff">
      {{ historyS }}
    </div>-->
    <!--    <div
      v-show="!connectionStatus && !introducedStatus"
      style="position: absolute;top: 80px;z-index: 9999;background: #fff"
    >
      <div @click="add('asrChange')">
        asrChange
      </div>
      <div @click="add('asrEnd')">
        asrEnd
      </div>
      <div @click="add('subtitle1')">
        subtitle1
      </div>
      <div @click="add('subtitle2')">
        subtitle2
      </div>
      <div @click="add('subtitle3')">
        subtitle3
      </div>
      <div @click="add('feedText-START')">
        subtitle-START
      </div>
      <div @click="add('feedText-END')">
        subtitle-END
      </div>
      {{ answerDisplayedTextMapStr }}
    </div>-->
    <div
      v-show="!connectionStatus && !introducedStatus"
      class="bottom_btn_area"
    >
      <div class="keyboard">
        <img
          v-if="keyboardOpen"
          src="../../src/assets/keyboard_selected.png"
          @click="onChangeKeyboard(false)"
        >
        <img
          v-else
          src="../../src/assets/keyboard_unselected.png"
          @click="onChangeKeyboard(true)"
        >
      </div>
      <div class="taking_pictures">
        <img
          src="../../src/assets/taking_pictures.png"
          @click="onChangeCamera"
        >
        <input
          ref="fileInput"
          type="file"
          accept="image/*"
          capture="camera"
          style="display: none"
          @change="handleFileChange"
        >
      </div>
      <div class="voice">
        <img
          v-if="voiceOpen"
          src="../../src/assets/voice_selected.png"
          @click="onChangeVoice(false)"
        >
        <img
          v-else
          src="../../src/assets/voice_unselected.png"
          @click="onChangeVoice(true)"
        >
      </div>
    </div>
    <div
      v-if="keyboardOpen"
      v-show="!connectionStatus && !introducedStatus"
      class="bottom_input_area"
    >
      <a-input
        v-model:value="value"
        size="large"
        placeholder="发消息..."
      >
        <template #suffix>
          <div
            class="suffix-btn"
            @click="onSendTextMsg"
          >
            发送
            <img src="../../src/assets/btn.png">
          </div>
        </template>
      </a-input>
    </div>
  </div>
</template>

<style scoped lang="less">
.digital_human_content {
  width: calc(100vw + 4px);
  left: -2px;
  max-width: 500px;
  height: 100vh;
  position: relative;
  overflow: hidden;

  .digital_human_text {
    width: calc(100% - 24px);
    height: calc(100% - 220px);
    //background: #D6DEDCB2;
    //backdrop-filter: blur(50px);
    position: absolute;
    bottom: 190px;
    left: 12px;
    z-index: 999;
    border-radius: 12px;

    .ant-carousel {
      width: 100%;
      height: 100%;
    }

    /* 每个幻灯片的样式 */
    .carousel-item {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100%;
      background-color: #e0f7fa;
      /* 背景色 */
      color: #333;
      /* 文字颜色 */
      font-size: 18px;
    }

    /* 每个幻灯片的内容 */
    .carousel-content {
      text-align: center;
      padding: 20px;
      background-color: rgba(255, 255, 255, 0.8);
      /* 内容背景色 */
      border-radius: 10px;
      /* 内容区的圆角 */
      height: calc(100vh - 300px);
      overflow: scroll;
    }

    :deep(.slick-slider) {
      text-align: center;
      width: 100%;
      height: calc(100%);
      overflow: hidden;
    }

    :deep(.slick-slider .slick-list) {
      height: calc(100% - 40px);
    }

    :deep(.slick-slider .slick-list .slick-track) {
      height: calc(100%);
    }
  }

  .digital_human_video {
    width: 100%;
    height: 100%;
    position: relative;
    overflow: hidden;
    display: flex;           /* 使用 flex 布局 */
    justify-content: center; /* 居中视频 */
    align-items: center;     /* 垂直居中 */

    &_bg {
      position: absolute;
      width: 100%;
      height: 100%;
      background: url('../assets/home_bg.png') no-repeat;
      background-size: 100% 210px;
      background-position: bottom center;
      bottom: 0;
      left: 0;
    }

    img {
      //width: 100%;
      //height: calc(100% - 10px);
      //position: absolute;
      //bottom: 0;
      //left: 0;
      width: 96%;
      height: calc(100% - 40px);
      position: absolute;
      bottom: 0;
      left: 2%;
    }

    .digital_human_video-player,
    .digital_human_audio-player {
      //width: 100%;
      ////height: calc(100%);
      position: absolute;
      top: 0;
      //left: 0;
      height: 100%;
      width: auto;
      margin: auto;
      //position: relative;
    }
  }

  .top_btn_area {
    width: 100%;
    padding: 0 16px;
    box-sizing: border-box;
    height: 44px;
    //background: #fff;
    display: flex;
    justify-content: space-between;
    align-items: center;
    position: absolute;
    top: 0;

    img,
    div {
      width: 22px;
      height: 22px;
    }
  }

  .bottom_input_area {
    display: flex;
    justify-content: space-around;
    align-items: center;
    position: absolute;
    bottom: 20px;
    width: calc(100% - 60px);
    left: 30px;

    .suffix-btn {
      cursor: pointer;
      width: 56px;
      height: 32px;
      line-height: 32px;
      font-size: 14px;
      color: #313C2C;
      border-radius: 18px;
      background: linear-gradient(270deg, #51B0A1 0%, #6BDAC8 48.67%, #8BBC8B 100%);
      display: flex;
      justify-content: center;
      align-items: center;

      img {
        width: 9.6px;
        height: 6px;
        margin-left: 6px;
      }
    }

    :deep(.ant-input-affix-wrapper-lg) {
      height: 46px !important;
      border-radius: 16px;
      box-shadow: 0px 0px 3px 0px #2E474133;
    }

    :deep(.ant-input-affix-wrapper) {
      border-width: 0px !important;
    }

    :deep(.ant-input-affix-wrapper-focused) {
      outline: none !important;
    }

    :deep(.ant-input) {
      color: #222222 !important;
      caret-color: #3CBEA9;
      /* 设置光标颜色 */
    }
  }

  .bottom_btn_area {
    display: flex;
    justify-content: space-around;
    align-items: center;
    position: absolute;
    bottom: 80px;
    width: calc(100% - 60px);
    left: 30px;

    .keyboard {
      width: 84.76px;
      height: 58px;

      img {
        width: 100%;
        height: 100%;
        cursor: pointer;
      }
    }

    .taking_pictures {
      width: 102.3px;
      height: 70px;

      img {
        width: 100%;
        height: 100%;
        cursor: pointer;
      }
    }

    .voice {
      width: 84.76px;
      height: 58px;

      img {
        width: 100%;
        height: 100%;
        cursor: pointer;
      }
    }
  }
}

.scroll_nav {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;

  .swiper_box {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: flex-end;
    justify-content: center;

    .first_box {
      width: 100%;
      border-radius: 12px;
      background-color: #0F1211BF;
      color: #E8ECEB;
      box-sizing: border-box;
      overflow: hidden;

      &_content {
        max-height: 340px;
        //min-height: 72px;
        width: 100%;
        padding: 0 10px;
        box-sizing: border-box;
        text-align: left;
        overflow: scroll;
      }
    }

    .second_box {
      width: 100%;
      height: 100%;
      border-radius: 12px;
      background-color: #D6DEDCB2;
      color: #111111;
      padding: 20px 0;
      overflow: hidden;
      box-sizing: border-box;
      position: relative;

      &_bg {
        backdrop-filter: blur(50px);
        position: absolute;
        top: 0;
        height: 100%;
        width: 100%;
      }
      &_content {
        height: 100%;
        width: 100%;
        padding: 0 10px;
        box-sizing: border-box;
        text-align: left;
        overflow: scroll;
      }
    }
  }
}

/* 自定义分页按钮样式 */
.custom-pagination {
  text-align: center;
  color: red;
}

.custom-bullet {
  width: 30px;
  height: 3px;
  background: rgba(0, 0, 0, 0.7);
  border-radius: 2px;
  display: inline-block;
  margin: 0 5px;
  cursor: pointer;
  transition: background-color 0.3s;
}

.custom-bullet.swiper-pagination-bullet-active {
  background-color: #8BB8AE;
}
</style>
