<template>
  <div class="dialog-page">
    <ZPaging
      use-chat-record-mode
      use-virtual-list
      cell-height-mode="dynamic"
      :refresher-enabled="true"
      :show-scrollbar="false"
      :loading-more-enabled="true"
      :hide-empty-view="true"
      height="100%"
      ref="zpagingRef"
      v-model="virtualList"
      :loading-more-custom-style="{ display: 'none', height: '0' }"
      @scrolltolower="onScrollToLower"
      @scrolltoupper="onScrollToUpper"
    >
      <template #top>
        <customNavbar :title="talkParams.username" id="navBarArea">
          <template
            #subTitle
            v-if="talkStore?.findItem(talkParams.index_name)?.group_type === 4"
          >
            <div class="text-[24rpx] text-[#999999]">公司群</div>
          </template>
          <template #right>
            <div class="mr-[36rpx] toChatSetting_btn">
              <tm-icon
                color="rgb(51, 51, 51)"
                :font-size="36"
                name="tmicon-gengduo"
                @click="toChatSettingsPage"
              ></tm-icon>
            </div>
          </template>
        </customNavbar>
      </template>
      <!-- <template #top>
            <div class="load-toolbar pointer">
              <span v-if="loadConfig.status == 0"> 正在加载数据中 ... </span>
              <span v-else-if="loadConfig.status == 1" @click="onScrollToLower"> 查看更多消息 ... </span>
              <span v-else class="no-more"> 没有更多消息了 </span>
            </div>
          </template> -->

      <!-- 数据加载状态栏 -->
      <div class="dialog-list" @touchstart="handleHidePanel">
        <div
          class="message-item"
          v-for="item in virtualList"
          :id="`zp-id-${item.msg_id}`"
          :key="item.zp_index"
          style="transform: scaleY(-1);"
        >
          <!-- 系统消息 -->
          <div v-if="item.msg_type >= 1000" class="message-box">
            <component
              :is="MessageComponents[item.msg_type] || 'unknown-message'"
              :extra="item.extra"
              :data="item"
            />
          </div>
          <!-- 撤回消息 -->
          <div v-else-if="item.is_revoke == 1" class="message-box">
            <revoke-message
              :login_uid="userStore.uid"
              :user_id="item.user_id"
              :nickname="item.nickname"
              :talk_type="item.talk_type"
              :datetime="item.created_at"
              :msg_id="item.msg_id"
            >
            <template v-if="canEditRevokedMessage(item) && item.user_id === userStore.uid">
              <span class="edit-revoked-message" @click="restoreRevokedMessage(item)">重新编辑</span>
            </template>
            </revoke-message>
          </div>

          <div
            v-else
            class="message-box record-box"
            :class="{
              'direction-rt': item.float == 'right',
              'multi-select': dialogueStore.isOpenMultiSelect,
              'multi-select-check': item.isCheck,
            }"
          >
            <!-- 多选按钮 -->
            <aside
              v-if="dialogueStore.isOpenMultiSelect"
              class="checkbox-column"
            >
              <!-- <n-checkbox size="small" :checked="item.isCheck" @update:checked="item.isCheck = !item.isCheck" /> -->
              <tm-checkbox
                :round="10"
                :defaultChecked="item.isCheck"
                @update:modelValue="item.isCheck = !item.isCheck"
                :size="42"
                color="#46299D"
              ></tm-checkbox>
            </aside>

            <!-- 头像信息 -->
            <aside class="avatar-column" @click="toUserDetailPage(item)">
              <im-avatar
                class="pointer"
                :src="item.avatar"
                :size="80"
                :username="item.nickname"
                @click="showUserInfoModal(item.user_id)"
              />
            </aside>

            <!-- 主体信息 -->
            <main class="main-column">
              <div class="talk-title">
                <span
                  class="nickname pointer"
                  v-show="talkParams.type == 2 && item.float == 'left'"
                >
                  <span class="at">@</span>
                  {{ item.nickname }}
                </span>
                <span>
                  {{ parseTime(item.created_at, '{m}/{d} {h}:{i}') }}
                </span>
              </div>

              <div
                class="talk-content"
                :class="{ pointer: dialogueStore.isOpenMultiSelect }"
              >
                <deepBubble
                  @clickMenu="(menuType) => onContextMenu(menuType, item)"
                  :isShowCopy="isShowCopy(item)"
                  :isShowWithdraw="isRevoke(talkParams.uid, item)"
                >
                  <component
                    class="component-content"
                    :key="item.zp_index"
                    :is="MessageComponents[item.msg_type] || 'unknown-message'"
                    :extra="item.extra"
                    :data="item"
                    :max-width="true"
                    :source="'panel'"
                  />
                </deepBubble>
                <!-- <div class="talk-tools">
                    <template v-if="talkParams.type == 1 && item.float == 'right'">
                      <loading theme="outline" size="19" fill="#000" :sxtrokeWidth="1" class="icon-rotate"
                        v-show="item.send_status == 1" />

                      <span v-show="item.send_status == 1"> 正在发送... </span>
                      <span v-show="item.send_status != 1"> 已送达 </span>
                    </template>

                  </div> -->
              </div>

              <div
                v-if="item.extra.reply"
                class="talk-reply pointer"
                @click="onJumpMessage(item.extra?.reply?.msg_id)"
              >
                <!-- <n-icon :component="ToTop" size="14" class="icon-top" /> -->
                <span class="ellipsis">
                  回复 {{ item.extra?.reply?.nickname }}:
                  {{ item.extra?.reply?.content }}
                </span>
              </div>
            </main>
          </div>
        </div>
        <div class="load-toolbar pointer" style="transform: scaleY(-1);">
          <span v-if="loadConfig.status == 0">正在加载数据中 ...</span>
          <span v-else-if="loadConfig.status == 1" @click="onScrollToLower">
            查看更多消息 ...
          </span>
          <span
            v-else-if="
              loadConfig.status != 0 &&
              loadConfig.status != 1 &&
              state.localPageLoadDone
            "
            class="no-more"
          >
            没有更多消息了
          </span>
        </div>
      </div>
      <template #bottom>
        <div class="footBox" id="footBoxArea">
          <div v-if="!dialogueStore.isOpenMultiSelect">
            <div
              class="pt-[16rpx] ml-[32rpx] mr-[32rpx] flex items-start justify-between"
            >
              <div class="flex-1 quillBox">
                <QuillEditor
                  ref="editor"
                  id="editor"
                  :options="editorOption"
                  @editorChange="onEditorChange"
                  style="width: 100%; flex: 1; height: 100%; border: none;"
                  @click="onEditorClick"
                />
                <!-- <tm-input type=textarea autoHeight focusColor="#F9F9F9" color="#F9F9F9" :inputPadding="[12]"
              placeholder=""></tm-input> -->
                <div class="quote-area" v-if="state?.quoteInfo">
                  <span
                    v-if="state?.quoteInfo?.msg_type === 1"
                    class="text-[28rpx] text-[#999]"
                  >
                    {{
                      state?.quoteInfo?.nickname +
                      ':' +
                      state?.quoteInfo?.extra?.content
                    }}
                  </span>
                  <span
                    v-if="state?.quoteInfo"
                    class="text-[28rpx] text-[#999]"
                  >
                    {{
                      state?.quoteInfo?.nickname +
                      ':' +
                      ChatMsgTypeMapping[state?.quoteInfo?.msg_type]
                    }}
                  </span>
                  <img
                    @click="clearQuoteInfo"
                    style="width: 30rpx; height: 30rpx;"
                    src="/src/static/image/login/check-circle-filled@3x.png"
                  />
                </div>
              </div>
              <div class="flex items-center justify-end h-[72rpx]">
                <tm-image
                  :margin="[10, 0]"
                  @click="handleEmojiPanel"
                  :width="52"
                  :height="52"
                  :round="12"
                  :src="state.isOpenEmojiPanel ? keyboard : smile"
                ></tm-image>
                <tm-image
                  @click="handleFilePanel"
                  :margin="[10, 0]"
                  :width="52"
                  :height="52"
                  :round="12"
                  :src="addCircleGray"
                ></tm-image>
                <tm-button
                  @click="onSendMessageClick"
                  :margin="[0, 0]"
                  :padding="[0, 30]"
                  color="#46299D"
                  :fontSize="28"
                  size="mini"
                  :shadow="0"
                  label="发送"
                ></tm-button>
              </div>
            </div>
            <div v-if="state.isOpenEmojiPanel" class="mt-[50rpx]">
              <emojiPanel @on-select="onEmoticonEvent" />
            </div>
            <div v-if="state.isOpenFilePanel" class="mt-[16rpx]">
              <filePanel
                @selectImg="handleSelectImg"
                :talkParams="talkParams"
              />
            </div>
          </div>
          <div v-else class="h-[232rpx]">
            <div
              class="flex items-center justify-center mt-[12rpx] text-[24rpx] text-[#747474] leading-[44rpx]"
            >
              <div class="mr-[8rpx]">已选中:</div>
              <div>{{ selectedMessage.length }}条消息</div>
            </div>
            <div
              class="flex items-center justify-around pl-[128rpx] pr-[128rpx] mt-[18rpx] text-[20rpx] text-[#737373]"
            >
              <div
                @click="handleMergeForward"
                class="flex flex-col items-center justify-center"
              >
                <tm-image :width="68" :height="68" :src="zu6050"></tm-image>
                <div class="mt-[6rpx]">合并转发</div>
              </div>
              <div
                @click="handleSingleForward"
                class="flex flex-col items-center justify-center"
              >
                <tm-image :width="68" :height="68" :src="zu6051"></tm-image>
                <div class="mt-[6rpx]">逐条转发</div>
              </div>
              <div
                @click="handleWechatForward"
                class="flex flex-col items-center justify-center"
              >
                <tm-image :width="68" :height="68" :src="zu6052"></tm-image>
                <div class="mt-[6rpx]">微信</div>
              </div>
              <div
                @click="handleDelete"
                class="flex flex-col items-center justify-center"
              >
                <tm-image :width="68" :height="68" :src="zu6053"></tm-image>
                <div class="mt-[6rpx]">删除</div>
              </div>
            </div>
          </div>

          <!--底部安全区-->
          <div class="content-placeholder"></div>
          <tm-drawer
            placement="bottom"
            v-model:show="state.showWin"
            :hideHeader="true"
            :height="416"
            :round="6"
          >
            <div class="w-full h-full flex flex-col items-center">
              <div
                class="mt-[46rpx] mb-[44rpx] leading-[48rpx] text-[#747474] text-[24rpx]"
              >
                撤回该条消息?
              </div>
              <div class="divider"></div>
              <div
                @click="withdrawerConfirm"
                class="mt-[32rpx] mb-[32rpx] text-[32rpx] text-[#CF3050] leading-[48rpx]"
              >
                撤回
              </div>
              <div class="divider"></div>
              <div
                @click="state.showWin = false"
                class="mt-[32rpx] mb-[32rpx] text-[32rpx] text-[#000000] leading-[48rpx]"
              >
                取消
              </div>
            </div>
          </tm-drawer>
        </div>
      </template>
    </ZPaging>
    <tm-drawer
      placement="bottom"
      v-model:show="state.isShowMentionSelect"
      :hideHeader="true"
      :round="5"
      :height="state.mentionSelectHeight"
    >
      <div
        class="mention-select-drawer flex flex-row flex-1 flex-row flex-row-center-between"
      >
        <div
          class="cancel-btns flex-row flex flex-row-center-start"
          style="width: 210rpx;"
        >
          <div
            class="hide-btn"
            v-if="!state.mentionIsMulSelect"
            @click="hideMentionSelect"
          >
            <img
              style="width: 40rpx; height: 40rpx;"
              src="/src/static/image/chatList/mention_select_hide_bg.png"
            />
            <img
              style="
                position: absolute;
                top: 50%;
                left: 50%;
                margin-left: -9rpx;
                margin-top: -5rpx;
              "
              src="/src/static/image/chatList/mention_select_hide_icon.png"
            />
          </div>
          <span
            style="flex-shrink: 0; display: block;"
            class="text-[32rpx] font-regular text-[#191919]"
            v-if="state.mentionIsMulSelect"
            @click="changeMentionSelectMul(false)"
          >
            {{ $t('cancel') }}
          </span>
        </div>
        <div
          class="flex flex-row-center-center flex-col"
          style="padding: 6rpx 0;"
        >
          <text>{{ $t('chat.mention.select') }}</text>
        </div>
        <div class="flex-row flex flex-row-center-end" style="width: 210rpx;">
          <div
            class="mention-edit-btn"
            v-if="!state.mentionIsMulSelect"
            @click="changeMentionSelectMul(true)"
          >
            <span class="text-[32rpx] font-regular text-[#191919]">
              {{ $t('button.multiple.choice') }}
            </span>
          </div>
          <div
            class="mention-done-btn"
            :class="
              state?.selectedMembersNum > 0 ? 'mention-done-btn-can-do' : ''
            "
            v-if="state.mentionIsMulSelect"
            @click="confirmMentionSelect"
          >
            <span class="text-[32rpx] font-regular text-[#191919]">
              {{ $t('button.text.done') }}
            </span>
            <span
              class="text-[32rpx] font-regular text-[#191919]"
              v-if="state?.selectedMembersNum > 0"
            >
              {{ '(' + state?.selectedMembersNum + ')' }}
            </span>
          </div>
        </div>
      </div>
      <selectMemberByAlphabet
        :manageType="'mention'"
        ref="selectMemberByAlphabetRef"
        :selectAreaHeight="state.selectAreaHeight"
        @updateSelectedMembersNum="updateSelectedMembersNum"
        :isMulSelect="state.mentionIsMulSelect"
        @getSelectResult="getSelectResult"
        @getMentionSelectLists="getMentionSelectLists"
      ></selectMemberByAlphabet>
    </tm-drawer>
  </div>
