<template>
  <div class="default-width message" :style="`height: calc(100vh - ${isEnterprise ? '130px' : '50px'});`">
    <div class="message-left">
      <div class="message-left-search d-flex align-center px-3 justify-space-between" >
        <div>
          <v-icon class="mr-3">mdi-history</v-icon>
          最近联系人
        </div>
        <div>
          <v-btn
            density="compact"
            :color="showDelete ? '' : 'red'"
            :icon="showDelete ? 'mdi-close' : 'mdi-trash-can-outline'"
            variant="text"
            @click="showDelete = !showDelete"
          >
          </v-btn>
        </div>
        <!-- {{ connected ? '连接成功': '连接失败' }} -->
      </div>
      <div class="message-chat-box mt-5">
        <v-overlay
          :model-value="!IM.connected"
          contained
          class="align-center justify-center"
        >
          <v-progress-circular
            color="primary"
            size="64"
            indeterminate
          ></v-progress-circular>
        </v-overlay>
        <div v-if="conversationList.length">
          <v-list density="compact" mandatory @update:selected="handleChange">
            <v-list-item
              v-for="(val, i) in conversationList"
              :key="i"
              :value="val"
              color="primary"
              class="mb-2"
              :active="val.channel.channelID === info?.channel?.channelID"
              :title="val.userInfoVo ? (val.userInfoVo.userInfoResp.name ? val.userInfoVo.userInfoResp.name : '游客') : '系统消息'"
              :subtitle="timesTampChange(+val.timestamp.padEnd(13, '0'))"
            >
              <template v-slot:subtitle="{ subtitle }">
                <div class="mt-2">{{ subtitle }}</div>
              </template>
              <template v-slot:prepend>
                <v-avatar :image="getUserAvatar(val?.userInfoVo?.userInfoResp?.avatar, val?.userInfoVo?.userInfoResp?.sex)"></v-avatar>
              </template>
              <template v-slot:append>
                <v-badge
                  v-if="val.unread > 0"
                  color="error"
                  :content="val.unread"
                  inline
                ></v-badge>
                <v-btn v-show="showDelete" density="compact" icon="mdi-trash-can-outline" variant="text" color="red" @click.stop="handleDelete(val)"></v-btn>
              </template>
            </v-list-item>
          </v-list>
          <div class="message-no-more-text mt-3">没有更多了</div>
        </div>
        <div v-else class="left-noData">
          <Empty :elevation="false" message="暂无30天内联系人" width="300" height="150"></Empty>
        </div>
      </div>
    </div>

    <div class="message-right">
      <div v-if="showRightNoData" class="right-noData">
        <Empty :elevation="false" message="与您进行过沟通的 Boss 都会在左侧列表中显示"></Empty>
      </div>
      <Chatting
        ref="chatRef"
        :items="messageItems"
        :info="info"
        :interview="interview"
        :has-more="hasMore"
        @handleSend="handleUpdate"
        @handleMore="handleGetMore"
        @handleAgree="handleAgree"
        @handleRefuse="handleRefuse"
        @handlePreview="handlePreview"
        @handleSendResume="handleSendResume"
      >
        <template #tools>
          <v-btn
            v-for="tool in tools"
            :key="tool.name"
            size="small"
            class="mr-3"
            :color="tool.color"
            @click="tool.handle(tool)"
          >
            <v-progress-circular
              v-if="tool.loading"
              :width="2"
              :size="16"
              color="white"
              class="mr-2"
              indeterminate
            ></v-progress-circular>
            <v-icon v-else class="mr-2">{{ tool.icon }}</v-icon>
            {{ tool.name }}
          </v-btn>
        </template>
      </Chatting>
    </div>
  </div>

  <File ref="uploadFile" @success="handleUploadResume"></File>

  <CtDialog :visible="showInvite" :widthType="2" titleClass="text-h6" title="邀请面试" @close="showInvite = false" @submit="handleSubmit">
    <InvitePage v-if="showInvite" ref="inviteRef" :item-data="itemData" :position="positionList"></InvitePage>
  </CtDialog>

  <CtDialog :visible="showResume" :widthType="2" titleClass="text-h6" title="发送简历" @close="showResume = false; selectResume = null " @submit="handleSubmitResume">
    
    <div style="position: relative; min-height: 200px">
      <v-radio-group v-model="selectResume">
        <v-radio v-for="val in resumeList" :key="val.id" :value="val.id" :label="val.title" color="primary"></v-radio>
      </v-radio-group>
    </div>
    
  </CtDialog>
