import { defineStore } from 'pinia'
import {
  ServeRemoveRecords,
  ServeRevokeRecords,
  ServePublishMessage,
  ServeCollectEmoticon
} from '@/api/chat'
import { ServeGetGroupMembers,ServeGroupDetail } from '@/api/group.js'
import { useEditorStore } from './editor'
// 键盘消息事件定时器
let keyboardTimeout = null

export const useDialogueStore = defineStore('dialogue', {
  state: () => {
    return {
      // 对话索引（聊天对话的唯一索引）
      index_name: '',
      globalUploadList:[],
      // 添加一个映射，用于快速查找每个会话的上传任务
      uploadTaskMap: {},  // 格式: { "talk_type_receiver_id": [task1, task2, ...] }
      // 对话节点
      talk: {
        avatar:'',
        username: '',
        talk_type: 0, // 对话来源[1:私聊;2:群聊]
        receiver_id: 0,
        group_type:0
      },

      // 好友是否正在输入文字
      keyboard: false,

      // 对方是否在线
      online: false,

      // 聊天记录
      records: [],

      // 查询指定消息上下文的消息信息
      specifiedMsg: '',

      // 是否不刷新聊天记录
      noRefreshRecords: false,

      // 是否是手动切换会话
      isManualSwitch: false,

      // 新消息提示
      unreadBubble: 0,

      // 是否开启多选操作模式
      isOpenMultiSelect: false,

      // 是否显示编辑器
      isShowEditor: false,

      //是否已被解散
      isDismiss: false,

      //是否退群/移出群
      isQuit: false,

      // 是否显示会话列表
      isShowSessionList: true,
      groupInfo: {} ,
      // 群成员列表
      members: [],
      // 群成员列表按字母分组
      membersByAlphabet: {},

      // 对话记录
      items: {
        '1_1': {
          talk_type: 1, // 对话类型
          receiver_id: 0, // 接收者ID
          read_sequence: 0, // 当前已读的最后一条记录
          records: []
        }
      }
    }
  },
  getters: {
    // 多选列表
    selectItems: (state) => state.records.filter((item) => item.isCheck),
    // 当前对话是否是群聊
    isGroupTalk: (state) => state.talk.talk_type === 2
  },
  actions: {
    // 更新在线状态
    setOnlineStatus(status) {
      this.online = status
    },

    // 更新群解散状态
    updateDismiss(isDismiss) {
      this.isDismiss = isDismiss
    },

    // 更新群成员退出状态
    updateQuit(isQuit) {
      this.isQuit = isQuit
    },

    // 更新对话信息
    setDialogue(data = {}) {
      this.online = data.is_online == 1
      this.talk = {
        username: data.remark || data.name,
        talk_type: data.talk_type,
        receiver_id: data.receiver_id,
        avatar:data.avatar,
        group_type:data.group_type
      }

      this.index_name = `${data.talk_type}_${data.receiver_id}`
      this.records = []
      this.unreadBubble = 0
      this.isShowEditor = data?.is_robot === 0

      this.isDismiss = data?.is_dismiss === 1 ? true : false
      this.isQuit = data?.is_quit === 1 ? true : false
      
      // 只在手动切换会话时清空 specifiedMsg
      // if (this.isManualSwitch) {
      //   this.specifiedMsg = ''
      //   this.isManualSwitch = false
      // }

      this.members = []
      this.membersByAlphabet = []
      if (data.talk_type == 2) {
        this.updateGroupMembers()
        this.getGroupInfo()
      }
      
      // 注意：上传任务的恢复将在聊天记录加载完成后进行
      // 在useTalkRecord.ts的onLoad方法中，会在加载完聊天记录后调用restoreUploadTasks方法
    },

    // 更新提及列表
    async updateGroupMembers() {
      let { code, data } = await ServeGetGroupMembers({
        group_id: this.talk.receiver_id
      })

      if (code != 200) return

      this.members = data.items.map((o) => ({
        id: o.user_id,
        nickname: o.nickname,
        avatar: o.avatar,
        gender: o.gender,
        leader: o.leader,
        remark: o.remark,
        online: false,
        value: o.nickname
      }))
      const groupMap = {};
      data.sortItems.forEach(member => {
        const alpha = (member.key || member.nickname?.[0] || '#').toUpperCase();
        if (!groupMap[alpha]) groupMap[alpha] = [];
        groupMap[alpha].push(member);
      });
      const alphabets = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
      this.membersByAlphabet = alphabets.map(alpha => ({
        alphabet: alpha,
        members: groupMap[alpha] || []
      })).filter(group => group.members.length > 0);
    },

    // 清空对话记录
    clearDialogueRecord() {
      this.records = []
    },

    // 数组头部压入对话记录
    unshiftDialogueRecord(records) {
      console.log('unshiftDialogueRecord')
      this.records.unshift(...records)
    },
    //数组尾部加入更多对话记录
    addDialogueRecordForLoadMore(records){
            console.log('addDialogueRecordForLoadMore')
      this.records.push(...records)
    },
    async getGroupInfo(){
      const { code, data } = await ServeGroupDetail({
        group_id: this.talk.receiver_id
      })
      if(code == 200){
        this.groupInfo = data
      }
    },
    // 推送对话记录
    async addDialogueRecord(record) {
      // TOOD 需要通过 sequence 排序，保证消息一致性
      // this.records.splice(index, 0, record)
      this.records.push(record)
      
      // 同步到本地数据库
      try {
        const { addMessage } = await import('@/utils/db')
        await addMessage(record)
      } catch (error) {
        console.error('同步消息到本地数据库失败:', error)
      }
    },

    // 更新对话记录
    async updateDialogueRecord(params) {
      const { msg_id = '' } = params

      const item = this.records.find((item) => item.msg_id === msg_id)

      if (item) {
        Object.assign(item, params)
        
        // 同步到本地数据库
        try {
          // 如果是撤回消息
          if (params.is_revoke === 1) {
            const { revokeMessage } = await import('@/utils/db')
            await revokeMessage(msg_id)
          }
        } catch (error) {
          console.error('同步消息更新到本地数据库失败:', error)
        }
      }
    },

    // 批量删除对话记录
    async batchDelDialogueRecord(msgIds = []) {
      // 同步到本地数据库
      try {
        const { deleteMessage } = await import('@/utils/db')
        for (const msgid of msgIds) {
          await deleteMessage(msgid)
        }
      } catch (error) {
        console.error('同步消息删除到本地数据库失败:', error)
      }
      
      // 从内存中删除
      msgIds.forEach((msgid) => {
        const index = this.records.findIndex((item) => item.msg_id === msgid)

        if (index >= 0) this.records.splice(index, 1)
      })
    },

    // 自增好友键盘输入事件
    triggerKeyboard() {
      this.keyboard = true

      clearTimeout(keyboardTimeout)

      keyboardTimeout = setTimeout(() => (this.keyboard = false), 2000)
    },

    setUnreadBubble(value) {
      if (value === 0) {
        this.unreadBubble = 0
      } else {
        this.unreadBubble++
      }
    },

    // 关闭多选模式
    closeMultiSelect() {
      this.isOpenMultiSelect = false

      for (const item of this.selectItems) {
        if (item.isCheck) {
          item.isCheck = false
        }
      }
    },

    // 删除聊天记录
    ApiDeleteRecord(msgIds = []) {
      ServeRemoveRecords({
        talk_type: this.talk.talk_type,
        receiver_id: this.talk.receiver_id,
        msg_ids: msgIds
      }).then((res) => {
        if (res.code == 200) {
          this.batchDelDialogueRecord(msgIds)
        }
      })
    },

    // 撤销聊天记录
    ApiRevokeRecord(msg_id = '') {
      ServeRevokeRecords({ msg_id }).then((res) => {
        if (res.code == 200) {
          this.updateDialogueRecord({ msg_id, is_revoke: 1 })
        } else {
          window['$message'].warning(res.message)
        }
      })
    },

    // 转发聊天记录
    ApiForwardRecord(options) {
      let data = {
        type: 'forward',
        receiver: {
          talk_type: this.talk.talk_type,
          receiver_id: this.talk.receiver_id
        },
        ...options
      }

      ServePublishMessage(data).then((res) => {
        if (res.code == 200) {
          this.closeMultiSelect()
        }
      })
    },

    ApiCollectImage(options) {
      const { msg_id } = options

      ServeCollectEmoticon({ msg_id }).then(() => {
        useEditorStore().loadUserEmoticon()
        window['$message'] && window['$message'].success('收藏成功')
      })
    },

    // 更新视频上传进度
    updateUploadProgress(uploadId, percentage) {
      // 更新全局列表中的进度
      const globalTask = this.globalUploadList.find(item => 
        item.extra && item.extra.is_uploading && item.extra.upload_id === uploadId
      )
      
      if (globalTask) {
        globalTask.extra.percentage = percentage
      }
      
      // 更新当前会话记录中的进度
      const record = this.records.find(item => 
        item.extra && item.extra.is_uploading && item.extra.upload_id === uploadId
      )
      
      if (record) {
        record.extra.percentage = percentage
      }
    },
    
    // 添加上传任务
    addUploadTask(task) {
      // 添加到全局列表
      this.globalUploadList.push(task)
      
      // 添加到会话映射
      const sessionKey = `${task.talk_type}_${task.receiver_id}`
      if (!this.uploadTaskMap[sessionKey]) {
        this.uploadTaskMap[sessionKey] = []
      }
      this.uploadTaskMap[sessionKey].push(task)
      
      // 同时添加到当前会话记录
      this.addDialogueRecord(task)
    },
    
    // 上传完成后移除任务
    removeUploadTask(uploadId) {
      // 从全局列表中找到任务
      const taskIndex = this.globalUploadList.findIndex(item => item.msg_id === uploadId)
      
      if (taskIndex >= 0) {
        const task = this.globalUploadList[taskIndex]
        const sessionKey = `${task.talk_type}_${task.receiver_id}`
        
        // 从会话映射中移除
        if (this.uploadTaskMap[sessionKey]) {
          const mapIndex = this.uploadTaskMap[sessionKey].findIndex(item => item.msg_id === uploadId)
          if (mapIndex >= 0) {
            this.uploadTaskMap[sessionKey].splice(mapIndex, 1)
          }
        }
        
        // 从全局列表中移除
        this.globalUploadList.splice(taskIndex, 1)
        // 移除消息记录

        this.batchDelDialogueRecord([uploadId])
      }
    },
    
    // 视频上传完成后更新消息
    completeUpload(uploadId, videoInfo) {
      const record = this.records.find(item => 
        item.extra && item.extra.is_uploading && item.extra.upload_id === uploadId
      )
      
      if (record) {
        record.extra.is_uploading = false
        record.extra.url = videoInfo.url
        // record.extra.cover = videoInfo.cover
      }
    },

    // 更新会话信息
    updateDialogueTalk(params){
      Object.assign(this.talk, params)
    },
    
    // 根据 insert_sequence 将任务插入到 records 数组的正确位置（使用优化的二分查找）
    insertTaskAtCorrectPosition(task) {
      const len = this.records.length
      
      // 快速路径：如果数组为空或任务应该插入到末尾
      if (len === 0) {
        this.records.push(task)
        return
      }
      
      // 快速路径：检查是否应该插入到开头或末尾（避免二分查找的开销）
      if (task.insert_sequence < this.records[0].sequence) {
        this.records.unshift(task)
        return
      }
      
      if (task.insert_sequence >= this.records[len - 1].sequence) {
        this.records.push(task)
        return
      }
      
      // 使用优化的二分查找算法找到插入位置
      let low = 0
      let high = len - 1
      
      // 二分查找优化：使用位运算加速计算中点
      while (low <= high) {
        const mid = (low + high) >>> 1 // 无符号右移代替 Math.floor((low + high) / 2)
        if (this.records[mid].sequence <= task.insert_sequence) {
          low = mid + 1
        } else {
          high = mid - 1
        }
      }
      
      // 在找到的位置插入任务
      this.records.splice(low, 0, task)
    },
    
    // 恢复当前会话的上传任务
    restoreUploadTasks() {
      // 获取当前会话的sessionKey
      const sessionKey = `${this.talk.talk_type}_${this.talk.receiver_id}`
      
      // 检查是否有需要恢复的上传任务
      if (!this.uploadTaskMap[sessionKey] || this.uploadTaskMap[sessionKey].length === 0) {
        return
      }
      
      // 性能优化：缓存数组长度和本地变量，减少属性查找
      const tasks = this.uploadTaskMap[sessionKey]
      const tasksLength = tasks.length
      
      // 如果只有一个任务，直接处理
      if (tasksLength === 1) {
        this.insertTaskAtCorrectPosition(tasks[0])
        return
      }
      
      // 性能优化：对于少量任务，避免创建新数组和排序开销
      if (tasksLength <= 10) {
        // 找出最小的 insert_sequence
        let minIndex = 0
        for (let i = 1; i < tasksLength; i++) {
          if (tasks[i].insert_sequence < tasks[minIndex].insert_sequence) {
            minIndex = i
          }
        }
        
        // 按顺序插入任务
        let inserted = 0
        let currentMin = tasks[minIndex]
        this.insertTaskAtCorrectPosition(currentMin)
        inserted++
        
        while (inserted < tasksLength) {
          minIndex = -1
          let minSequence = Infinity
          
          // 找出剩余任务中 insert_sequence 最小的
          for (let i = 0; i < tasksLength; i++) {
            const task = tasks[i]
            if (task !== currentMin && task.insert_sequence < minSequence) {
              minIndex = i
              minSequence = task.insert_sequence
            }
          }
          
          if (minIndex !== -1) {
            currentMin = tasks[minIndex]
            this.insertTaskAtCorrectPosition(currentMin)
            inserted++
          }
        }
      } else {
        // 对于大量任务，使用排序后批量处理
        // 创建一个新数组并排序，避免修改原数组
        const sortedTasks = [...tasks].sort((a, b) => a.insert_sequence - b.insert_sequence)
        
        // 性能优化：使用 requestAnimationFrame 进行批处理，更好地配合浏览器渲染周期
        const batchSize = 50 // 每批处理的任务数量
        const totalBatches = Math.ceil(sortedTasks.length / batchSize)
        
        const processBatch = (batchIndex) => {
          const startIndex = batchIndex * batchSize
          const endIndex = Math.min(startIndex + batchSize, sortedTasks.length)
          
          // 处理当前批次的任务
          for (let i = startIndex; i < endIndex; i++) {
            this.insertTaskAtCorrectPosition(sortedTasks[i])
          }
          
          // 如果还有更多批次，安排下一个批次
          if (batchIndex < totalBatches - 1) {
            // 使用 requestAnimationFrame 配合浏览器渲染周期
            // 如果不支持，回退到 setTimeout
            if (typeof requestAnimationFrame !== 'undefined') {
              requestAnimationFrame(() => processBatch(batchIndex + 1))
            } else {
              setTimeout(() => processBatch(batchIndex + 1), 0)
            }
          }
        }
        
        // 开始处理第一批
        processBatch(0)
      }
    }
  }
})