</template>
<script setup>
import selectMemberByAlphabet from '../chatSettings/components/selectMemberByAlphabet.vue'
import {
  ref,
  reactive,
  watch,
  computed,
  onMounted,
  onUnmounted,
  nextTick,
} from 'vue'
import { QuillEditor, Quill } from '@vueup/vue-quill'
import EmojiBlot from './formats/emoji'
import { useChatList } from '@/store/chatList/index.js'
import { useAuth } from '@/store/auth'
import {
  useUserStore,
  useDialogueStore,
  useUploadsStore,
  useEditorDraftStore,
  useTalkStore,
  useSettingsStore,
  useDialogueListStore,
} from '@/store'
import addCircleGray from '@/static/image/chatList/addCircleGray.png'
import {
  MessageComponents,
  ForwardableMessageType,
  ChatMsgTypeMapping,
} from '@/constant/message'
import { formatTime, parseTime } from '@/utils/datetime'
import { deltaToMessage, deltaToString, isEmptyDelta } from './util'
import smile from '@/static/image/chatList/smile@2x.png'
import keyboard from '@/static/image/chatList/keyboard@2x.png'
import { useInject, useTalkRecord } from '@/hooks'
import { emitCall } from '@/utils/common'
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
import useZPaging from '@/uni_modules/z-paging/components/z-paging/js/hooks/useZPaging.js'
import emojiPanel from './components/emojiPanel.vue'
import filePanel from './components/filePanel.vue'
import lodash from 'lodash'
import { ServePublishMessage,detailGetRecordsContext } from '@/api/chat'
import copy07 from '@/static/image/chatList/copy07@2x.png'
import multipleChoices from '@/static/image/chatList/multipleChoices@2x.png'
import cite from '@/static/image/chatList/cite@2x.png'
import withdraw from '@/static/image/chatList/withdraw@2x.png'
import delete07 from '@/static/image/chatList/delete@2x.png'
import zu6050 from '@/static/image/chatList/zu6050@2x.png'
import zu6051 from '@/static/image/chatList/zu6051@2x.png'
import zu6052 from '@/static/image/chatList/zu6052@2x.png'
import zu6053 from '@/static/image/chatList/zu6053@2x.png'
import deepBubble from '@/components/deep-bubble/deep-bubble.vue'
import { isRevoke } from './menu'
import useConfirm from '@/components/x-confirm/useConfirm.js'
import { onLoad as uniOnload } from '@dcloudio/uni-app'

