<template>
  <!--
    群成员选择面板：用于「移除成员 / 设置管理员 / 转让群主 / 禁言成员」等场景
    - 左：搜索 + 群成员列表（圆形勾选）
    - 右：已选数标题 + 已选成员（list / grid 两种形态可配，默认 list 对齐微信新视觉）
    - Panel 不带 el-dialog 壳；dialog 由业务壳持有
    - 三态语义：hide > locked > disabled
  -->
  <div class="flex h-full">
    <!-- 左栏 -->
    <div
      class="flex flex-col flex-1 min-w-0 border-r border-r-solid border-[var(--el-border-color-lighter)] bg-[var(--el-fill-color-light)]"
    >
      <!-- 搜索框 -->
      <div class="flex-shrink-0 px-3 py-2">
        <el-input v-model="keyword" placeholder="搜索成员" clearable>
          <template #prefix>
            <Icon icon="ant-design:search-outlined" />
          </template>
        </el-input>
      </div>

      <div class="flex-1 min-h-0">
        <PagedScroller :items="shownMembers" :page-size="30">
          <template #default="{ item }">
            <GroupMemberItem
              :member="(item as GroupMemberLite)"
              :height="46"
              @click="handleToggle(item as GroupMemberLite)"
            >
              <span
                class="flex flex-shrink-0 justify-center items-center w-5 h-5 rounded-full transition-colors"
                :class="getCheckClass(item as GroupMemberLite)"
              >
                <Icon
                  v-if="isSelected(item as GroupMemberLite) || isLocked(item as GroupMemberLite)"
                  icon="ant-design:check-outlined"
                  :size="12"
                  color="#fff"
                />
              </span>
            </GroupMemberItem>
          </template>
        </PagedScroller>
      </div>
    </div>

    <!-- 右栏 -->
    <div class="flex flex-col flex-1 min-w-0">
      <!-- 标题：已选数；高度对齐左侧 input default（32px） -->
      <div
        class="flex-shrink-0 h-12 px-4 leading-[3rem] border-b border-b-solid text-13px text-[var(--el-text-color-secondary)] border-[var(--el-border-color-lighter)]"
      >
        已选择 {{ selectedCount }} 位成员
      </div>

      <el-scrollbar class="flex-1">
        <!-- list 形态：纵向行，每行带 × 移除（locked 不渲染 ×） -->
        <template v-if="selectedDisplay === 'list'">
          <div
            v-for="member in selectedMembers"
            :key="member.userId"
            class="flex gap-2.5 items-center px-4 py-2"
          >
            <UserAvatar
              :id="member.userId"
              :url="member.avatar"
              :name="member.nickname"
              :size="36"
              :clickable="false"
            />
            <span
              class="flex-1 min-w-0 overflow-hidden text-sm truncate text-[var(--el-text-color-primary)]"
            >
              {{ member.showName }}
            </span>
            <Icon
              v-if="!isLocked(member)"
              icon="ant-design:close-outlined"
              :size="14"
              class="flex-shrink-0 cursor-pointer transition-colors text-[var(--el-text-color-placeholder)] hover:text-[var(--el-color-danger)]"
              @click="handleToggle(member)"
            />
          </div>
        </template>

        <!-- grid 形态：宫格预览（管理员设置等场景沿用） -->
        <div v-else class="flex flex-wrap p-2.5">
          <GroupMemberGrid
            v-for="member in selectedMembers"
            :key="member.userId"
            :member="member"
          />
        </div>

        <div
          v-if="selectedMembers.length === 0"
          class="py-10 text-13px text-center text-[var(--el-text-color-disabled)]"
        >
          请从左侧选择成员
        </div>
      </el-scrollbar>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { computed, ref } from 'vue'
import Icon from '@/components/Icon/src/Icon.vue'
import { useMessage } from '@/hooks/web/useMessage'

import { CommonStatusEnum } from '@/utils/constants'
import GroupMemberItem from '../group/GroupMemberItem.vue'
import GroupMemberGrid from '../group/GroupMemberGrid.vue'
import UserAvatar from '../user/UserAvatar.vue'
import PagedScroller from '../PagedScroller.vue'
import { useSelectedItems } from '../../composables/useSelectedItems'
import type { GroupMemberLite } from '../group/GroupMember.vue'