</template>

<script setup>
defineOptions({ name: 'personal-message-index'})
import InvitePage from '@/views/recruit/enterprise/interview/components/invite'
import { timesTampChange } from '@/utils/date'
import { ref, inject, watch,onMounted, nextTick } from 'vue'
import Chatting from './components/chatting.vue'
import { initConnect, send, initChart, getMoreMessages, checkConversation } from '@/hooks/web/useIM'
import { useRoute } from 'vue-router'
import { getPositionDetails } from '@/api/position'
import { getInterviewInviteListByInviteUserId } from '@/api/common'
import { getUserInfo } from '@/api/personal/user'
import { useIMStore } from '@/store/im'
import { useUserStore } from '@/store/user'
import Snackbar from '@/plugins/snackbar'
import { getUserAvatar } from '@/utils/avatar'

import { getJobAdvertised } from '@/api/enterprise'
import { dealDictArrayData } from '@/utils/position'
import { saveInterviewInvite } from '@/api/recruit/enterprise/interview'
import { savePersonResumeCv } from '@/api/recruit/personal/resume'
import { useI18n } from '@/hooks/web/useI18n'
import { userInterviewInviteReject, userInterviewInviteConsent } from '@/api/recruit/personal/personalCenter'
import { getPersonResumeCv } from '@/api/recruit/personal/resume'
import { previewFile } from '@/utils'
import Confirm from '@/plugins/confirm'

const { t } = useI18n()
const chatRef = ref()

const IM = useIMStore()
// 自己的信息
const { baseInfo } = useUserStore()

const isEnterprise = inject('isEnterprise')
// 实例
const route = useRoute()

const channelItem = ref(null)
const messageItems = ref([])
const pageSize = ref(1)
const hasMore = ref(false)

const showInvite = ref(false)

const positionList = ref([])

const showDelete = ref(false)
const itemData = ref({})

const inviteRef = ref()

// 发送简历
const uploadFile = ref()
const showResume = ref(false)
const resumeList = ref([])
const selectResume = ref(null)

// 求职者面试列表
const interview = ref([])

const showRightNoData = ref(false)

const info = ref({})

const enterpriseTools = ref([
  { name: '求简历', icon: 'mdi-email', color:"primary", loading: false, handle: handleRequest },
  { name: '面试邀约', icon: 'mdi-email', color:"primary", loading: false, handle: handleInvite }
])

const userTools = ref([
  { name: '发送简历', icon: 'mdi-email', color:"primary", loading: false, handle: handleSendResume }
])

const tools = isEnterprise ? enterpriseTools.value : userTools.value

if (!IM) {
  console.log('IM is disconnected')
}

if (route.query.id) {
  const api = route.query.enterprise ? getPositionDetails : getUserInfo
  const res = await api({ id: route.query.id })
  const query = route.query.enterprise ? [res.contact?.userId, res.contact?.enterpriseId] : [res?.id]
  onMounted(() => {
    nextTick(async () => {
      const { channel } = await checkConversation(...query)
      const items = [
        {
          channel,
          userInfoVo: {
            userInfoResp: route.query.enterprise ? res.contact : { ...res, userId: res.id}
          }
        }
      ]
      handleChange(items)
    })
  })
}

const {
  conversationList,
  updateConversation,
  updateUnreadCount,
  deleteConversations,
  resetUnread
} = initConnect(async (successful) => {
  if (!successful) {
    Snackbar.error('发送失败')
    return
  }
  chatRef.value.reset()
  // 发送成功
  const { list } = await getMoreMessages(1, channelItem.value)
  // updateConversation()
  messageItems.value = list.value
  chatRef.value.scrollBottom()
})