Quill.register('formats/emoji', EmojiBlot)

const selectMemberByAlphabetRef = ref(null)

const {
  getDialogueList,
  updateZpagingRef,
  virtualList,
} = useDialogueListStore()
const talkStore = useTalkStore()
const { showConfirm } = useConfirm()
const settingsStore = useSettingsStore()
const userStore = useUserStore()
const dialogueStore = useDialogueStore()
const editorDraftStore = useEditorDraftStore()
const editor = ref()
const zpagingRef = ref()
useZPaging(zpagingRef)
const indexName = computed(() => dialogueStore.index_name)
const talkParams = reactive({
  uid: computed(() => userStore.uid),
  index_name: computed(() => dialogueStore.index_name),
  type: computed(() => dialogueStore.talk.talk_type),
  receiver_id: computed(() => dialogueStore.talk.receiver_id),
  username: computed(() => dialogueStore.talk.username),
  online: computed(() => dialogueStore.online),
  keyboard: computed(() => dialogueStore.keyboard),
  num: computed(() => dialogueStore.members.length),
})

const state = ref({
  isOpenEmojiPanel: false,
  isOpenFilePanel: false,
  showWin: false,
  onfocusItem: null,
  sessionId: '',
  localPageLoadDone: true, //分页加载缓存中的聊天记录是否完毕
  quoteInfo: null, //引用信息
  mentionIsMulSelect: false, //是否是多选提醒的人
  selectedMembersNum: 0, //选中的要提醒的人数
  mentionSelectHeight: 0, //选择要提醒人的区域高度
  selectAreaHeight: 0, //选择要提醒人的可选人员列表区域高度
  isShowMentionSelect: false, //是否显示要提醒人的选择区域
  useCustomLoadMore: false, //是否使用自定义加载更多事件(下拉刷新、上拉加载)
})

