<template>
  <div class="notification-bell">
    <el-badge :is-dot="unreadCount > 0" class="item">
      <el-icon :size="24" class="toolBar-icon bell-icon" @click="openDialog">
        <Bell />
      </el-icon>
    </el-badge>
    <el-dialog v-model="dialogVisible" width="880px" class="notification-dialog" destroy-on-close :show-close="true" align-center>
      <NotificationDrawerContent v-if="dialogVisible" ref="drawerContentRef" @close="handleDrawerClose" />
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from "vue";
import { useDebounceFn } from "@vueuse/core";
import { Bell } from "@element-plus/icons-vue";
import { getMessageNoRead } from "@/api/modules/headerNotice";
import { localGet } from "@/utils";
import { useWebSocketStore } from "@/stores/modules/websocket";
import NotificationDrawerContent from "./NotificationDrawerContent.vue";

const dialogVisible = ref(false);
const unreadCount = ref(0);
const drawerContentRef = ref<InstanceType<typeof NotificationDrawerContent> | null>(null);
const socketStore = useWebSocketStore();
let cleanMessageFn: (() => void) | null = null;

const WS_BASE = (import.meta.env.VITE_WS_BASE || "ws://120.26.186.130:8000/alienStore/socket/").replace(/\/$/, "");

/** 与商家端 tabbar getMessage 一致：获取未读数量 */
async function getMessage() {
  const phone = localGet("iphone") || localGet("geeker-user")?.userInfo?.phone;
  if (!phone) {
    unreadCount.value = 0;
    return;
  }
  try {
    const res: any = await getMessageNoRead({
      receiverId: `store_${phone}`
    });
    const data = res?.data ?? res;
    unreadCount.value = Number(data) || 0;
  } catch (error) {
    console.error("获取消息数量失败", error);
    unreadCount.value = 0;
  }
}

/** 收到 WebSocket 消息时刷新（与商家端 handleWebSocketMessage 一致，debounce 300ms） */
const handleWebSocketMessage = useDebounceFn(() => {
  getMessage();
  if (dialogVisible.value && drawerContentRef.value?.refresh) {
    drawerContentRef.value.refresh();
  }
}, 300);

async function connectWebSocket() {
  const phone = localGet("iphone") || localGet("geeker-user")?.userInfo?.phone;
  if (!phone) return;

  const wsUrl =
    WS_BASE.startsWith("wss") || WS_BASE.startsWith("ws")
      ? `${WS_BASE}/store_${phone}`
      : WS_BASE.replace("https", "wss").replace("http", "ws") + `/store_${phone}`;

  if (!socketStore.isConnected || socketStore.lastConnectedUrl !== wsUrl) {
    await socketStore.connect(wsUrl);
  }

  if (cleanMessageFn) {
    cleanMessageFn();
    cleanMessageFn = null;
  }

  cleanMessageFn = socketStore.subscribe("message", () => {
    handleWebSocketMessage();
  });
}

function openDialog() {
  dialogVisible.value = true;
  getMessage();
}

function handleDrawerClose() {
  dialogVisible.value = false;
  getMessage();
}

onMounted(() => {
  getMessage();
  connectWebSocket();
});

onBeforeUnmount(() => {
  if (cleanMessageFn) {
    cleanMessageFn();
    cleanMessageFn = null;
  }
});
</script>

<style scoped lang="scss">
.notification-bell {
  display: flex;
  align-items: center;
  .item {
    :deep(.el-badge__content) {
      background-color: #ff2442;
      border: none;
    }
  }
  .bell-icon {
    color: var(--el-header-text-color);
    cursor: pointer;
  }
}
</style>

<style lang="scss">
.notification-dialog {
  .el-dialog__header {
    padding: 16px 20px 12px;
    margin-right: 16px;
  }
  .el-dialog__body {
    display: flex;
    flex-direction: column;
    min-height: 520px;
    max-height: 75vh;
    padding: 0 20px 20px;
    overflow: hidden;
  }
}
</style>