defineOptions({ name: 'ImGroupMemberPickerPanel' })

const props = withDefaults(
  defineProps<{
    /** 群成员列表 */
    members: GroupMemberLite[]
    /** 已选 userId（v-model）；按数组顺序即为点击顺序 */
    selectedIds: number[]
    /** 锁定 userId：默认勾选、不可取消、计入已选数 */
    lockedIds?: number[]
    /** 禁用 userId：列表里展示置灰、不可勾选、不计入已选数 */
    disabledIds?: number[]
    /** 隐藏 userId：不展示（hide > locked > disabled） */
    hideIds?: number[]
    /** 已选数上限；不传或 <=0 时不限 */
    maxSize?: number
    /** 已选区展示形态：默认 list 对齐微信新视觉 */
    selectedDisplay?: 'list' | 'grid'
  }>(),
  {
    lockedIds: () => [],
    disabledIds: () => [],
    hideIds: () => [],
    maxSize: 0,
    selectedDisplay: 'list'
  }
)

const emit = defineEmits<{
  'update:selectedIds': [value: number[]]
}>()

const message = useMessage()

const keyword = ref('')

/** userId → member 映射，已选反查 / 三态判定共用 */
const byId = computed(() => {
  const map = new Map<number, GroupMemberLite>()
  for (const member of props.members) {
    map.set(member.userId, member)
  }
  return map
})

const hideSet = computed(() => new Set(props.hideIds))
const lockedSet = computed(() => new Set(props.lockedIds))
const disabledSet = computed(() => new Set(props.disabledIds))
const selectedSet = computed(() => new Set(props.selectedIds))

/** 当前展示的成员：剔除 hideIds、剔除已退群（DISABLE）、按关键字大小写无关过滤 */
const shownMembers = computed(() => {
  const keywordLower = keyword.value.trim().toLowerCase()
  return props.members.filter(
    (member) =>
      !hideSet.value.has(member.userId) &&
      member.status !== CommonStatusEnum.DISABLE &&
      (!keywordLower || member.showName.toLowerCase().includes(keywordLower))
  )
})

/** 已选数 + 已选成员列表：三态优先级 + 顺序拼接由 useSelectedItems 统一承担 */
const { selectedCount, selectedItems: selectedMembers } = useSelectedItems<GroupMemberLite>(
  () => props.selectedIds,
  () => props.lockedIds,
  () => props.disabledIds,
  () => props.hideIds,
  byId
)

/** 是否被锁定 */
function isLocked(member: GroupMemberLite): boolean {
  return lockedSet.value.has(member.userId)
}

/** 是否被禁用：locked / hide 已被前置过滤，剩下的才算 disabled */
function isDisabled(member: GroupMemberLite): boolean {
  return !lockedSet.value.has(member.userId) && disabledSet.value.has(member.userId)
}

/** 是否选中：locked 视为永远选中 */
function isSelected(member: GroupMemberLite): boolean {
  return selectedSet.value.has(member.userId)
}

/** 圆形勾选指示器的 class */
function getCheckClass(member: GroupMemberLite): string {
  if (isLocked(member) || isSelected(member)) {
    return 'bg-[#07c160] border border-solid border-[#07c160]'
  }
  if (isDisabled(member)) {
    return 'bg-[var(--el-fill-color)] border border-solid border-[var(--el-border-color)]'
  }
  return 'border border-solid border-[var(--el-border-color)] bg-[var(--el-bg-color)]'
}

/** 切换选中态：locked / disabled 不响应；右栏 × / 行 click 都走这里 */
function handleToggle(member: GroupMemberLite) {
  if (isLocked(member) || isDisabled(member)) {
    return
  }
  const next = [...props.selectedIds]
  const index = next.indexOf(member.userId)
  if (index >= 0) {
    next.splice(index, 1)
  } else {
    if (props.maxSize > 0 && selectedCount.value >= props.maxSize) {
      message.error(`最多选择 ${props.maxSize} 位成员`)
      return
    }
    next.push(member.userId)
  }
  emit('update:selectedIds', next)
}
</script>

