<template>
  <div ref="rootRef" class="user-picker relative">
    <button type="button" class="picker-trigger" @click.stop="toggleOpen">
      <span v-if="selectedUser" class="selected-text">{{ selectedUser.username }}</span>
      <span v-else class="placeholder">选择操作人</span>
      <span v-if="selectedUser" class="clear-btn" @click.stop="clearSelection">✕</span>
    </button>

    <div v-if="isOpen" class="popover-card" @click.stop>
      <input
        v-model="searchKeyword"
        type="text"
        class="search-input"
        placeholder="搜索账号或邮箱..."
        @input="handleSearch"
      />
      <div v-if="loading" class="popover-empty">加载中...</div>
      <div v-else-if="users.length === 0" class="popover-empty">暂无用户</div>
      <ul v-else class="user-list">
        <li
          v-for="user in users"
          :key="user.id"
          class="user-item"
          :class="{ active: modelValue === user.id }"
          @click="selectUser(user)"
        >
          <span class="user-name">{{ user.username }}</span>
          <span class="user-email">{{ user.email }}</span>
        </li>
      </ul>
      <div v-if="total > pageSize" class="popover-pagination">
        <button type="button" :disabled="currentPage <= 1" @click="goPage(currentPage - 1)">上一页</button>
        <span>{{ currentPage }} / {{ totalPages }}</span>
        <button type="button" :disabled="currentPage >= totalPages" @click="goPage(currentPage + 1)">下一页</button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
import { getUsersPaginated, type User } from '../../services/api'

const props = defineProps<{
  modelValue?: number | null
}>()

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

const rootRef = ref<HTMLElement | null>(null)
const isOpen = ref(false)
const loading = ref(false)
const users = ref<User[]>([])
const total = ref(0)
const currentPage = ref(1)
const pageSize = 10
const searchKeyword = ref('')
const selectedUser = ref<User | null>(null)

let searchTimer: ReturnType<typeof setTimeout> | null = null

const totalPages = computed(() => Math.max(1, Math.ceil(total.value / pageSize)))

const loadUsers = async () => {
  loading.value = true
  try {
    const result = await getUsersPaginated({
      page: currentPage.value,
      pageSize,
      keyword: searchKeyword.value || undefined
    })
    users.value = result.list
    total.value = result.total
    if (props.modelValue) {
      const found = result.list.find(u => u.id === props.modelValue)
      if (found) selectedUser.value = found
    }
  } finally {
    loading.value = false
  }
}

const toggleOpen = () => {
  isOpen.value = !isOpen.value
  if (isOpen.value) {
    currentPage.value = 1
    loadUsers()
  }
}

const handleSearch = () => {
  if (searchTimer) clearTimeout(searchTimer)
  searchTimer = setTimeout(() => {
    currentPage.value = 1
    loadUsers()
  }, 300)
}

const goPage = (page: number) => {
  currentPage.value = page
  loadUsers()
}

const selectUser = (user: User) => {
  selectedUser.value = user
  emit('update:modelValue', user.id)
  isOpen.value = false
}

const clearSelection = () => {
  selectedUser.value = null
  emit('update:modelValue', null)
}

const handleClickOutside = (e: MouseEvent) => {
  if (rootRef.value && !rootRef.value.contains(e.target as Node)) {
    isOpen.value = false
  }
}

watch(() => props.modelValue, async (id) => {
  if (!id) {
    selectedUser.value = null
    return
  }
  if (selectedUser.value?.id === id) return
  const result = await getUsersPaginated({ page: 1, pageSize: 1, keyword: String(id) })
  const found = result.list.find(u => u.id === id)
  if (found) {
    selectedUser.value = found
  } else {
    try {
      const { fetchUser } = await import('../../services/api')
      selectedUser.value = await fetchUser(id)
    } catch {
      selectedUser.value = null
    }
  }
}, { immediate: true })

onMounted(() => document.addEventListener('click', handleClickOutside))
onUnmounted(() => document.removeEventListener('click', handleClickOutside))
</script>

<style scoped>
.user-picker {
  min-width: 160px;
}

.picker-trigger {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.5rem 0.75rem;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 0.375rem;
  color: white;
  font-size: 0.875rem;
  cursor: pointer;
  text-align: left;
}

.placeholder {
  color: rgba(255, 255, 255, 0.4);
}

.selected-text {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.clear-btn {
  color: rgba(255, 255, 255, 0.4);
  font-size: 0.75rem;
  padding: 0 0.25rem;
}

.clear-btn:hover {
  color: white;
}

.popover-card {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 100;
  width: 280px;
  background: #1a1a1e;
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 0.5rem;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  overflow: hidden;
}

.search-input {
  width: 100%;
  padding: 0.625rem 0.75rem;
  background: rgba(255, 255, 255, 0.05);
  border: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  color: white;
  font-size: 0.875rem;
  outline: none;
}

.user-list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 240px;
  overflow-y: auto;
}

.user-item {
  padding: 0.625rem 0.75rem;
  cursor: pointer;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}

.user-item:hover,
.user-item.active {
  background: rgba(212, 179, 131, 0.1);
}

.user-name {
  font-size: 0.875rem;
  color: white;
}

.user-email {
  font-size: 0.75rem;
  color: rgba(255, 255, 255, 0.45);
}

.popover-empty {
  padding: 1.5rem;
  text-align: center;
  color: rgba(255, 255, 255, 0.4);
  font-size: 0.875rem;
}

.popover-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 0.75rem;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  font-size: 0.75rem;
  color: rgba(255, 255, 255, 0.5);
}

.popover-pagination button {
  background: none;
  border: none;
  color: #d4b383;
  cursor: pointer;
  font-size: 0.75rem;
  padding: 0.25rem;
}

.popover-pagination button:disabled {
  color: rgba(255, 255, 255, 0.2);
  cursor: not-allowed;
}
</style>
