<template>
  <div class="flex">
    <div class="w-[300px] h-screen flex flex-col bg-white" v-show="show">
      <div class="pl-3 h-12 flex items-center border-b gap-x-2 bg-white">
        <div class="">会话列表</div>
      
        <div class="grow text-xs text-slate-600">客户列表</div>
        <div class="mr-2">
          <SvgIcon name="speaker-wave" class="w-5 h-5 text-indigo-600" v-if="alterTone"
            :class="[superAlterTone ? 'text-red-600' : '']" />
          <SvgIcon name="speaker-x-mark" class="w-5 h-5 text-indigo-600" v-if="!alterTone" />
        </div>
        <div></div>
        
        <div class="cursor-pointer hover:bg-gray-200 h-7 w-7 rounded flex items-center justify-center">
          <el-dropdown>
            <SvgIcon name="setting" class="w-5 h-5 text-indigo-600" />
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item @click="logout">退出登录</el-dropdown-item>
              </el-dropdown-menu>
              <el-dropdown-menu>
                <el-dropdown-item @click="onSwitchAlterTone">
                  <div class="flex flex-row items-center justify-center">
                    <span class="mr-2">提示音</span>
                    <el-switch v-model="alterTone" />
                  </div>
                </el-dropdown-item>
              </el-dropdown-menu>
              <el-dropdown-menu>
                <el-dropdown-item @click="onSwitchSuperAlterTone">
                  <div class="flex flex-row items-center justify-center">
                    <span class="mr-2">超强提示音</span>
                    <el-switch v-model="superAlterTone" />
                  </div>
                </el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </div>
      </div>
      <div class="px-3 py-2">
        <div style="text-align: center;"> <el-switch @click="onMessageListTab" v-model="value" size="small" active-text="最新消息优先" inactive-text="最早消息优先" />
       </div>
        <div class="relative mt-2 rounded-md shadow-sm">
          <input v-model="params.username" type="text" name="username" id="username" class="block w-full outline-0 rounded-md border-0 py-1.5 pl-3 pr-10
              text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400
              focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6" placeholder="搜索" />
          <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
            <SvgIcon name="search" class="h-5 w-5 text-gray-400" aria-hidden="true" />
          </div>
        </div>
      </div>
      <el-scrollbar class="py-3 pl-3 grow min-h-[80vh]" @scroll="handleScroll" ref="scrollbarRef">
        <div class="transition flex items-center p-2 mr-2 cursor-pointer rounded-md relative mt-1 first:mt-0"
          v-for="(item, index) in userList" :key="'sidebar' + (item.username as string)"
          :id="'online-status-user-' + item.id"
          :class="[clickIndex == index ? 'bg-[#e5effa]' : 'bg-white hover:bg-[#f8f9fa]']" @click="handleClick(index)">
          <span class="relative inline-block">
            <el-avatar size="large" :style="clickIndex == index ? 'background: rgb(99 ,102 ,241)' : ''">
              <span class="text-3xl">{{ item.username ? item.username[0] : 'U' }}</span>
            </el-avatar>
            <span class="absolute bottom-0 right-0 block h-4 w-4 rounded-full ring-2 ring-white"
              :class="[item.onlineStatus == 1 ? 'bg-green-400' : 'bg-gray-400']" />
          </span>
          <div class="ml-3.5 grow">
            <div class="flex items-center">
              <div class="text-xs text-slate-400 line-clamp-1 break-all grow">[{{ comeForm }}] ID:{{ item.id }}</div>
              <el-badge :value="item.unreadCount" :hidden="!item.unreadCount || item.unreadCount <= 0">
                <div class="shrink-0 bg-slate-200 px-2 py-0.5 rounded shadow">
                  <el-popover show-arrow :width="340" trigger="hover" placement="top" :id="item + ''">
                    <template #reference>
                      <SvgIcon name="ellipsis-horizontal" class="w-3.5 h-3.5 text-gray-500" />
                    </template>
                    <template #default>
                      <RemarkForm @onSuccess="onSaveRemarkSuccess" :user-info="item" />
                    </template>
                  </el-popover>
                </div>
              </el-badge>

            </div>
            <div class="flex flex-col items-start justify-center break-all gap-x-1">
              <div class="line-clamp-2 text-sm">{{ item.memberRemark?.nickName }}</div>
              <div class="text-sm text-gray-500 font-light shrink-0 w-full">
                <div class="flex flex-row justify-between items-center">
                  <span v-if="item.userType !== 99" class="text-black font-medium">{{ item.username }}</span>
                  <span v-if="item.userType === 99" class="text-orange-400 font-medium">匿名用户</span>
                  <span>{{ formatDate(item.loginDate as number, 'DD/MM HH:mm:ss') }}</span>
                </div>
              </div>
            </div>
            <div class="flex items-center justify-between">
              <div class="text-base text-slate-400 grow line-clamp-1 break-all" v-if="item.lastMessageType === 2">[图片消息]
              </div>
              <div class="text-base text-slate-400 grow line-clamp-1 break-all" v-if="item.lastMessageType !== 2">
                {{ item.lastMessage }}</div>
            </div>
            <!-- tag -->
            <div class="flex flex-wrap items-center jus tify-start mt-1">
              <UserTag @removeTag="removeTag(tag)" :item="tag" v-for="(tag, index) in item.tagList"
                :class="[index > 0 ? 'ml-1' : '']">
                {{ tag.tagName }}
              </UserTag>
            </div>
          </div>
          <div class="absolute right-0 top-1 w-3 h-3 rounded-full bg-red-500" v-show="item.hasNewMessage"></div>
        </div>
      </el-scrollbar>
    </div>
    <div class="h-screen px-0.5 bg-white shadow-sm border-r flex flex-col items-center justify-center">
      <div class="h-12 w-3 flex items-center border rounded-tr-md rounded-br-md cursor-pointer" @click="show = !show">
        <SvgIcon name="caret-left" class="w-4 h-4 text-black transition-transform shrink-0 -ml-0.5"
          :class="[show ? 'rotate-0' : 'rotate-180']" />
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import SvgIcon from '@/components/SvgIcon.vue'
import RemarkForm from './RemarkForm.vue'
import { nextTick, onMounted, ref, watch } from 'vue'
import { listOnline, pageMemberUser } from '@/api/user'
import { formatDate } from '@/utils/formatTime'
import { useMessageStore, useUserInfoListStore, useUserInfoStore } from '@/stores/counter'
import UserTag from '@/components/UserTag.vue'
import { deleteTagRelations } from '@/api/tags'
import type { Message, TagRelation, UserInfo } from '@/types/global'
import { ElMessage, ElMessageBox } from 'element-plus'
import * as AuthUtils from '@/utils/auth'
import { useRouter } from 'vue-router'
import * as AudioUtils from '@/utils/audioUtils'
import { useAlterToneStore } from "@/stores/audioStore";
const alterToneStore = useAlterToneStore()
const comeForm = import.meta.env.VITE_COMPANY_NAME

