<script lang="ts" setup>
import type { ChatMessage } from '#/api/core/chat';
import type {
  AnnouncementItem,
  NotificationItem,
} from '#/composables/useNotification';
import type { WatchStopHandle } from 'vue';

import {
  computed,
  defineAsyncComponent,
  onUnmounted,
  ref,
  watch,
} from 'vue';
import { useRouter } from 'vue-router';

import { useWatermark } from '@vben/hooks';
import { BasicLayout } from '@vben/layouts';
import { $t } from '@vben/locales';
import { preferences } from '@vben/preferences';
import { useAccessStore, useUserStore } from '@vben/stores';

import { getFileUrl } from '#/composables/useFileUrl';
import { useAuthStore } from '#/store';

const LoginForm = defineAsyncComponent(
  () => import('#/views/_core/authentication/login.vue'),
);
const AuthenticationLoginExpiredModal = defineAsyncComponent(() =>
  import('@vben/common-ui/es/login-expired-modal'),
);
const UserDropdown = defineAsyncComponent(() =>
  import('@vben/layouts/es/user-dropdown').then((module) => module.UserDropdown),
);
const NotificationPopup = defineAsyncComponent(
  () => import('#/components/notification/NotificationPopup.vue'),
);

const notifications = ref<NotificationItem[]>([]);
const messageUnreadCount = ref(0);
const announcements = ref<AnnouncementItem[]>([]);
const announcementUnreadCount = ref(0);
const activeTab = ref<'announcement' | 'chat' | 'message'>('message');
const showDot = computed(
  () => messageUnreadCount.value + announcementUnreadCount.value > 0,
);
const unreadChatMessages = ref<ChatMessage[]>([]);
const chatTotalUnread = ref(0);

const userStore = useUserStore();
const authStore = useAuthStore();
const accessStore = useAccessStore();
const { destroyWatermark, updateWatermark } = useWatermark();

// 初始化消息通知
const router = useRouter();
let notificationApi: any = null;
let chatApi: any = null;
let layoutActive = true;
let realtimeInitializing: Promise<void> | null = null;
let realtimeInitialized = false;
let stopRealtimeWatches: WatchStopHandle[] = [];

onUnmounted(() => {
  layoutActive = false;
  stopRealtimeWatches.forEach((stop) => stop());
  stopRealtimeWatches = [];
  notificationApi?.cleanup();
  chatApi?.disconnectChat();
});

async function initRealtimeFeatures() {
  if (realtimeInitialized) return;
  if (realtimeInitializing) return realtimeInitializing;

  realtimeInitializing = doInitRealtimeFeatures().finally(() => {
    realtimeInitializing = null;
  });
  await realtimeInitializing;
}

async function doInitRealtimeFeatures() {
  const [notificationModule, chatModule] = await Promise.all([
    import('#/composables/useNotification'),
    import('#/views/_core/chat/composables/useChat'),
  ]);

  if (!layoutActive) return;

  notificationApi = notificationModule.useNotification();
  chatApi = chatModule.useChat();

  stopRealtimeWatches = [
    watch(
      notificationApi.notifications,
      (value) => {
        notifications.value = value;
      },
      { immediate: true },
    ),
    watch(
      notificationApi.messageUnreadCount,
      (value) => {
        messageUnreadCount.value = value;
      },
      { immediate: true },
    ),
    watch(
      notificationApi.announcements,
      (value) => {
        announcements.value = value;
      },
      { immediate: true },
    ),
    watch(
      notificationApi.announcementUnreadCount,
      (value) => {
        announcementUnreadCount.value = value;
      },
      { immediate: true },
    ),
    watch(
      notificationApi.activeTab,
      (value) => {
        activeTab.value = value;
      },
      { immediate: true },
    ),
    watch(
      chatApi.unreadChatMessages,
      (value) => {
        unreadChatMessages.value = value;
      },
      { immediate: true },
    ),
    watch(
      chatApi.totalUnread,
      (value) => {
        chatTotalUnread.value = value;
      },
      { immediate: true },
    ),
  ];

  notificationApi.init();
  chatApi.connectChat();
  chatApi.loadConversations();
  chatApi.loadUnreadChatMessages();
  realtimeInitialized = true;
}

