<script setup lang="ts">
// 참여자 목록 — 진행자/참여자 그룹 구분, 이름 검색, 마이크·품질 표시, 진행자의 승격 버튼.
import { computed, ref } from 'vue'
import { ConnectionQuality, type Participant } from 'livekit-client'
import MeetingIcon from './MeetingIcon.vue'
import QualityBars from './QualityBars.vue'
import { avatarColor, avatarInitial } from '@/shared/utils/avatar'
import { normalizeQuality } from '@/composables/useLiveKitRoom'

interface Props {
  participants: Participant[]
  featuredId: string | null
  localId: string | null
  isHost: boolean
}
const props = defineProps<Props>()
const emit = defineEmits<{ (e: 'promote', identity: string): void }>()

const query = ref('')

// metadata 로 진행자 판정
function isHostMeta(p: Participant): boolean {
  if (!p.metadata) return false
  try {
    return (JSON.parse(p.metadata) as { role?: string }).role === 'host'
  } catch {
    return false
  }
}

const filtered = computed(() => {
  const q = query.value.trim()
  return props.participants.filter((p) =>
    (p.name || p.identity).includes(q),
  )
})
const hosts = computed(() => filtered.value.filter(isHostMeta))
const guests = computed(() => filtered.value.filter((p) => !isHostMeta(p)))

function quality(p: Participant) {
  return normalizeQuality(p.connectionQuality as ConnectionQuality)
}
</script>

<template>
  <div class="people">
    <div class="pp-search">
      <MeetingIcon name="search" />
      <input
        v-model="query"
        type="text"
        placeholder="이름 검색…"
        aria-label="참여자 검색"
      >
    </div>
    <div class="pp-list">
      <template v-if="hosts.length">
        <div class="pp-group">
          진행자
        </div>
        <div
          v-for="p in hosts"
          :key="p.identity"
          class="pp-row"
          :class="{ featured: p.identity === featuredId }"
        >
          <span
            class="pp-av"
            :style="{ background: avatarColor(p.name || p.identity) }"
          >{{ avatarInitial(p.name || p.identity) }}</span>
          <span class="pp-name">{{ p.name || p.identity }}{{ p.identity === localId ? ' (나)' : '' }}</span>
          <span
            v-if="p.identity === featuredId"
            class="pp-pin"
            title="스테이지"
          ><MeetingIcon name="pin" /></span>
          <span class="pp-grow" />
          <QualityBars
            :quality="quality(p)"
            variant="bare"
          />
          <span
            class="pp-mic"
            :class="{ off: !p.isMicrophoneEnabled }"
          ><MeetingIcon :name="p.isMicrophoneEnabled ? 'mic' : 'micOff'" /></span>
          <button
            v-if="isHost && p.identity !== featuredId"
            type="button"
            class="pp-promote"
            title="스테이지로 크게 보기"
            @click="emit('promote', p.identity)"
          >
            <MeetingIcon name="expand" />
          </button>
        </div>
      </template>

      <template v-if="guests.length">
        <div class="pp-group">
          참여자 {{ guests.length }}
        </div>
        <div
          v-for="p in guests"
          :key="p.identity"
          class="pp-row"
          :class="{ featured: p.identity === featuredId }"
        >
          <span
            class="pp-av"
            :style="{ background: avatarColor(p.name || p.identity) }"
          >{{ avatarInitial(p.name || p.identity) }}</span>
          <span class="pp-name">{{ p.name || p.identity }}{{ p.identity === localId ? ' (나)' : '' }}</span>
          <span
            v-if="p.identity === featuredId"
            class="pp-pin"
            title="스테이지"
          ><MeetingIcon name="pin" /></span>
          <span class="pp-grow" />
          <QualityBars
            :quality="quality(p)"
            variant="bare"
          />
          <span
            class="pp-mic"
            :class="{ off: !p.isMicrophoneEnabled }"
          ><MeetingIcon :name="p.isMicrophoneEnabled ? 'mic' : 'micOff'" /></span>
          <button
            v-if="isHost && p.identity !== featuredId"
            type="button"
            class="pp-promote"
            title="스테이지로 크게 보기"
            @click="emit('promote', p.identity)"
          >
            <MeetingIcon name="expand" />
          </button>
        </div>
      </template>

      <div
        v-if="filtered.length === 0"
        class="pp-empty"
      >
        검색 결과가 없습니다.
      </div>
    </div>
  </div>
</template>

<style scoped>
.people {
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1;
}
.pp-search {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0.75rem 1rem;
  height: 2.25rem;
  padding: 0 0.6875rem;
  background: var(--d-panel-2);
  border: 1px solid var(--d-border);
  border-radius: 0.5rem;
}
.pp-search svg {
  width: 0.9375rem;
  height: 0.9375rem;
  color: var(--d-text-3);
  flex-shrink: 0;
}
.pp-search input {
  flex: 1;
  min-width: 0;
  border: none;
  outline: none;
  background: transparent;
  font-family: inherit;
  font-size: 0.8125rem;
  color: var(--d-text);
}
.pp-search input::placeholder {
  color: var(--d-text-3);
}
.pp-list {
  flex: 1;
  overflow-y: auto;
  padding: 0 0.5rem 0.75rem;
  scrollbar-width: thin;
  scrollbar-color: var(--d-border) transparent;
}
.pp-list::-webkit-scrollbar {
  width: 0.4375rem;
}
.pp-list::-webkit-scrollbar-thumb {
  background: var(--d-border);
  border-radius: 0.25rem;
}
.pp-group {
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--d-text-3);
  padding: 0.75rem 0.5rem 0.3125rem;
}
.pp-row {
  display: flex;
  align-items: center;
  gap: 0.5625rem;
  padding: 0.4375rem 0.5rem;
  border-radius: 0.5rem;
}
.pp-row:hover {
  background: var(--d-panel-2);
}
.pp-row.featured {
  background: rgba(79, 70, 229, 0.13);
}
.pp-av {
  width: 1.875rem;
  height: 1.875rem;
  border-radius: 50%;
  color: #fff;
  display: grid;
  place-items: center;
  font-size: 0.75rem;
  font-weight: 700;
  flex-shrink: 0;
  text-transform: uppercase;
}
.pp-name {
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--d-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pp-pin {
  color: #9b91ff;
  display: grid;
  place-items: center;
}
.pp-pin svg {
  width: 0.8125rem;
  height: 0.8125rem;
}
.pp-grow {
  flex: 1;
}
.pp-mic {
  color: var(--d-text-2);
  display: grid;
  place-items: center;
}
.pp-mic svg {
  width: 0.9375rem;
  height: 0.9375rem;
}
.pp-mic.off {
  color: var(--d-red);
}
.pp-promote {
  width: 1.75rem;
  height: 1.75rem;
  border: 1px solid var(--d-border);
  background: transparent;
  color: var(--d-text-2);
  border-radius: 0.4375rem;
  cursor: pointer;
  display: grid;
  place-items: center;
}
.pp-promote svg {
  width: 0.875rem;
  height: 0.875rem;
}
.pp-promote:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.pp-empty {
  padding: 1.875rem;
  text-align: center;
  font-size: 0.8125rem;
  color: var(--d-text-3);
}
</style>
