<script setup lang="ts">
import { ref, onMounted, onUnmounted, computed, watch } from 'vue'
import { useGroupStore } from '@/stores/group'
import { listPlayerBlacklist, subscribePlayerBlacklist } from '@/api/playerBlacklist'
import { deletePlayerBlacklistEntry } from '@/api/playerBlacklist'
import { ElMessage, ElPopconfirm } from 'element-plus'
import { pb } from '@/api/pocketbase'
import { displayName } from '@/types'
import { PlayerTagMap, BlacklistSeverityMap } from '@/types'
import type { PlayerBlacklistEntry, PlayerTag, BlacklistSeverity } from '@/types'
import CreatePlayerBlacklistDialog from './CreatePlayerBlacklistDialog.vue'

const groupStore = useGroupStore()

const allEntries = ref<PlayerBlacklistEntry[]>([])
const loading = ref(false)
const showCreate = ref(false)

// 筛选
const filterTag = ref<PlayerTag | ''>('')
const filterSeverity = ref<BlacklistSeverity | ''>('')

// 搜索
const searchPlayerId = ref('')

let unsubscribeFn: (() => void) | null = null

// 按玩家ID聚合
const groupedByPlayer = computed(() => {
  let filtered = allEntries.value
  if (searchPlayerId.value.trim()) {
    const q = searchPlayerId.value.trim().toLowerCase()
    filtered = filtered.filter(e => e.playerId.toLowerCase().includes(q))
  }

  const map = new Map<string, PlayerBlacklistEntry[]>()
  for (const entry of filtered) {
    const key = `${entry.playerId}|${entry.platform}`
    if (!map.has(key)) map.set(key, [])
    map.get(key)!.push(entry)
  }
  for (const entries of map.values()) {
    entries.sort((a, b) => new Date(b.created).getTime() - new Date(a.created).getTime())
  }
  return map
})

// 玩家列表（按被标记次数降序）
const playerGroups = computed(() => {
  const groups: { playerId: string; platform: string; entries: PlayerBlacklistEntry[] }[] = []
  for (const [key, entries] of groupedByPlayer.value) {
    const [playerId, platform] = key.split('|')
    groups.push({ playerId, platform, entries })
  }
  groups.sort((a, b) => b.entries.length - a.entries.length)
  return groups
})

// 展开的玩家
const expandedPlayer = ref<string | null>(null)

async function loadEntries() {
  const groupId = groupStore.currentGroupId
  if (!groupId) return
  loading.value = true
  try {
    const options: { tag?: string; severity?: string } = {}
    if (filterTag.value) options.tag = filterTag.value
    if (filterSeverity.value) options.severity = filterSeverity.value
    allEntries.value = await listPlayerBlacklist(groupId, options)
  } catch (error) {
    console.error('加载玩家黑名单失败:', error)
  } finally {
    loading.value = false
  }
}

async function startSubscription() {
  const groupId = groupStore.currentGroupId
  if (!groupId) return
  unsubscribeFn = await subscribePlayerBlacklist(groupId, () => loadEntries())
}

function stopSubscription() {
  if (unsubscribeFn) {
    unsubscribeFn()
    unsubscribeFn = null
  }
}

function togglePlayer(key: string) {
  expandedPlayer.value = expandedPlayer.value === key ? null : key
}

function handleCreated() {
  showCreate.value = false
  loadEntries()
}

const currentUserId = computed(() => pb.authStore.model?.id)
const isOwner = computed(() => groupStore.isGroupOwner)

function canDelete(entry: PlayerBlacklistEntry): boolean {
  return entry.reporter === currentUserId.value || isOwner.value
}

async function handleDelete(entryId: string) {
  try {
    await deletePlayerBlacklistEntry(entryId)
    ElMessage.success('已删除')
    loadEntries()
  } catch (error: any) {
    ElMessage.error(error.message || '删除失败')
  }
}