const router = useRouter()

const value = ref(localStorage.getItem("messageListTab")=="ok"?true:false)

const userInfoStore = useUserInfoStore()
const messageRecord = useMessageStore()
const userInfoListStore = useUserInfoListStore()
const show = ref(true)
const scrollbarRef = ref()
// 用户列表
const userList = ref<UserInfo[]>([])
let originalUserList = [] as UserInfo[];  // 保存原始数组的副本
// 选中的中户
const userInfo = ref<UserInfo>({})
const clickIndex = ref(-1)
// 提示音
const alterTone = ref(alterToneStore.getAlterTone())
const superAlterTone = ref(alterToneStore.getSuperAlterTone())

const emits = defineEmits(['switchUser'])


// 点击用户选中状态
const handleClick = (index: number, resetUnread: boolean = true) => {
  clickIndex.value = index
  userInfo.value = userList.value[index]
  const currentUser = userInfoStore.getUserInfo()
  if (userInfo.value.id === currentUser.id) {
    console.log('点同一个用户干嘛')
    if (resetUnread) {
      userInfo.value.unreadCount = 0
    }
    AudioUtils.stopPlay()
    return
  }
  userInfoStore.setUserInfo(userInfo.value)
  emits('switchUser')
  AudioUtils.stopPlay()
  document.title = import.meta.env.VITE_APP_TITLE
}

const params = ref({
  pageNo: 1,
  pageSize: 50,
  username: '',
})

const disabledScroll = ref(false)
const loading = ref(false)
// 是否滚动到底部
const isBottom = () => {
  const { scrollTop, scrollHeight, clientHeight } = scrollbarRef.value.wrapRef
  return scrollTop + clientHeight >= scrollHeight
}

// 查询数据
const fetchData = async () => {
  loading.value = true
  try {
    const res = await pageMemberUser(params.value)
    const list = res.list
    // 会员放到store中保存
    list.forEach((userInfo: UserInfo) => {
      userInfoListStore.setUserInfoList(userInfo.id as number, userInfo)
    })
    // 对列表进行排序， 根据onlineStatus 和 loginDate排序
    userList.value = userList.value.concat(res.list)
    originalUserList = userList.value
    if (userList.value.length >= res.total) {
      disabledScroll.value = true
    }
    // 触发点击第一个用户
    // handleClick(0)
  } finally {
    loading.value = false
  }
}


