import type { GroupLite, User } from '../types'

import { reactive, ref } from 'vue'

import { acceptHMRUpdate, defineStore } from 'pinia'

import { ImFriendAddSource } from '../../utils/constants'

/**
 * IM 全局 UI store
 *
 * 收纳标准：触发点 N 个、挂载点想保持 1 个的浮层状态。
 * 任意位置都可能 open，但 DOM 上只想留一份实例 → 走 store 派发，
 * 由 `index.vue` 挂一个订阅组件统一渲染。
 */
export const useImUiStore = defineStore('imUiStore', () => {
  // ==================== 用户名片 UserInfoCard ====================
  // 用户名片悬浮卡

  const userInfoCard = reactive({
    show: false,
    user: null as null | User,
    position: { x: 0, y: 0 },
    // addSource / addSourceExtra 跟随触发点带入「加好友」来源（群成员入口 = GROUP + 群名；其余默认搜索）
    addSource: ImFriendAddSource.SEARCH as number,
    addSourceExtra: '' as string
  })

  /** 打开用户名片 */
  function openUserInfoCard(
    user: User,
    position: { x: number; y: number },
    addSource: number = ImFriendAddSource.SEARCH,
    addSourceExtra: string = ''
  ) {
    const viewportWidth = document.documentElement.clientWidth
    const viewportHeight = document.documentElement.clientHeight
    userInfoCard.user = user
    userInfoCard.position.x = Math.min(position.x, viewportWidth - 350)
    userInfoCard.position.y = Math.min(position.y, viewportHeight - 220)
    userInfoCard.addSource = addSource
    userInfoCard.addSourceExtra = addSourceExtra
    userInfoCard.show = true
  }

  /** 鼠标点击位置 + 20px 横向偏移打开名片：避免名片直接覆盖触发元素，对齐头像 / 名片消息等点击交互的统一观感 */
  function openUserInfoCardAtEvent(
    user: User,
    e: MouseEvent,
    addSource: number = ImFriendAddSource.SEARCH,
    addSourceExtra: string = ''
  ) {
    openUserInfoCard(user, { x: e.clientX + 20, y: e.clientY }, addSource, addSourceExtra)
  }

  /** 关闭用户名片 */
  function closeUserInfoCard() {
    userInfoCard.show = false
  }

  // ==================== 群名片 GroupInfoCard ====================

  const groupInfoCard = reactive({
    show: false,
    group: null as GroupLite | null,
    position: { x: 0, y: 0 }
  })

  /** 鼠标点击位置 + 20px 横向偏移打开群名片，对齐 UserInfoCard 的统一观感 */
  function openGroupInfoCardAtEvent(group: GroupLite, e: MouseEvent) {
    const viewportWidth = document.documentElement.clientWidth
    const viewportHeight = document.documentElement.clientHeight
    groupInfoCard.group = group
    groupInfoCard.position.x = Math.min(e.clientX + 20, viewportWidth - 350)
    groupInfoCard.position.y = Math.min(e.clientY, viewportHeight - 220)
    groupInfoCard.show = true
  }

  /** 关闭群名片 */
  function closeGroupInfoCard() {
    groupInfoCard.show = false
  }

  // ==================== 右键菜单 ContextMenu ====================
  // 右键菜单虽然是一个组件挂在主壳上，但其触发时机分散在各列表
  interface ContextMenuItem {
    key: string
    name: string
    disabled?: boolean
    divided?: boolean // 是否在该项上方显示分割线（用于把"删除"等危险操作与上面的常规项隔开）
    danger?: boolean // 是否走危险操作样式（红色文字）
    icon?: string // 可选 iconify 图标名（如 ant-design:delete-outlined）；不传则不渲染前置图标
  }

  const contextMenu = reactive({
    show: false,
    position: { x: 0, y: 0 },
    items: [] as ContextMenuItem[],
    /** 选中回调：每次 open 时由调用方传入 */
    onSelect: null as ((item: ContextMenuItem) => void) | null
  })

  /** 打开右键菜单 */
  function openContextMenu(
    position: { x: number; y: number },
    items: ContextMenuItem[],
    onSelect: (item: ContextMenuItem) => void
  ) {
    contextMenu.position = position
    contextMenu.items = items
    contextMenu.onSelect = onSelect
    contextMenu.show = true
  }

  /** 关闭右键菜单 */
  function closeContextMenu() {
    contextMenu.show = false
    contextMenu.onSelect = null
  }

  // ==================== 消息 Tab 跳转下一未读 ====================
  // 在 ImHomeConversation 页面再次点击工具栏「消息」时触发；
  // 通过递增 nonce 让 conversation/index.vue 的 watch 感知后执行滚动 + 高亮

  const nextUnreadJumpNonce = ref(0)

  /** 请求滚动到下一个未读会话（含免打扰） */
  function requestNextUnreadJump() {
    nextUnreadJumpNonce.value++
  }

  return {
    userInfoCard,
    openUserInfoCard,
    openUserInfoCardAtEvent,
    closeUserInfoCard,

    groupInfoCard,
    openGroupInfoCardAtEvent,
    closeGroupInfoCard,

    contextMenu,
    openContextMenu,
    closeContextMenu,

    nextUnreadJumpNonce,
    requestNextUnreadJump
  }
})

// dev: 让 Pinia 的 actions / state 改动支持 HMR，避免每次改 store 都得硬刷
// 否则 Vite 把新模块推下来后，老 store 实例的 action 闭包仍指向旧函数体
if (import.meta.hot) {
  import.meta.hot.accept(acceptHMRUpdate(useImUiStore, import.meta.hot))
}