uniOnload((options) => {
  if (options.sessionId) {
    state.value.sessionId = options.sessionId
  }
  if (options.msgInfo) {
    const msgInfo = JSON.parse(decodeURIComponent(options.msgInfo))
    queryRecordsByMsgInfo(msgInfo)
    state.value.useCustomLoadMore = true
    return
  }
  initData()
})

const handleEmojiPanel = () => {
  state.value.isOpenFilePanel = false
  state.value.isOpenEmojiPanel = !state.value.isOpenEmojiPanel
}
const handleFilePanel = () => {
  state.value.isOpenEmojiPanel = false
  state.value.isOpenFilePanel = !state.value.isOpenFilePanel
}

//点击隐藏表情/文件上传 面板
const handleHidePanel = () => {
  state.value.isOpenFilePanel = false
  state.value.isOpenEmojiPanel = false
}

//点击编辑区聚焦输入框
const onEditorClick = () => {
  handleHidePanel()
}

const onSendMessage = (data = {}, callBack) => {
  let message = {
    ...data,
    receiver: {
      receiver_id: talkParams.receiver_id,
      talk_type: talkParams.type,
    },
  }

  ServePublishMessage(message)
    .then(({ code, message }) => {
      if (code == 200) {
        if (callBack) {
          callBack(true)
        }
      } else {
        message.warning(message)
      }
    })
    .catch(() => {
      message.warning('网络繁忙,请稍后重试!')
    })
}

const onSendMessageClick = () => {
  let delta = getQuill().getContents()
  if (state.value.quoteInfo) {
    delta.ops.unshift({
      insert: {
        quote: {
          id: state.value.quoteInfo.msg_id,
        },
      },
    })
  }
  let data = deltaToMessage(delta)

  if (data.items.length === 0) {
    return
  }

  switch (data.msgType) {
    case 1: // 文字消息
      if (data.items[0].content.length > 1024) {
        return message.info('发送内容超长,请分条发送')
      }
      onSendTextEvent({
        data,
        callBack: (ok) => {
          if (!ok) return
          getQuill().setContents([], Quill.sources.USER)
          if (state.value.quoteInfo) {
            state.value.quoteInfo = null
          }
        },
      })
      break
  }
}

// 发送文本消息
const onSendTextEvent = lodash.throttle((value) => {
  let { data, callBack } = value

  let message = {
    type: 'text',
    content: data.items[0].content,
    quote_id: data.quoteId,
    mentions: data.mentionUids,
  }

  onSendMessage(message, callBack)
}, 1000)

// 编辑器输入事件
const onInputEvent = ({ data }) => {
  talkStore.updateItem({
    index_name: indexName.value,
    draft_text: data,
  })

  // 判断对方是否在线和是否需要推送
  // 3秒时间内推送一次
  if (settingsStore.isKeyboard && props.online) {
    onKeyboardPush()
  }
}

// 发送表情消息
const onSendEmoticonEvent = ({ data }) => {
  onSendMessage({ type: 'emoticon', emoticon_id: data })
}

// 注册事件
const evnets = {
  text_event: onSendTextEvent,
  input_event: onInputEvent,
  emoticon_event: onSendEmoticonEvent,
  history_event: () => {
    isShowHistory.value = true
  },
}

const {
  loadConfig,
  records,
  onLoad,
  onRefreshLoad,
  onJumpMessage,
} = useTalkRecord(talkParams.uid)

const getQuill = () => {
  return editor.value?.getQuill()
}

const isShowCopy = (item) => {
  switch (item.msg_type) {
    case 1:
      return true
    case 3:
      return true
    case 5:
      return true
    case 6:
      return true
    default:
      return false
  }
}

const selectedMessage = computed(() => {
  return virtualList.value.filter((item) => item.isCheck)
})

// 编辑器事件
const onEditorEvent = (msg) => {
  evnets[msg.event] && evnets[msg.event](msg)
}

const getQuillSelectionIndex = () => {
  let quill = getQuill()
  return (quill.getSelection() || {}).index
}

const onEmoticonEvent = (data) => {
  if (data.type == 1) {
    const quill = getQuill()
    let index = getQuillSelectionIndex()

    if (index == 1 && quill.getLength() == 1 && quill.getText(0, 1) == '\n') {
      quill.deleteText(0, 1)
      index = 0
    }
    if (data.img) {
      quill.insertEmbed(index, 'emoji', {
        alt: data.value,
        src: data.img,
      })
    } else {
      quill.insertText(index, data.value)
    }

    quill.setSelection(index + 1, 0, 'user')
  } else {
    let fn = emitCall('emoticon_event', data.value, () => {})
    emit('editor-event', fn)
  }
}