function formatTime(dateStr: string): string {
  const date = new Date(dateStr)
  const now = new Date()
  const diffMs = now.getTime() - date.getTime()
  const diffMinutes = Math.floor(diffMs / (1000 * 60))
  const diffHours = Math.floor(diffMinutes / 60)
  const diffDays = Math.floor(diffHours / 24)
  if (diffDays > 30) return `${date.getMonth() + 1}月${date.getDate()}日`
  if (diffDays > 0) return `${diffDays}天前`
  if (diffHours > 0) return `${diffHours}小时前`
  if (diffMinutes > 0) return `${diffMinutes}分钟前`
  return '刚刚'
}

function reporterName(entry: PlayerBlacklistEntry): string {
  return entry.expand?.reporter ? displayName(entry.expand.reporter) : '未知用户'
}

function severityClass(severity: BlacklistSeverity): string {
  return `severity--${severity}`
}

onMounted(() => {
  if (groupStore.currentGroupId) {
    loadEntries()
    startSubscription()
  }
})

watch(() => groupStore.currentGroupId, (newId, oldId) => {
  if (newId && newId !== oldId) {
    expandedPlayer.value = null
    stopSubscription()
    loadEntries()
    startSubscription()
  }
})

watch([filterTag, filterSeverity], () => loadEntries())

onUnmounted(() => stopSubscription())
</script>

<template>
  <div class="player-blacklist-main">
    <div class="player-blacklist-main__header">
      <h3 class="player-blacklist-main__title">玩家黑名单</h3>
      <div class="player-blacklist-main__actions">
        <div class="player-blacklist-main__filters">
          <el-input
            v-model="searchPlayerId"
            placeholder="搜索玩家ID"
            clearable
            size="small"
            class="player-blacklist-main__search"
          />
          <el-select
            v-model="filterTag"
            placeholder="标签筛选"
            clearable
            size="small"
            class="player-blacklist-main__filter-select"
          >
            <el-option
              v-for="(label, key) in PlayerTagMap"
              :key="key"
              :label="label"
              :value="key"
            />
          </el-select>
          <el-select
            v-model="filterSeverity"
            placeholder="严重程度"
            clearable
            size="small"
            class="player-blacklist-main__filter-select"
          >
            <el-option
              v-for="(label, key) in BlacklistSeverityMap"
              :key="key"
              :label="label"
              :value="key"
            />
          </el-select>
        </div>
        <button class="player-blacklist-main__create-btn" @click="showCreate = true">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="player-blacklist-main__create-icon">
            <line x1="12" y1="5" x2="12" y2="19" />
            <line x1="5" y1="12" x2="19" y2="12" />
          </svg>
          标记玩家
        </button>
      </div>
    </div>

    <CreatePlayerBlacklistDialog v-model="showCreate" @created="handleCreated" />

    <!-- 玩家卡片列表 -->
    <div v-if="playerGroups.length > 0" class="player-blacklist-main__content">
      <div v-for="group in playerGroups" :key="group.playerId + group.platform" class="player-blacklist-main__player-group">
        <!-- 玩家卡片 -->
        <div class="player-card" @click="togglePlayer(group.playerId + group.platform)">
          <div class="player-card__info">
            <div class="player-card__name-row">
              <span class="player-card__name">{{ group.playerId }}</span>
              <span class="player-card__platform">{{ group.platform }}</span>
              <span class="player-card__badge">{{ group.entries.length }} 次标记</span>
            </div>
            <div class="player-card__tags">
              <span
                v-for="tag in [...new Set(group.entries.flatMap(e => e.tags))].slice(0, 4)"
                :key="tag"
                class="player-card__tag"
              >
                {{ PlayerTagMap[tag] }}
              </span>
              <span
                v-for="entry in [...new Set(group.entries.map(e => e.customTag).filter(Boolean))].slice(0, 2)"
                :key="entry"
                class="player-card__tag player-card__tag--custom"
              >
                {{ entry }}
              </span>
            </div>
            <div v-if="group.entries[0]?.description" class="player-card__desc">
              {{ group.entries[0].description }}
            </div>
          </div>
          <div class="player-card__arrow">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="player-card__arrow-icon">
              <polyline points="6 9 12 15 18 9" />
            </svg>
          </div>
        </div>

        <!-- 展开的详细记录 -->
        <div v-if="expandedPlayer === group.playerId + group.platform" class="player-blacklist-main__expanded">
          <div
            v-for="(entry, index) in group.entries"
            :key="entry.id"
            :class="['entry', { 'entry--bordered': index > 0 }]"
          >
            <div class="entry__header">
              <div class="entry__reporter">
                <div class="entry__avatar">{{ reporterName(entry).charAt(0) }}</div>
                <span class="entry__name">{{ reporterName(entry) }}</span>
              </div>
              <div class="entry__header-right">
                <span class="entry__time">{{ formatTime(entry.created) }}</span>
                <el-popconfirm
                  v-if="canDelete(entry)"
                  title="确定删除？"
                  confirm-button-text="删除"
                  cancel-button-text="取消"
                  @confirm="handleDelete(entry.id)"
                >
                  <template #reference>
                    <button class="entry__delete-btn" title="删除" @click.stop>
                      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="entry__delete-icon">
                        <polyline points="3 6 5 6 21 6" />
                        <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
                      </svg>
                    </button>
                  </template>
                </el-popconfirm>
              </div>
            </div>
            <div class="entry__tags">
              <span v-for="tag in entry.tags" :key="tag" class="entry__tag">{{ PlayerTagMap[tag] }}</span>
              <span v-if="entry.customTag" class="entry__tag entry__tag--custom">{{ entry.customTag }}</span>
              <span class="entry__severity" :class="severityClass(entry.severity)">{{ BlacklistSeverityMap[entry.severity] }}</span>
            </div>
            <div class="entry__desc">{{ entry.description }}</div>
          </div>
        </div>
      </div>
    </div>

    <div v-else-if="loading" class="player-blacklist-main__loading">
      <p class="player-blacklist-main__loading-text">加载中...</p>
    </div>

    <div v-else class="player-blacklist-main__empty">
      <svg class="player-blacklist-main__empty-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
        <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" />
        <circle cx="12" cy="7" r="4" />
      </svg>
      <p class="player-blacklist-main__empty-text">暂无玩家黑名单记录</p>
      <p class="player-blacklist-main__empty-hint">标记坑人的玩家，下次遇到有准备</p>
    </div>
  </div>
