<script setup lang="ts">
import { post } from '@af-mobile-client-vue3/services/restTools'
import useUserStore from '@af-mobile-client-vue3/stores/modules/user'
import { mobileUtil } from '@af-mobile-client-vue3/utils/mobileUtil'
import { Badge as VanBadge, Icon as VanIcon } from 'vant'
import { onMounted, onUnmounted, ref } from 'vue'
import { closeWebSocket, initWebSocket } from './webSocket'
import 'vant/es/badge/style'
import 'vant/es/icon/style'

interface Props {
  iconColor?: string
}

const props = withDefaults(defineProps<Props>(), {
  iconColor: '#666',
})

const userInfo = useUserStore().getUserInfo()

// 未读消息数量
const unreadCount = ref(0)

// 打开消息下拉菜单
const isShowMessageDropdown = ref(false)

// 消息列表数据
const messages = ref<any[]>([])

// 组件根元素的引用
const messageNotificationRef = ref<HTMLElement | null>(null)

// 获取消息数据
async function fetchMessages() {
  const param = {
    userId: `${userInfo.id}:phone`, // |phone
    typeList: '\'phone\'', // phone
    pageNo: 1,
    pageSize: 10,
  }
  const res = await post('/af-system/logic/getNotificationListByType', param)
  messages.value = (res || []).map((item: any) => {
    const event: any = JSON.parse(item.f_event || '{}')
    return {
      id: item.id,
      type: event.type,
      time: item.f_input_date,
      title: event.title || '',
      status: item.f_state,
      content: event.description || '',
    }
  })
}

// 获取未读消息数量
async function fetchMessagesCount() {
  const param = {
    userId: `${userInfo.id}:phone`, // |phone
    typeList: '\'phone\'', // phone
  }
  const count = await post('/af-system/logic/getNotificationCount', param)
  unreadCount.value = count.count
}

// 处理 WebSocket 消息
function createMessageCallback(message: any) {
  fetchMessagesCount()
  fetchMessages()
}
// 处理 不同的业务
function sendMessageCallback(message: any) {
  console.log('>>>> 处理业务', JSON.stringify(message))
  if (message.businessType === 'audio') {
    // 播放响铃, 响铃文件为 message.audioName
    mobileUtil.execute({
      funcName: 'playAudio',
      param: {
        fileName: message.audioName,
      },
      callbackFunc: (result: any) => {
        // {"status":"success","data":{"message":"音频播放成功","fileName":"anjian.mp3","path":"assets/audio/anjian.mp3"}}
      },
    })
  }
}

// 全部标记为已读（清空消息列表）
function markAllAsRead() {
  post('/af-system/logic/finishMessageAllByType', {
    type: ['phone'],
    userId: `${userInfo.id}:phone`,
  }).then(() => {
    fetchMessages()
    fetchMessagesCount()
  })
}

// 单条消息标记为已读
function markAsRead(id: string | number) {
  post('/af-system/logic/confirmMessage', {
    id,
    f_state: 2,
  }).then(() => {
    fetchMessages()
    fetchMessagesCount()
  })
}

function handleIconClick(message: any) {
  // 乐观更新为已读状态，使图标立刻变绿
  message.status = 2
  setTimeout(() => {
    markAsRead(message.id)
  }, 200)
}

function showMessageDropdown() {
  isShowMessageDropdown.value = !isShowMessageDropdown.value
  if (isShowMessageDropdown.value) {
    fetchMessages()
  }
}

// 处理全局点击事件
function handleDocumentClick(event: MouseEvent) {
  if (messageNotificationRef.value && !messageNotificationRef.value.contains(event.target as Node)) {
    isShowMessageDropdown.value = false
  }
}

onMounted(() => {
  fetchMessagesCount()
  // 初始化 WebSocket 连接
  initWebSocket(userInfo.id, sendMessageCallback, createMessageCallback)
  // 添加全局点击事件监听器
  document.addEventListener('click', handleDocumentClick)
})