const onEditorChange = () => {
  let delta = getQuill().getContents()

  let text = deltaToString(delta)

  if (
    text.length > 0 &&
    text.slice(-2).trim() === '@' &&
    talkParams.type === 2
  ) {
    state.value.isShowMentionSelect = true
  }

  if (!isEmptyDelta(delta)) {
    editorDraftStore.items[indexName.value || ''] = JSON.stringify({
      text: text,
      ops: delta.ops,
    })
  } else {
    // 删除 editorDraftStore.items 下的元素
    delete editorDraftStore.items[indexName.value || '']
  }
  onEditorEvent(emitCall('input_event', text))
  // emit('editor-event', emitCall('input_event', text))
  // 清理过期的撤回消息(超过5分钟)
  const now = new Date().getTime()
  Object.keys(state.value.revokedMessages).forEach(msgId => {
    if ((now - state.value.revokedMessages[msgId].revokeTime) > 5 * 60 * 1000) {
      delete state.value.revokedMessages[msgId]
    }
  })
}

const onClipboardMatcher = (node, Delta) => {
  const ops = []

  Delta.ops.forEach((op) => {
    // 如果粘贴了图片,这里会是一个对象,所以可以这样处理
    if (op.insert && typeof op.insert === 'string') {
      ops.push({
        insert: op.insert, // 文字内容
        attributes: {}, //文字样式(包括背景色和文字颜色等)
      })
    } else {
      ops.push(op)
    }
  })

  Delta.ops = ops
  return Delta
}

const editorOption = {
  debug: false,
  modules: {
    toolbar: false,
    clipboard: {
      // 粘贴版,处理粘贴时候的自带样式
      matchers: [[Node.ELEMENT_NODE, onClipboardMatcher]],
    },

    keyboard: {
      bindings: {
        enter: {
          key: 13,
          handler: onSendMessageClick,
        },
      },
    },

    // imageUploader: {
    //   upload: onEditorUpload
    // },

    // mention: {
    //   allowedChars: /^[\u4e00-\u9fa5]*$/,
    //   mentionDenotationChars: ['@'],
    //   positioningStrategy: 'fixed',
    //   renderItem: (data) => {
    //     const el = document.createElement('div')
    //     el.className = 'ed-member-item'
    //     el.innerHTML = `<img src="${data.avatar}" class="avator"/>`
    //     el.innerHTML += `<span class="nickname">${data.nickname}</span>`
    //     return el
    //   },
    //   source: function (searchTerm, renderList) {
    //     if (!props.members.length) {
    //       return renderList([])
    //     }

    //     let list = [
    //       { id: 0, nickname: '所有人', avatar: defAvatar, value: '所有人' },
    //       ...props.members
    //     ]

    //     const items = list.filter(
    //       (item) => item.nickname.toLowerCase().indexOf(searchTerm) !== -1
    //     )

    //     renderList(items)
    //   },
    //   mentionContainerClass: 'ql-mention-list-container me-scrollbar me-scrollbar-thumb'
    // }
  },
  placeholder: '',
}

const handleSelectImg = (data) => {
  onSendMessage({ ...data })
}

const virtualListChange = (vList) => {
  virtualList.value = vList
}

const onContextMenu = (menuType, item) => {
  console.log(menuType, item, 'item')
  switch (menuType) {
    case 'actionCopy':
      actionCopy(item)
      break
    case 'multipleChoose':
      multipleChoose(item)
      break
    case 'actionCite':
      actionCite(item)
      break
    case 'actionWithdraw':
      actionWithdraw(item)
      break
    case 'actionDelete':
      actionDelete(item)
      break

    default:
      break
  }
}

const actionCopy = (item) => {
  console.log('复制')
  let content = ''
  switch (item.msg_type) {
    case 1:
      content = item.extra.content
      break
    case 3:
      content = item.extra.url
      break
    case 5:
      content = item.extra.url
      break

    default:
      break
  }
  uni.setClipboardData({
    data: content,
  })
}

const multipleChoose = (item) => {
  item.isCheck = true
  dialogueStore.setMultiSelect(true)
}

const actionCite = (item) => {
  console.log('引用')
  state.value.quoteInfo = item
}

//清除引用信息
const clearQuoteInfo = () => {
  state.value.quoteInfo = null
}

const actionWithdraw = (item) => {
  console.log('撤回')
  state.value.onfocusItem = item
  state.value.showWin = true
}

const withdrawerConfirm = () => {
  dialogueStore.ApiRevokeRecord(state.value.onfocusItem.msg_id)
  state.value.onfocusItem = null
  state.value.showWin = false
}

// 添加检查是否可以重新编辑撤回消息的函数
const canEditRevokedMessage = (item) => {
  console.log( item)
  if(item.is_revoke === 1 && item.msg_type === 1) {
    const now = new Date().getTime();
    const revokeTime = new Date(item.created_at).getTime();
    console.log(now)
    // 检查是否在5分钟内
    return (now - revokeTime) <= 5 * 60 * 1000
  }
  return false

}

// 添加恢复撤回消息到输入框的函数
const restoreRevokedMessage = async (item) => {
  // 接口拿数据,之后把查询的内容给输入框
  const res = await detailGetRecordsContext({
    msgId: item.msg_id
  })
  console.log(res)
  if(res.code == 200) {
    const content = res.data.item?.extra?.content;
    const quill = getQuill()
    quill.setText(content)
    // 将光标设置到文本末尾
    quill.setSelection(content.length, 0)
    quill.focus()
  }
  /* const revokedMsg = state.value.revokedMessages[msgId]

  // 根据消息类型处理
  if (revokedMsg.msgType === 1) { // 文本消息
    const quill = getQuill()
    quill.setText(revokedMsg.content)
    quill.focus()
  } */
  // 可以根据需要添加其他类型消息的处理
}