const menus = computed(() => [
  // {
  //   handler: () => {
  //     openWindow(VBEN_DOC_URL, {
  //       target: '_blank',
  //     });
  //   },
  //   icon: BookOpenText,
  //   text: $t('ui.widgets.document'),
  // },
  // {
  //   handler: () => {
  //     openWindow(VBEN_GITHUB_URL, {
  //       target: '_blank',
  //     });
  //   },
  //   icon: SvgGithubIcon,
  //   text: 'GitHub',
  // },
  // {
  //   handler: () => {
  //     openWindow(`${VBEN_GITHUB_URL}/issues`, {
  //       target: '_blank',
  //     });
  //   },
  //   icon: CircleHelp,
  //   text: $t('ui.widgets.qa'),
  // },
]);

/** 双列仅第一列窄条展示时的短文案 */
const PRODUCT_BRAND_SHORT = 'AI Agent';

// 头像URL（响应式）
const avatar = ref('');

// 异步加载头像URL
async function loadAvatarUrl() {
  const avatarPath = userStore.userInfo?.avatar;
  avatar.value = avatarPath ? await getFileUrl(avatarPath) : '';
}

// 监听用户信息变化，加载头像URL
watch(
  () => userStore.userInfo?.avatar,
  () => {
    loadAvatarUrl();
  },
  { immediate: true },
);

async function handleLogout() {
  await authStore.logout(false);
}

function handleNoticeClear() {
  notificationApi?.clearReadMessages();
}

function handleMakeAll() {
  notificationApi?.markAllAsRead();
}

function handleNoticeRead(item: any) {
  notificationApi?.markAsRead(item);
}

function handleAnnouncementRead(item: any) {
  notificationApi?.markAnnouncementAsRead(item);
}

function handleViewAll() {
  notificationApi?.viewAllMessages();
}

function handleTabChange(tab: 'announcement' | 'chat' | 'message') {
  activeTab.value = tab;
  if (notificationApi) {
    notificationApi.activeTab.value = tab;
  }
}

function handleNotificationOpen() {
  void initRealtimeFeatures();
}

function handleChatClick(msg: ChatMessage) {
  // 新开tab跳转到聊天页面，带上会话ID
  const url = router.resolve(
    `/chat?conversationId=${msg.conversation_id}`,
  ).href;
  window.open(url, '_blank');

  // 从未读聊天列表中移除
  const index = unreadChatMessages.value.findIndex((m) => m.id === msg.id);
  if (index !== -1) {
    unreadChatMessages.value.splice(index, 1);
  }
}
watch(
  () => ({
    enable: preferences.app.watermark,
    content: preferences.app.watermarkContent,
  }),
  async ({ enable, content }) => {
    if (enable) {
      await updateWatermark({
        content:
          content ||
          `${userStore.userInfo?.username} - ${userStore.userInfo?.realName}`,
      });
    } else {
      destroyWatermark();
    }
  },
  {
    immediate: true,
  },
);
</script>

<template>
  <BasicLayout>
    <template #user-dropdown>
      <UserDropdown
        :avatar
        :menus
        :text="userStore.userInfo?.realName"
        :description="
          userStore.userInfo?.email || userStore.userInfo?.username || ''
        "
        tag-text="Pro"
        @logout="handleLogout"
      />
    </template>
    <template #notification>
      <NotificationPopup
        :dot="showDot || chatTotalUnread > 0"
        :notifications="notifications"
        :message-unread-count="messageUnreadCount"
        :announcements="announcements"
        :announcement-unread-count="announcementUnreadCount"
        :unread-chats="unreadChatMessages"
        :chat-unread-count="chatTotalUnread"
        :active-tab="activeTab"
        @clear="handleNoticeClear"
        @click-chat="handleChatClick"
        @make-all="handleMakeAll"
        @open="handleNotificationOpen"
        @read-message="handleNoticeRead"
        @read-announcement="handleAnnouncementRead"
        @view-all="handleViewAll"
        @update:active-tab="handleTabChange"
      />
    </template>
    <template #sidebar-footer="sidebarFooterProps">
      <button
        type="button"
        class="text-muted-foreground hover:text-foreground max-w-full px-1 py-0.5 text-center text-[11px] leading-tight transition-colors"
        :title="
          sidebarFooterProps?.compact
            ? PRODUCT_BRAND_SHORT
            : $t('ui.layout.poweredBy')
        "
      >
        <span
          v-show="sidebarFooterProps?.compact || !preferences.sidebar.collapsed"
          class="truncate"
          >{{
            sidebarFooterProps?.compact
              ? PRODUCT_BRAND_SHORT
              : $t('ui.layout.poweredBy')
          }}</span>
      </button>
    </template>
    <template #extra>
      <AuthenticationLoginExpiredModal
        v-model:open="accessStore.loginExpired"
        :avatar
      >
        <LoginForm />
      </AuthenticationLoginExpiredModal>
    </template>
  </BasicLayout>
</template>