onUnmounted(() => {
  closeWebSocket()
  // 移除全局点击事件监听器
  document.removeEventListener('click', handleDocumentClick)
})
</script>

<template>
  <div ref="messageNotificationRef" class="message_icon" @click="showMessageDropdown">
    <VanBadge v-if="unreadCount > 0" :content="unreadCount" max="99">
      <VanIcon name="bell" :color="props.iconColor" />
    </VanBadge>
    <VanIcon v-else name="bell" :color="props.iconColor" />
  </div>

  <div v-if="isShowMessageDropdown" class="message_overlay" @click="isShowMessageDropdown = false" />

  <div v-show="isShowMessageDropdown" class="message_dropdown" @click.stop>
    <div class="message_header">
      <span class="label">消息通知</span>
      <span class="action" @click="markAllAsRead">全部已读</span>
    </div>
    <div class="message_list">
      <template v-if="messages.length > 0">
        <div
          v-for="message in messages"
          :key="message.id"
          class="message_item"
          :class="{ info: message.type === 'info', warning: message.type === 'warning' }"
        >
          <!-- 第一行：div1 + div2 -->
          <div class="message_row">
            <!-- div1：标题+时间 -->
            <div class="message_left">
              <p class="message_title">
                {{ message.title }}
              </p>
              <p class="message_time">
                {{ message.time }}
              </p>
            </div>
            <!-- div2：图标 -->
            <div class="message_right">
              <VanIcon
                name="checked"
                :color="message.status === 2 ? '#52c41a' : '#999'"
                size="28"
                @click.stop="handleIconClick(message)"
              />
            </div>
          </div>
          <!-- 第二行：div3 内容 -->
          <div class="message_content">
            <p class="message_text">
              {{ message.content }}
            </p>
          </div>
        </div>
      </template>
      <div v-else class="empty_message">
        暂无未读消息
      </div>
    </div>
  </div>
</template>

<style scoped lang="less">
.message_dropdown {
  position: absolute;
  top: 56px;
  left: 0;
  right: 0;
  background-color: #fff;
  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.2);
  z-index: 10001;
  max-height: 400px;
  overflow-y: auto;

  .message_header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 16px;
    border-bottom: 1px solid #eee;

    .label {
      font-size: 14px;
      color: #999;
    }
    .action {
      font-size: 14px;
      color: #1989fa;
      cursor: pointer;
    }
  }

  .message_list {
    .message_item {
      padding: 12px 16px;
      border-bottom: 1px solid #f5f5f5;

      &.info {
        background-color: #eff6ff;
      }
      &.warning {
        background-color: #fff7ed;
      }

      .message_row {
        display: flex;
        justify-content: space-between;
        align-items: flex-start;
      }

      .message_left {
        flex: 1;
        min-width: 0;

        .message_title {
          font-size: 14px;
          font-weight: 500;
          color: #333;
          margin: 0;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
        }

        .message_time {
          font-size: 12px;
          color: #999;
          margin: 4px 0 0 0;
        }
      }

      .message_right {
        flex: 0 0 auto;
        display: flex;
        align-items: center;
        padding-left: 8px;

        .van-icon {
          font-size: 18px;
          color: #999;
        }
      }

      .message_content {
        margin-top: 8px;

        .message_text {
          border-radius: 4px;
          font-size: 13px;
          color: #666;
          background-color: #fafafc;
          margin: 0;
          padding: 8px 12px;
          line-height: 1.4;
        }
      }
    }

    .empty_message {
      padding: 60px 0;
      text-align: center;
      color: #999;
      font-size: 14px;
    }
  }
}

.message_overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  z-index: 10001;
  margin-top: 56px;
  margin-bottom: 50px;
}
.message_icon {
  padding: 8px;
  position: relative;
  cursor: pointer;

  .van-icon {
    font-size: 20px;
  }
}
</style>