const actionDelete = (item) => {
  console.log('删除')
  item.isCheck = true
  handleDelete()
}

const handleMergeForward = () => {
  if (selectedMessage.value.length == 0) {
    return message.warning('未选择消息')
  }
  console.log('合并转发')
  dialogueStore.setForwardType(2)
  dialogueStore.setForwardMessages(selectedMessage.value)
  uni.navigateTo({
    url: '/pages/chooseChat/index',
    success: function (res) {
      clearMultiSelect()
    },
  })
}

const handleSingleForward = () => {
  if (selectedMessage.value.length == 0) {
    return message.warning('未选择消息')
  }
  console.log('逐条转发')
  dialogueStore.setForwardType(1)
  dialogueStore.setForwardMessages(selectedMessage.value)
  uni.navigateTo({
    url: '/pages/chooseChat/index',
    success: function (res) {
      clearMultiSelect()
    },
  })
}

const handleWechatForward = () => {
  if (selectedMessage.value.length == 0) {
    return message.warning('未选择消息')
  }
  console.log('微信转发')
}

const handleDelete = () => {
  if (selectedMessage.value.length == 0) {
    return message.warning('未选择消息')
  }
  console.log('删除')
  showConfirm({
    content: '确定删除聊天记录',
    confirmText: '删除',
    confirmColor: '#CF3050',
    onConfirm: async () => {
      const msgIds = selectedMessage.value.map((item) => item.msg_id)
      virtualList.value = virtualList.value.filter(
        (item) => !msgIds.includes(item.msg_id),
      )
      dialogueStore.ApiDeleteRecord(msgIds)
      clearMultiSelect()
    },
    onCancel: () => {},
  })
}

//更新选中的要提醒的人数
const updateSelectedMembersNum = (numChange) => {
  state.value.selectedMembersNum = state.value.selectedMembersNum + numChange
}

watch(
  () => zpagingRef.value,
  (newValue, oldValue) => {
    if (newValue) {
      updateZpagingRef(newValue)
    }
  },
)

watch(
  () => virtualList.value,
  (newValue, oldValue) => {
    if (newValue) {
      const dialogueList = getDialogueList(talkParams.index_name)
      // console.log(newValue[newValue.length - 1]?.sequence, dialogueList?.records?.[0]?.sequence)
      if (
        newValue[newValue.length - 1]?.sequence ===
        dialogueList.records?.[0]?.sequence
      ) {
        //相同意味着分页加载缓存中的聊天记录完毕
        state.value.localPageLoadDone = true
      } else {
        state.value.localPageLoadDone = false
      }
    }
  },
  {
    deep: true,
  },
)

const onScrollToLower = () => {
  if (state.value.useCustomLoadMore) {
    const tempVirtualList = lodash.cloneDeep(virtualList.value).reverse()
    const dialogueList = getDialogueList(talkParams.index_name)
    const recordIndex = dialogueList.records.findIndex(
      (record) => record.msg_id === tempVirtualList[0].msg_id,
    )
    if (recordIndex === -1) {
    } else {
      if (tempVirtualList[0].sequence > dialogueList.records[0].sequence) {
        virtualList.value = dialogueList.records
          .slice(0, recordIndex)
          .concat(tempVirtualList)
          .reverse()
        // zpagingRef.value.setLocalPaging(
        //   dialogueList.records
        //     .slice(0, recordIndex)
        //     .concat(tempVirtualList)
        //     .reverse(),
        //   // zpagingRef.value.scrollIntoViewById('zp-id-' + virtualList.value[virtualList.value.length - 1].msg_id)
        // )

        console.log(virtualList.value)
      }
    }
    return
  }
  if (state.value.localPageLoadDone) {
    //本地缓存的聊天记录分页加载完之后,才可以请求接口
    onRefreshLoad()
  }
}

//本来的下拉刷新——列表倒置后为上拉加载
const onScrollToUpper = () => {
  if (state.value.useCustomLoadMore) {
    const tempVirtualList = lodash.cloneDeep(virtualList.value).reverse()
    const dialogueList = getDialogueList(talkParams.index_name)
    const recordIndex = dialogueList.records.findIndex(
      (record) =>
        record.msg_id === tempVirtualList[tempVirtualList.length - 1].msg_id,
    )
    if (recordIndex === -1) {
    } else {
      if (
        tempVirtualList[tempVirtualList.length - 1].sequence <
        dialogueList.records[dialogueList.records.length - 1].sequence
      ) {
        virtualList.value = tempVirtualList
          .concat(
            dialogueList.records.slice(
              recordIndex + 1,
              dialogueList.records.length,
            ),
          )
          .reverse()
        // zpagingRef.value.setLocalPaging(
        //   tempVirtualList
        //     .concat(
        //       dialogueList.records.slice(
        //         recordIndex + 1,
        //         dialogueList.records.length,
        //       ),
        //     )
        //     .reverse(),
        //   // zpagingRef.value.scrollIntoViewById('zp-id-' + virtualList.value[virtualList.value.length - 1].msg_id)
        // )

        console.log(virtualList.value)
      }
    }
  }
}

const clearMultiSelect = () => {
  dialogueStore.setMultiSelect(false)
  virtualList.value.forEach((item) => {
    item.isCheck = false
  })
}

const initData = async () => {
  const dialogueList = getDialogueList(talkParams.index_name)

  let objT = {
    uid: talkParams.uid,
    talk_type: talkParams.type,
    receiver_id: talkParams.receiver_id,
    index_name: talkParams.index_name,
    direction: dialogueList ? 'down' : 'up',
    no_limit: dialogueList ? 1 : 0,
  }
  await onLoad({ ...objT })
  zpagingRef.value?.setLocalPaging(records.value)
}

