<!-- =============================================================================
// 企微IT智能服务台 — H5用户端参与者列表组件
// =============================================================================
// 说明：展示会话中所有参与者信息
//   - 被邀请人列表（真实头像 + 姓名 + 部门 + 加入状态）
//   - 当前用户高亮标识
//   - 退出会话按钮（仅被邀请人可见）
//   - 头像降级策略：有avatar URL用<img>，无则显示姓名首字
// ============================================================================= -->

<template>
  <div class="participant-list">
    <!-- 参与者列表 -->
    <div class="participant-list__items">
      <!-- 原始员工（会话发起人） -->
      <div v-if="ownerInfo" class="participant-item participant-item--owner">
        <div class="participant-item__avatar">
          <!-- 有头像URL：渲染<img>，加载失败降级显示首字 -->
          <img
            v-if="ownerInfo.avatar"
            :src="ownerInfo.avatar"
            :alt="ownerInfo.name"
            class="participant-item__avatar-img"
            @error="onAvatarError($event)"
          />
          <span v-else class="participant-item__avatar-letter">
            {{ avatarLetter(ownerInfo.name) }}
          </span>
        </div>
        <div class="participant-item__info">
          <span class="participant-item__name">{{ ownerInfo.name }}</span>
          <span v-if="ownerInfo.department" class="participant-item__dept">{{ ownerInfo.department }}</span>
        </div>
        <span class="participant-item__badge participant-item__badge--owner">发起人</span>
      </div>

      <!-- 主责坐席 -->
      <div v-if="agentInfo" class="participant-item participant-item--agent">
        <div class="participant-item__avatar participant-item__avatar--agent">
          <span class="participant-item__avatar-letter">
            {{ avatarLetter(agentInfo.name) }}
          </span>
        </div>
        <div class="participant-item__info">
          <span class="participant-item__name">{{ agentInfo.name }}</span>
          <span class="participant-item__dept">IT坐席</span>
        </div>
        <span class="participant-item__badge participant-item__badge--agent">坐席</span>
      </div>

      <!-- 被邀请参与者 -->
      <div
        v-for="p in invitedParticipants"
        :key="p.id"
        class="participant-item"
        :class="{ 'participant-item--self': p.id === currentUserId }"
      >
        <div class="participant-item__avatar">
          <!-- 有头像URL：渲染<img>，加载失败降级显示首字 -->
          <img
            v-if="p.avatar"
            :src="p.avatar"
            :alt="p.name"
            class="participant-item__avatar-img"
            @error="onAvatarError($event)"
          />
          <span v-else class="participant-item__avatar-letter">
            {{ avatarLetter(p.name) }}
          </span>
        </div>
        <div class="participant-item__info">
          <span class="participant-item__name">
            {{ p.name }}
            <span v-if="p.id === currentUserId" class="participant-item__self-tag">（我）</span>
          </span>
          <span v-if="p.department" class="participant-item__dept">{{ p.department }}</span>
        </div>
        <!-- 加入状态 -->
        <span
          v-if="p.joined"
          class="participant-item__badge participant-item__badge--joined"
        >已加入</span>
        <span
          v-else
          class="participant-item__badge participant-item__badge--pending"
        >待加入</span>
      </div>
    </div>

    <!-- 退出按钮（仅被邀请参与者可见） -->
    <div v-if="store.isParticipant" class="participant-list__footer">
      <button
        class="participant-list__leave-btn"
        :disabled="leaving"
        @click="handleLeave"
      >
        {{ leaving ? '退出中...' : '退出会话' }}
      </button>
    </div>
  </div>
</template>

<script setup lang="ts">
/**
 * ParticipantList 参与者列表组件
 * 展示会话中所有参与者信息（含真实头像），被邀请人可退出
 *
 * 头像策略：
 * 1. 被邀请参与者：后端 invite_participants 时从 employees 表/企微API获取 avatar，存入 participants JSON
 * 2. 原始员工（发起人）：从 employeeStore.employeeInfo.avatar 获取当前用户头像
 * 3. 坐席：暂无头像接口，使用首字母降级
 * 4. 所有 <img> 加载失败时，自动降级显示姓名首字
 */
import { ref, computed } from 'vue'
import { showToast, showConfirmDialog } from 'vant'
import { useConversationStore } from '@/stores/conversation'
import { useEmployeeStore } from '@/stores/employee'
import type { ParticipantItem } from '@/api/conversation'

const store = useConversationStore()
const employeeStore = useEmployeeStore()

/** 退出操作进行中 */
const leaving = ref(false)

/** 当前登录用户 ID */
const currentUserId = computed(() => store.userInfo?.employee_id || '')