const getInterviewInviteList = async () => {
  if (!info.value.userId) return
  const data = await getInterviewInviteListByInviteUserId(info.value.userId)
  interview.value = data.slice(0, 1)
}

watch(
  () => conversationList.value,
  async () => {
    // console.log('发生变化', val)
    // 数据发生变化
    if (channelItem.value && IM.fromChannel === channelItem.value.channelID) {
      // 更新
      const { list } = await getMoreMessages(1, channelItem.value)
      messageItems.value = list.value
      if (!isEnterprise) getInterviewInviteList()
      chatRef.value.scrollBottom()
    }
  },
  {
    deep: true,
    immediate: true
  }
)


async function handleChange (items) {
  // console.log([...items])
  try {
    chatRef.value.changeOverlay(true)
    const { userInfoVo, channel: myChannel } = items.pop()
    info.value = userInfoVo?.userInfoResp ?? { name: '系统消息' }
    Object.assign(info.value, {
      channel: myChannel
    })
    const userId = userInfoVo.userInfoResp.userId
    const enterpriseId = userInfoVo.userInfoResp.enterpriseId || undefined
    const { channel, list, more } = await initChart(userId, enterpriseId)
    // console.log('--------',list)
    channelItem.value = channel.value
    messageItems.value = list.value
    hasMore.value = more
    chatRef.value.scrollBottom()
    // 点开窗口消除未读数量
    await resetUnread(channel.value, baseInfo?.enterpriseId)
    await updateConversation()
    updateUnreadCount()
    if (!isEnterprise) getInterviewInviteList()
  } catch (error) {
    messageItems.value = []
  } finally {
    chatRef.value.changeOverlay(false)
  }
}

// 普通消息
const handleUpdate = (val) => {
  send(val.value, channelItem.value)
}

// 获取简历
async function handleSendResume (item) {
  try {
    item.loading = true
    // showResume.value = true
    // 获取简历列表
    const result = await getPersonResumeCv()
    if (result.length === 0) {
      Snackbar.error(t('resume.resumeYetSubmit'))
      uploadFile.value.trigger()
      return
    }
    resumeList.value = result
    showResume.value = true
  } finally {
    item.loading = false
  }
}

/**
 * 发送简历
 * text param
 * {
 *  remark: 备注
 *  query: {} 自定义参数 access -1 未确定 0 拒绝 1 同意
 *  type: 1 => 发送简历
 *        2 => 索要简历
 *        3 => 信息描述
 * }
 */

// 没有上传过简历的弹窗上传并发送给对方
const handleUploadResume = async (url, title) => {
  if (!url || !title) return
  await savePersonResumeCv({ title, url })
  const text = {
    remark: '发送简历',
    query: {
      src: url,
      title
    },
    type: 1
  }
  send (JSON.stringify(text), channelItem.value, 105)
}

function handleSubmitResume () {
  if (!selectResume.value) {
    Snackbar.error(t('resume.selectResumeToSubmit'))
    return
  }
  const _info = resumeList.value.find((item) => item.id === selectResume.value)
  const text = {
    remark: '发送简历',
    query: {
      src: _info.url,
      title: _info.title,
      id: _info.id,
    },
    type: 1
  }
  send (JSON.stringify(text), channelItem.value, 105)
  showResume.value = false
}
// 求简历
function handleRequest () {
  const text = {
    remark: '求简历',
    query: {
      src: '',
      title: '',
      id: '',
    },
    type: 2
  }
  send (JSON.stringify(text), channelItem.value, 105)
}

// 简历预览
const handlePreview = (val) => {
  previewFile(val.content.query.src)
}

const handleGetMore = async () => {
  try {
    chatRef.value.changeLoading(true)
    pageSize.value++
    const { list, more } = await getMoreMessages(pageSize.value, channelItem.value)
    messageItems.value.unshift(...list.value)
    hasMore.value = more
    // chatRef.value.scrollBottom()
  } finally {
    chatRef.value.changeLoading(false)
  }
}