</template>

<style scoped>
.player-blacklist-main {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.player-blacklist-main__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
}

.player-blacklist-main__title {
  font-size: 18px;
  font-weight: 700;
  color: var(--gg-text);
  margin: 0;
}

.player-blacklist-main__actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.player-blacklist-main__filters {
  display: flex;
  align-items: center;
  gap: 8px;
}

.player-blacklist-main__search {
  width: 140px;
}

.player-blacklist-main__filter-select {
  width: 110px;
}

.player-blacklist-main__create-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 16px;
  border: none;
  border-radius: var(--gg-radius-sm);
  background: var(--gg-primary);
  color: #ffffff;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: opacity 0.2s;
}

.player-blacklist-main__create-btn:hover {
  opacity: 0.85;
}

.player-blacklist-main__create-icon {
  width: 16px;
  height: 16px;
}

.player-blacklist-main__content {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.player-blacklist-main__player-group {
  display: flex;
  flex-direction: column;
}

.player-blacklist-main__expanded {
  padding: 0 16px;
  background: var(--gg-bg-elevated);
  border: 1px solid var(--gg-border);
  border-top: none;
  border-radius: 0 0 var(--gg-radius-md) var(--gg-radius-md);
}

/* 玩家卡片 */
.player-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: var(--gg-bg-card);
  border: 1px solid var(--gg-border);
  border-radius: var(--gg-radius-md);
  padding: 16px 18px;
  cursor: pointer;
  transition: border-color 0.2s, box-shadow 0.2s, transform 0.15s;
}

.player-card:hover {
  border-color: var(--gg-primary-light);
  box-shadow: 0 0 20px rgba(5, 150, 105, 0.1);
  transform: translateY(-1px);
}

