<script lang="ts" setup>
import type { FriendLite } from '../../types'

import { computed, ref } from 'vue'

import { Button, message, Modal } from 'ant-design-vue'

import { createGroup } from '#/api/im/group'

import { buildDefaultGroupName } from '../../../utils/group'
import { useFriendStore } from '../../store/friendStore'
import { useGroupStore } from '../../store/groupStore'
import { FriendPickerPanel } from '../picker'

defineOptions({ name: 'ImGroupCreateDialog' })

const emit = defineEmits<{
  /** 创建成功，携带新群编号；父侧通常用来跳转到新群会话 */
  created: [groupId: number]
}>()

const friendStore = useFriendStore()
const groupStore = useGroupStore()

const visible = ref(false)
const submitting = ref(false)
const lockedIds = ref<number[]>([])
const selectedIds = ref<number[]>([])

defineExpose({
  /** 打开发起群聊弹窗：reset → 灌参 → visible=true */
  open(opts?: { lockedIds?: number[] }) {
    lockedIds.value = opts?.lockedIds ? [...opts.lockedIds] : []
    selectedIds.value = []
    submitting.value = false
    visible.value = true
  }
})

/** 全量好友：直接复用 friendStore Lite 视图（带拼音字段供分桶用） */
const friends = computed<FriendLite[]>(() => friendStore.getActiveFriendLiteList)

/** 完成按钮可点：至少有 1 个非 locked 勾选（locked 是入口锁定项，不算"用户主动选择"） */
const canSubmit = computed(() => selectedIds.value.length > 0)

/** 拿到所有要进群的好友（locked + selected）；建群默认群名按这批人生成 */
function resolveMembersToInvite(): FriendLite[] {
  const seen = new Set<number>()
  const result: FriendLite[] = []
  const byId = new Map(friends.value.map((f) => [f.id, f]))
  for (const id of lockedIds.value) {
    if (seen.has(id)) {
      continue
    }
    const friend = byId.get(id)
    if (friend) {
      seen.add(id)
      result.push(friend)
    }
  }
  for (const id of selectedIds.value) {
    if (seen.has(id)) {
      continue
    }
    const friend = byId.get(id)
    if (friend) {
      seen.add(id)
      result.push(friend)
    }
  }
  return result
}

/** 创建群聊：建群（同时邀请初始成员）→ upsert groupStore → emit created 让父页跳转新会话 */
async function handleOk() {
  const members = resolveMembersToInvite()
  if (members.length === 0) {
    return
  }
  submitting.value = true
  try {
    const memberUserIds = members.map((m) => m.id)
    const name = buildDefaultGroupName(members)
    const group = await createGroup({ name, memberUserIds, joinApproval: false })
    if (!group?.id) {
      throw new Error('创建群失败：未返回群编号')
    }
    // 直接 upsert 进 groupStore，省一次 fetchGroupList —— 服务端返回 VO 已经够建会话了
    groupStore.upsertGroup({
      id: group.id,
      name: group.name,
      avatar: group.avatar,
      notice: group.notice,
      ownerUserId: group.ownerUserId
    })
    message.success('群聊创建成功')
    emit('created', group.id)
    visible.value = false
  } finally {
    submitting.value = false
  }
}
</script>

<template>
  <!--
    发起群聊：选好友 → 默认按所选成员名生成群名 → createGroup
    - dialog 壳本组件持有；选择 UI 委托 FriendPickerPanel
    - lockedIds 由调用方通过 open({ lockedIds }) 传入；私聊侧 +建群锁定对方
    - 不再要求先输入群名 / 不再展示「进群审批」开关，对齐微信 PC
    - 对外接口：ref + open({ lockedIds }) + emit created(groupId)
  -->
  <Modal
    v-model:open="visible"
    title="发起群聊"
    width="720px"
    :mask-closable="false"
    class="im-picker-dialog"
  >
    <div class="h-[480px]">
      <FriendPickerPanel
        v-model:selected-ids="selectedIds"
        :friends="friends"
        :locked-ids="lockedIds"
      />
    </div>

    <template #footer>
      <Button @click="visible = false">取消</Button>
      <Button type="primary" :loading="submitting" :disabled="!canSubmit" @click="handleOk">
        完成
      </Button>
    </template>
  </Modal>
</template>

<style scoped lang="scss">
@use '../picker/picker-dialog' as picker;

/* :deep 穿透 el-dialog 内部类；复用 picker 公共 mixin */
.im-picker-dialog {
  @include picker.styles;
}
</style>