//加载更多数据
const loadMoreData = async () => {
  if (!loading.value && !disabledScroll.value && isBottom()) {
    params.value.pageNo += 1 // increment page number
    console.log('加载分页消息记录，加之前的大小', messageRecord.getMessageRecord(userInfo.value.id).length)
    await fetchData()
    console.log('加载分页消息记录，加之后的大小', messageRecord.getMessageRecord(userInfo.value.id).length)
  }
}

const handleScroll = async (e: any) => {
  await loadMoreData()
}

watch(
  () => params.value.username,
  (newVal, oldVal) => {
    if (newVal !== oldVal) {
      params.value.pageNo = 1
      if (newVal == '') {
        userList.value = [...originalUserList];
      } else {
        userList.value = originalUserList.filter((user) => {
          return user.username?.includes(newVal) ||
            (user.tagList?.some(tag => tag.tagName?.includes(newVal)))
            || (user.lastMessage?.includes(newVal))
            || (user?.memberRemark?.nickName?.includes(newVal))
            || (user?.memberRemark?.remark?.includes(newVal));
        })
      }
    }
  }
)

// 把用户移动到列表的前面
const moveSenderToFront = (sender: UserInfo) => {
  const index = userList.value.findIndex(user => user.id === sender.id);
  if (localStorage.getItem("messageListTab")!=="ok"){
    if (index > -1) {
    userList.value.splice(index, 1);
    userList.value.unshift(sender);
   }
  }
 
}

// 闪烁
const flashNotificationForUser = (id: number) => {
  const element = document.getElementById('online-status-user-' + id);
  if (element) {
    element.classList.add('new-message');
    setTimeout(() => {
      element.classList.remove('new-message');
    }, 3000);
  }
}


const fetchNewSenderInfo = async (userId: number) => {
  const data = {
    pageNo: 1,
    pageSize: 1,
    id: userId,
  };
  try {
    const res = await pageMemberUser(data);
    return res.list[0];
  } catch (error) {
    console.log('获取用户信息失败', error);
    return null;
  }
}

const isLockList = ref(false)
const onNewMessage = async (body: Message) => {
  if (!body.customerId || !body.content) {
    console.log('消息是空的，直接返回')
    return
  }
  isLockList.value = true
  try {
    const senderId = body.customerId as number
    // 当前选中的聊天框
    const currentUserInfo = userInfoStore.getUserInfo()
    console.log('当前选中的用户为 {}', currentUserInfo)
    // 查询用户是不是在userList里, 如果不在，就查询用户信息 , 如果不存在
    let sender = userList.value.find((user) => user.id === senderId) as UserInfo;
    const isExists = !!sender;
    console.log('sidebar userInfo', sender)
    if (!isExists) {
      sender = { ...await fetchNewSenderInfo(body.customerId) }
      if (sender) {
        userList.value.unshift(sender)
      } else {
        ElMessage.error("获取新用户信息失败，请刷新页面");
      }
    } else {
      // 判断当前选中的用户是不是发消息的那个，如果是，就不需要移动位置
      if (sender.id !== currentUserInfo.id) {
        moveSenderToFront(sender)
      }
    }
    userInfoListStore.resetUserInfoList(userList.value)
    // 更新左侧列表显示的最后消息
    let currentUserInfoIndex = -1
    userList.value.forEach((item, index) => {
      if (item.id == body.customerId) {
        item.lastMessage = body.content
        item.lastMessageType = body.type
        // 发送者当前索引
        console.log('发送者当前索引', index)
        item.loginDate = body.createTime
        item.onlineStatus = 1
      }
      // 如果是客户发送的消息，才修改位置
      if (item.id && item.id === userInfo.value.id) {
        console.log('修改后的用户所在位置', index)
        if (currentUserInfoIndex !== index) {
          currentUserInfoIndex = index
          handleClick(index, false)
        }
      }
    })
    flashNotificationForUser(sender.id as number)
  } catch (err) {
    console.error('Error fetching message list:', err)
    ElMessage.error('处理新消息出现异常，请截图错误' + err)
  } finally {
    isLockList.value = false
  }
}

const addTagToUser = (tag: TagRelation) => {
  userList.value = userList.value.map(user => {
    if (tag.memberId == user.id) {
      if (!user.tagList) {
        user.tagList = []
      }
      user.tagList.push(tag)
      console.log('sidebar add tag', user)
    }
    return user
  })
}
const removeTag = async (tag: TagRelation) => {
  await deleteTagRelations(tag.id)
  userList.value = userList.value.map(user => {
    if (user.id === tag.memberId) {
      user.tagList = user.tagList?.filter(item => item.id !== tag.id)
      console.log('sidebar remove tag', tag, user)
    }
    return user
  })
}

const onSaveRemarkSuccess = (res: any) => {
  console.log('onSaveRemarkSuccess', res)
  userList.value.forEach((user) => {
    if (user.id == res.memberId) {
      user.memberRemark = { ...res }
    }
  })
  ElMessage({
    message: '保存成功',
    type: 'success',
  })
}