const handleDelete = async ({ channel }) => {
  await deleteConversations(channel, baseInfo?.enterpriseId)
  await updateConversation()
  updateUnreadCount()
}

// 没有企业ID则enterpriseId为undefined
// 发送消息体 { text, type: 2 }
// 面试邀约
async function handleInvite (item) {
  item.loading = true
  positionList.value = []
  try {
    const data = await getJobAdvertised({ hire: false })
    if (!data.length) return
    const list = dealDictArrayData([], data)
    positionList.value = list.map(e => {
      return {
        label: `${e.name}${e.areaName ? '_' + e.areaName : ''} ${e.payFrom}-${e.payTo}/${e.payName}`,
        value: e.id,
        data: e
      }
    })
    // itemData.value = {
    //   userId: '',
    //   jobId: ''
    // }
    showInvite.value = true
    // send(JSON.stringify(msg), channelItem.value, 101)
    // console.log(query)
  } catch (error) {
    console.log(error)
  } finally {
    item.loading = false
  }
}

const handleSubmit = async () => {
  const { valid } = await inviteRef.value.CtFormRef.formRef.validate()
  if (!valid) {
    return
  }
  const query = inviteRef.value.getQuery()
  if (!query.time) {
    Snackbar.error('时间不能为空')
    return
  }
  query.userId = info.value.userId
  query.positionInfo = positionList.value.find(e => e.value === query.jobId)
  // 需要id
  const data = await saveInterviewInvite(query)
  // 保留邀请id
  query.id = data.id
  Snackbar.success(t('common.operationSuccessful'))
  send(JSON.stringify(query), channelItem.value, 101)
  showInvite.value = false

}

const handleAgree = (val) => {
  if (!val.id) return
  const query = {
    id: val.id
  }
  const baseInfo = localStorage.getItem('baseInfo')
  if (baseInfo) {
    const { phone } = JSON.parse(baseInfo)
    query.phone = phone
  }

  Confirm(t('common.confirmTitle'), '是否确定接收此面试邀请？').then(async () => {
    await userInterviewInviteConsent(query)
    Snackbar.success(t('common.operationSuccessful'))
    getInterviewInviteList()
    send(JSON.stringify({ id: val.id }), channelItem.value, 104)
  })
}

// 拒绝面试邀请
const handleRefuse = (val) => {
  if (!val.id) return
  Confirm(t('common.confirmTitle'), '您是否确定要拒绝此面试邀请？').then(async () => {
    await userInterviewInviteReject(val.id)
    Snackbar.success(t('common.operationSuccessful'))
    getInterviewInviteList()
    send(JSON.stringify({ id: val.id }), channelItem.value, 103)
  })
}

</script>

<style scoped lang="scss">
.message {
  display: flex;
  &-left {
    position: relative;
    flex-shrink: 0;
    height: 100%;;
    width: 360px;
    background-color: #fff;
    border-radius: 8px;
    margin-right: 12px;
    .message-left-search {
      width: 100%;
      height: 60px;
      background: linear-gradient(90deg, #f5fcfc, #fcfbfa);
      border-radius: 8px 8px 0 0;
    }
    .message-chat-box {
      .chat-item {
        position: relative;
        width: 100%;
        height: 78px;
        padding: 14px 12px;
        cursor: pointer;
        &:hover {
          background-color: #f8f8f8;
        }
        .chat-item-time {
          position: absolute;
          right: 12px;
          top: 50%;
          transform: translateY(-50%);
        }
        .title-box {
          max-width: 114px;
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
          display: inline-block;
        }
      }
    }
    .message-no-more-text {
      color: var(--color-999);
      font-size: 14px;
      text-align: center
    }
    .left-noData {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }
  }
  &-right {
    height: 100%;
    flex: 1;
    width: 0;
    position: relative;
    background-color: #fff;
    border-radius: 8px;
    .right-noData {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }
  }
}
</style>