.player-card__info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.player-card__name-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.player-card__name {
  font-size: 15px;
  font-weight: 600;
  color: var(--gg-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.player-card__platform {
  flex-shrink: 0;
  padding: 1px 8px;
  border-radius: 10px;
  font-size: 11px;
  font-weight: 600;
  background: rgba(99, 102, 241, 0.1);
  color: #6366f1;
}

.player-card__badge {
  flex-shrink: 0;
  padding: 1px 8px;
  border-radius: 10px;
  font-size: 11px;
  font-weight: 600;
  background: rgba(239, 68, 68, 0.1);
  color: var(--gg-danger);
}

.player-card__tags {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

.player-card__tag {
  padding: 2px 8px;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 600;
  line-height: 18px;
  background: rgba(245, 158, 11, 0.1);
  color: var(--gg-warning);
}

.player-card__tag--custom {
  background: rgba(99, 102, 241, 0.1);
  color: #6366f1;
}

.player-card__desc {
  font-size: 13px;
  color: var(--gg-text-secondary);
  line-height: 1.5;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.player-card__arrow {
  flex-shrink: 0;
  display: flex;
  align-items: center;
}

.player-card__arrow-icon {
  width: 18px;
  height: 18px;
  color: var(--gg-text-muted);
  transition: transform 0.2s;
}

.player-card:hover .player-card__arrow-icon {
  color: var(--gg-primary);
}

/* 记录条目 */
.entry {
  padding: 12px 0;
}

.entry--bordered {
  border-top: 1px solid var(--gg-border);
}

.entry__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

.entry__reporter {
  display: flex;
  align-items: center;
  gap: 8px;
}

.entry__avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--gg-primary);
  color: #ffffff;
  font-size: 12px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.entry__name {
  font-size: 13px;
  font-weight: 500;
  color: var(--gg-text);
}

.entry__header-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

.entry__time {
  font-size: 12px;
  color: var(--gg-text-muted);
}

.entry__delete-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: none;
  border-radius: var(--gg-radius-sm);
  background: transparent;
  color: var(--gg-text-muted);
  cursor: pointer;
  transition: color 0.2s, background 0.2s;
}

.entry__delete-btn:hover {
  color: var(--gg-danger);
  background: rgba(239, 68, 68, 0.08);
}

.entry__delete-icon {
  width: 16px;
  height: 16px;
}

.entry__tags {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 8px;
  flex-wrap: wrap;
}

.entry__tag {
  padding: 2px 8px;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 600;
  line-height: 18px;
  background: rgba(245, 158, 11, 0.1);
  color: var(--gg-warning);
}

.entry__tag--custom {
  background: rgba(99, 102, 241, 0.1);
  color: #6366f1;
}

.entry__severity {
  padding: 2px 8px;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 600;
  line-height: 18px;
}

.severity--mild {
  background: rgba(16, 185, 129, 0.1);
  color: var(--gg-success);
}

.severity--medium {
  background: rgba(245, 158, 11, 0.1);
  color: var(--gg-warning);
}

.severity--severe {
  background: rgba(239, 68, 68, 0.1);
  color: var(--gg-danger);
}

.entry__desc {
  font-size: 13px;
  color: var(--gg-text-secondary);
  line-height: 1.6;
}

/* 加载/空状态 */
.player-blacklist-main__loading {
  display: flex;
  justify-content: center;
  padding: 40px 20px;
}

.player-blacklist-main__loading-text {
  font-size: 14px;
  color: var(--gg-text-muted);
}

.player-blacklist-main__empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 48px 20px;
  text-align: center;
}

.player-blacklist-main__empty-icon {
  width: 48px;
  height: 48px;
  color: var(--gg-text-muted);
  margin-bottom: 12px;
  opacity: 0.5;
}

.player-blacklist-main__empty-text {
  font-size: 15px;
  font-weight: 600;
  color: var(--gg-text-secondary);
  margin: 0 0 4px;
}

.player-blacklist-main__empty-hint {
  font-size: 13px;
  color: var(--gg-text-muted);
  margin: 0;
}

@media (max-width: 640px) {
  .player-blacklist-main__header {
    flex-direction: column;
    align-items: flex-start;
  }

  .player-blacklist-main__search {
    width: 100px;
  }

  .player-blacklist-main__filter-select {
    width: 90px;
  }
}
</style>