//点击跳转到聊天设置页面
const toChatSettingsPage = () => {
  uni.navigateTo({
    url:
      '/pages/chatSettings/index?groupId=' +
      talkParams?.receiver_id +
      '&sessionId=' +
      state.value.sessionId,
  })
}

//点击跳转到用户详情页面
const toUserDetailPage = (userItem) => {
  uni.navigateTo({
    url:
      '/pages/dialog/dialogDetail/userDetail?erpUserId=' + userItem.erp_user_id,
  })
}

//切换提醒的人选择弹窗多选状态
const changeMentionSelectMul = (status) => {
  state.value.mentionIsMulSelect = status
}

//隐藏要提醒人的选择
const hideMentionSelect = () => {
  state.value.isShowMentionSelect = false
}

//确认要提醒人的选择
const confirmMentionSelect = () => {
  if (state?.value.selectedMembersNum > 0) {
    if (selectMemberByAlphabetRef.value) {
      selectMemberByAlphabetRef.value.confirmSelectMembers()
    }
    hideMentionSelect()
  }
}

//获取选择的结果
const getSelectResult = (mentionSelect) => {
  console.log(mentionSelect)
  getMentionSelectLists(mentionSelect)
}

//处理要提醒人的消息样式
const getMentionSelectLists = (mentionSelectList) => {
  console.log(mentionSelectList)
  let mentionUserIds = []
  let mentionUsers = getQuill().getContents().ops //先读出来之前的信息内容
  mentionUsers[0].insert =
    mentionUsers[0].insert.slice(0, -2) + mentionUsers[0].insert.slice(-1)
  console.log(mentionUsers[0].insert)
  mentionSelectList.forEach((mentionSelectItem) => {
    mentionUserIds.push(mentionSelectItem.id)
    mentionUsers.push({
      insert: '@' + mentionSelectItem.nickname + ' ',
      attributes: {
        // mention: {
        //   id: mentionSelectItem.id,
        // },
        color: '#1890ff',
      },
    })
  })
  getQuill().setContents(mentionUsers)
  hideMentionSelect()
}

//根据msg信息找到对应的聊天记录,并根据sequence等查看上下文
const queryRecordsByMsgInfo = (msgInfo) => {
  console.log(msgInfo)
  const dialogueList = getDialogueList(talkParams.index_name)
  const recordIndex = dialogueList.records.findIndex(
    (record) => record.msg_id === msgInfo.msg_id,
  )
  if (recordIndex === -1) {
  } else {
    // console.log(recordIndex)
    const startRecordIndex = Math.max(0, recordIndex - 10)
    const endRecordIndex = Math.max(0, recordIndex + 10)
    // console.log(dialogueList.records.slice(startRecordIndex, endRecordIndex))
    // console.log(recordIndex-startRecordIndex)
    const recordsList = dialogueList.records.slice(
      startRecordIndex,
      endRecordIndex,
    )
    nextTick(() => {
      zpagingRef.value.complete(recordsList.reverse())
      loadConfig.status = dialogueList.records?.[0]?.sequence > 1 ? 1 : 2
      nextTick(() => {
        let offset = uni.getSystemInfoSync().windowHeight
        const navBarAreaQuery = uni.createSelectorQuery()
        navBarAreaQuery
          .select('#navBarArea')
          .boundingClientRect((res) => {
            if (res) {
              // console.log('元素高度:', res.height)
              offset = offset - res.height
            }
          })
          .exec()
        const footBoxAreaQuery = uni.createSelectorQuery()
        footBoxAreaQuery
          .select('#footBoxArea')
          .boundingClientRect((res) => {
            if (res) {
              // console.log('元素高度:', res.height)
              offset = offset - res.height
            }
          })
          .exec()
        setTimeout(() => {
          zpagingRef.value.scrollIntoViewById(
            'zp-id-' + msgInfo.msg_id,
            offset - 60,
          )
        }, 1000)
      })
    })
  }
}

onMounted(async () => {
  nextTick(() => {
    state.value.mentionSelectHeight = pxTorPx(
      uni.getSystemInfoSync().windowHeight * 0.86,
    )

    state.value.selectAreaHeight =
      rpxToPx(state.value.mentionSelectHeight) - rpxToPx(90) + 'px'
  })
})

const pxTorPx = (px) => {
  const sysInfo = uni.getSystemInfoSync()
  const rpx = px / (sysInfo.screenWidth / 750)
  return rpx
}

const rpxToPx = (rpx) => {
  const sysInfo = uni.getSystemInfoSync()
  const px = (sysInfo.screenWidth / 750) * rpx
  return px
}

onUnmounted(() => {
  dialogueStore.setDialogue({})
  clearMultiSelect()
})
</script>
<style scoped lang="less">
.dialog-page {
  flex: 1;
  background-image: url('@/static/image/clockIn/z3280@3x.png');
  background-size: cover;
  background-position: bottom center;
  background-attachment: fixed;
  width: 100%;

  .dialog-list {
    padding: 20rpx 32rpx;
  }

  .toChatSetting_btn {
    ::v-deep .tmicon-gengduo {
      line-height: unset !important;
    }
  }
}

.edit-revoked-message {
  margin-left: 10rpx;
  color: #46299D;
  cursor: pointer;
  font-size: 24rpx;

  &:hover {
    text-decoration: underline;
  }
}

.searchRoot {
  background-color: #fff;
  padding: 22rpx 18rpx;
}

.contentRoot {
  margin-top: 20rpx;
  background-color: #fff;
}