/** 原始员工信息（会话发起人），含头像 */
const ownerInfo = computed(() => {
  const conv = store.currentConversation
  if (!conv) return null

  // 判断发起人是否是当前用户
  const isSelf = conv.employee_id === currentUserId.value
  return {
    // 当前用户显示"我"，其他用户显示真实姓名（从会话 employee_name 获取）
    name: isSelf ? '我' : (conv.employee_name || '员工'),
    department: '',
    // 当前用户的头像从 employeeStore 获取，其他用户暂无头像接口
    avatar: isSelf ? (employeeStore.employeeInfo?.avatar || '') : '',
  }
})

/** 坐席信息（坐席头像暂无接口，使用首字母降级） */
const agentInfo = computed(() => {
  const conv = store.currentConversation
  if (!conv?.agent_name) return null
  return { name: conv.agent_name }
})

/** 被邀请的参与者（排除原始员工，avatar 由后端填充） */
const invitedParticipants = computed<ParticipantItem[]>(() => {
  return store.participants || []
})

/**
 * 获取姓名首字作为降级头像
 * @param name - 姓名
 */
function avatarLetter(name: string): string {
  return (name || '?').charAt(0)
}

/**
 * 头像加载失败时的降级处理
 * 做什么：隐藏 <img>，显示父容器的首字降级
 * 为什么：企微头像 URL 可能过期或网络异常
 */
function onAvatarError(event: Event): void {
  const img = event.target as HTMLImageElement
  // 隐藏图片元素，让 CSS 显示首字降级
  img.style.display = 'none'
}

/**
 * 退出会话
 * 做什么：被邀请人主动退出当前会话
 * 为什么：参与者不再需要参与时，可自行退出
 */
async function handleLeave(): Promise<void> {
  try {
    // 二次确认
    await showConfirmDialog({
      title: '退出会话',
      message: '确定要退出该会话吗？退出后将无法查看会话消息。',
      confirmButtonText: '确定退出',
      cancelButtonText: '再想想',
      confirmButtonColor: '#ee0a24',
    })

    leaving.value = true
    await store.leaveAsParticipant()
    showToast('已退出会话')
    // 退出成功后收起面板
    store.participantPanelVisible = false
  } catch (err: any) {
    // 用户取消确认时 err 为 'cancel'，不提示错误
    if (err !== 'cancel') {
      console.error('[ParticipantList] 退出失败:', err)
      showToast('退出失败，请重试')
    }
  } finally {
    leaving.value = false
  }
}
</script>

<style scoped>
/* 参与者列表容器 */
.participant-list {
  padding: 8px 0;
}

/* 参与者项 */
.participant-list__items {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* 单个参与者 */
.participant-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 8px;
  transition: background-color 0.15s;
}

.participant-item:hover {
  background-color: var(--bg-tertiary);
}

/* 当前用户高亮 */
.participant-item--self {
  background-color: var(--accent-soft, rgba(59, 130, 246, 0.08));
}

/* 头像容器（圆形，默认渐变背景 + 首字） */
.participant-item__avatar {
  position: relative;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: linear-gradient(135deg, #667eea, #764ba2);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 600;
  flex-shrink: 0;
  overflow: hidden;
}

.participant-item__avatar--agent {
  background: linear-gradient(135deg, #07C160, #00b347);
}

/* 真实头像图片（覆盖在容器上） */
.participant-item__avatar-img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
}

/* 首字降级（无头像时显示） */
.participant-item__avatar-letter {
  position: relative;
  z-index: 1;
  line-height: 1;
}

/* 信息区 */
.participant-item__info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.participant-item__name {
  font-size: 14px;
  color: var(--text-primary);
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.participant-item__self-tag {
  font-size: 12px;
  color: var(--accent);
  font-weight: 400;
}

.participant-item__dept {
  font-size: 11px;
  color: var(--text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 状态徽标 */
.participant-item__badge {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 10px;
  white-space: nowrap;
  flex-shrink: 0;
}

.participant-item__badge--owner {
  background-color: rgba(59, 130, 246, 0.1);
  color: var(--accent);
}

.participant-item__badge--agent {
  background-color: rgba(7, 193, 96, 0.1);
  color: #07C160;
}

.participant-item__badge--joined {
  background-color: rgba(7, 193, 96, 0.1);
  color: #07C160;
}

.participant-item__badge--pending {
  background-color: rgba(255, 152, 0, 0.1);
  color: #FF9800;
}

/* 底部退出按钮区域 */
.participant-list__footer {
  padding: 12px 12px 4px;
  border-top: 1px solid var(--border-color);
  margin-top: 8px;
}

/* 退出按钮 */
.participant-list__leave-btn {
  width: 100%;
  padding: 10px 0;
  border: 1px solid #ee0a24;
  background: transparent;
  color: #ee0a24;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s;
  font-family: inherit;
  -webkit-tap-highlight-color: transparent;
  outline: none;
}

.participant-list__leave-btn:hover:not(:disabled) {
  background-color: rgba(238, 10, 36, 0.06);
}

.participant-list__leave-btn:active:not(:disabled) {
  background-color: rgba(238, 10, 36, 0.12);
}

.participant-list__leave-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
</style>