const logout = async () => {
  const res = await ElMessageBox.confirm('是否确认退出登录?', 'Warning', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  })
  if (res) {
    AuthUtils.removeToken()
    router.push('/login')
  }
}





// 消息切换
const onMessageListTab = () => {
  console.log(value.value)
  localStorage.setItem("messageListTab",value.value===true?"ok":"")
}

// 提示音
const onSwitchAlterTone = () => {
  alterToneStore.setAlterTone(alterTone.value)
  if (alterTone.value) {
    AudioUtils.initAudio()
  }
}

const onSwitchSuperAlterTone = () => {
  alterToneStore.setSuperAlterTone(superAlterTone.value)
  if (superAlterTone.value) {
    AudioUtils.initAudio()
  }
}

const unbindSession = (userId: number) => {
  let currentIndex = -1;
  userList.value = userList.value.filter((item, index) => {
    if (item.id === userId) {
      currentIndex = index;
      return false;
    }
    return true;
  })
  userInfoListStore.resetUserInfoList(userList.value)
  if (currentIndex > -1) {
    handleClick(currentIndex);
  }
}

const openAudio = (val: boolean) => {
  alterTone.value = val
  alterToneStore.setAlterTone(val)
  AudioUtils.initAudio()
}


defineExpose({
  onNewMessage,
  addTagToUser,
  unbindSession,
  openAudio
})

// 每隔15秒查询一次用户在线状态
const checkUserOnlineStatus = () => {
  setInterval(async () => {
    const userIds = userList.value.map(item => item.id);
    const res = await listOnline({ userIds }) as Record<number, number>
    userList.value = userList.value.map(item => {
      const newStatus = res[item.id as number]
      if (newStatus === 1 && item.onlineStatus === 0) {
        document.getElementById('online-status-user-' + item.username)?.classList.add('new-message')
      } else {
        document.getElementById('online-status-user-' + item.username)?.classList.remove('new-message')
      }
      item.onlineStatus = newStatus
      return item
    })
  }, 300000)
}
// 每隔10秒检查一次左侧列表的用户是不是和服务器的一样
const checkUserList = () => {
  setInterval(async () => {
    if (isLockList.value) {
      return
    }
    const response = await pageMemberUser(params.value)
    const serverUserList = response.list as UserInfo[]
    if (serverUserList && serverUserList.length > 0) {
      // 对比serverList和userList的用户ID是不是一样的
      // 创建一个 id 到用户的映射
      let isChangeList = false
      let isChangeContent = false
      const userMap = new Map(userList.value.map(user => [user.id, user]));
      console.log('userList 大小', userList.value.length, 'serverList大小', serverUserList.length)
      // 统计执行一次需要花费多久
      const start = new Date()
      const idList: number[] = []
      // 当前选中的用户是哪个
      const currentUser = userInfoStore.getUserInfo()
      serverUserList.forEach(serverUser => {
        if (!userMap.has(serverUser.id)) {
          console.log('用户 不存在，更新列表', serverUser)
          userList.value.unshift(serverUser);
          isChangeList = true
          idList.push(serverUser.id as number)
        } else {
          // 对比最后一条消息是不是一样的
          const user = userMap.get(serverUser.id) as UserInfo
          if (user.lastMessage !== serverUser.lastMessage) {
            console.log('用户存在，但是最后一条消息不一样，更新列表', user.username, '最后一条内容是', user.lastMessage, '服务器上的最后一条内容是', serverUser.lastMessage)
            user.lastMessage = serverUser.lastMessage
            user.unreadCount = serverUser.unreadCount
            isChangeContent = true
            isChangeList = true
            idList.push(serverUser.id as number)
          }
        }
      })
      if (isChangeContent) {
        console.log('内容改变，播放声音')
        AudioUtils.playAudio()
      }
      if (isChangeList) {
        // userList按loginDate 倒叙排序
        userList.value.sort((a, b) => {
          return new Date(b.loginDate as number).getTime() - new Date(a.loginDate as number).getTime()
        })
        userList.value.forEach((user, index) => {
          if (user.id === currentUser.id) {
            handleClick(index)
            return
          }
        })
        userInfoListStore.resetUserInfoList(userList.value)
        idList.forEach(id => {
          flashNotificationForUser(id)
        })
      }
      const end = new Date()
      console.log('对比用户列表花费时间', end.getTime() - start.getTime())
    }
  }, 30000)
}


onMounted(async () => {
  await fetchData()
  // checkUserList()
  checkUserOnlineStatus()
})

// 查询用户列表
</script>

<style lang="css" scoped>
@keyframes flash {

  0%,
  100% {
    background-color: #ffffff;
  }

  25%,
  75% {
    background-color: #00ccff;
  }
}

.new-message {
  animation: flash 1s linear 3;
}
</style>