.footBox {
  min-height: 162rpx;
  background-color: #fff;

  .quote-area {
    margin: 4rpx 0 0 0;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    overflow: hidden;
    width: 100%;
    span {
      display: -webkit-inline-box;
      text-overflow: ellipsis;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
      width: 100%;
    }
    img {
      margin: 0 0 0 30rpx;
      flex-shrink: 0;
    }
  }
}

.load-toolbar {
  height: 50rpx;
  color: #409eff;
  text-align: center;
  line-height: 50rpx;
  font-size: 24rpx;

  .no-more {
    color: #b9b3b3;
  }
}

.message-item {
  &.border {
    border-radius: 16rpx;
  }
}

.message-box {
  width: 100%;
  min-height: 30rpx;
  margin-bottom: 5rpx;
}

.record-box {
  display: flex;
  flex-direction: row;
  align-items: flex-start;

  .checkbox-column {
    display: flex;
    justify-content: center;
    width: 42rpx;
    order: 1;
    user-select: none;
    margin-top: 20rpx;
    margin-right: 20rpx;
  }

  .avatar-column {
    width: 80rpx;
    display: flex;
    align-items: center;
    order: 2;
    user-select: none;
    margin-top: 16rpx;
    flex-direction: column;
  }

  .main-column {
    flex: 1 auto;
    order: 3;
    position: relative;
    box-sizing: border-box;
    padding: 16rpx 20rpx 14rpx 20rpx;
    // overflow: hidden;
    min-height: 30px;

    .talk-title {
      display: flex;
      align-items: center;
      margin-bottom: 6rpx;
      font-size: 24rpx;
      user-select: none;
      color: #bababa;
      opacity: 1;

      &.show {
        opacity: 1;
      }

      .nickname {
        color: var(--im-text-color);
        margin-right: 5rpx;

        .at {
          display: none;
        }

        &:hover {
          color: var(--im-primary-color);

          .at {
            display: inline-block;
          }
        }
      }

      span {
        transform: scale(0.88);
        transform-origin: left center;
      }
    }

    .talk-content {
      display: flex;
      justify-content: flex-start;
      align-items: flex-end;

      box-sizing: border-box;
      width: 100%;

      .talk-tools {
        display: flex;
        margin: 0 16rpx;
        color: #a79e9e;
        font-size: 24rpx;
        user-select: none;
        align-items: center;
        justify-content: space-around;

        .more-tools {
          visibility: hidden;
          margin-left: 5rpx;
        }
      }
    }

    .talk-reply {
      display: flex;
      align-items: flex-start;
      align-items: center;
      width: fit-content;
      padding: 8rpx;
      margin-top: 6rpx;
      margin-right: auto;
      font-size: 24rpx;
      color: #8f8f8f;
      word-break: break-all;
      background-color: var(--im-message-left-bg-color);
      border-radius: 10rpx;
      max-width: 450rpx;
      overflow: hidden;
      user-select: none;

      .icon-top {
        margin-right: 6rpx;
      }

      .ellipsis {
        display: -webkit-inline-box;
        text-overflow: ellipsis;
        -webkit-line-clamp: 3;
        -webkit-box-orient: vertical;
        overflow: hidden;
      }
    }

    &:hover {
      .talk-title {
        opacity: 1;
      }

      .more-tools {
        visibility: visible !important;
      }
    }
  }

  &.direction-rt {
    .avatar-column {
      order: 3;
    }

    .main-column {
      order: 2;

      .talk-title {
        justify-content: flex-end;

        span {
          transform-origin: right center;
        }
      }

      .talk-content {
        flex-direction: row-reverse;
      }

      .talk-reply {
        margin-right: 0;
        margin-left: auto;
      }
    }
  }

  &.multi-select {
    border-radius: 5px;

    &:hover,
    &.multi-select-check {
      background-color: var(--im-active-bg-color);
    }
  }
}

.content-placeholder {
  height: 58rpx;
}

.quillBox {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  :deep(.ql-clipboard) {
    position: relative;
    opacity: 0;
    height: 1rpx;
    overflow: auto;
  }

  :deep(.ql-editor) {
    padding: 14rpx 22rpx;
    background-color: #f9f9f9;
    border-radius: 8rpx;
    outline: none !important;
    max-height: 294rpx;
    overflow: auto;
    line-height: 44rpx;
    font-size: 32rpx;

    p {
      display: inline-flex;
      align-items: center;
      justify-content: flex-start;
      flex-wrap: wrap;
      white-space: normal;
      word-break: break-all;

      .ed-emoji {
        width: 44rpx;
        height: 44rpx;
        display: inline-block;
      }

      span {
        user-select: all;
      }
    }
  }
}

:deep(.wd-action-sheet) {
  background-color: #8b8b8b !important;
}

:deep(.wd-action-sheet__panel-title) {
  color: #fff !important;
}

.component-content {
  position: relative;
  z-index: 1;
  /* 确保 z-index 低于 deepBubble */
}
.divider {
  width: 100%;
  height: 1rpx;
  background-color: #e7e7e7;
}

.mention-select-drawer {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  padding: 36rpx 32rpx 0;
  .cancel-btns {
    flex-shrink: 0;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    .hide-btn {
      display: flex;
      flex-direction: row;
      align-items: center;
      justify-content: center;
      position: relative;
      text {
      }
      img {
        width: 18rpx;
        height: 10rpx;
      }
    }
  }

  .mention-done-btn {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    padding: 6rpx 24rpx;
    background-color: #f3f3f3;
    border-radius: 8rpx;
    flex-shrink: 0;
    span {
      color: #bababa;
      line-height: 40rpx;
      flex-shrink: 0;
    }
  }

  .mention-done-btn-can-do {
    background-color: #46299d;
    span {
      color: #fff;
    }
  }

  .mention-edit-btn {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-end;
    flex-shrink: 0;
    span {
      flex-shrink: 0;
    }
  }
}
</style>