<template>
  <q-page class="q-pa-md">
    <!-- 상단 툴바 -->
    <div class="row items-center q-mb-md">
      <div class="text-h6 text-weight-bold">회원 관리</div>
      <q-chip dense color="blue-1" text-color="primary" class="q-ml-sm">
        총 {{ members.length }}명
      </q-chip>
      <q-space />
      <q-input
        v-model="filter"
        dense
        outlined
        debounce="200"
        placeholder="이메일·닉네임 검색"
        class="q-mr-sm"
        style="min-width: 220px"
      >
        <template #prepend><q-icon name="search" /></template>
      </q-input>
      <q-btn flat round icon="refresh" :loading="loading" @click="load" />
    </div>

    <q-banner v-if="loadError" dense class="bg-red-1 text-red-8 q-mb-md rounded-borders">
      <template #avatar><q-icon name="wifi_off" /></template>
      회원 목록을 불러오지 못했습니다.
    </q-banner>

    <q-table
      :rows="members"
      :columns="columns"
      row-key="id"
      :loading="loading"
      :filter="filter"
      :pagination="{ rowsPerPage: 20 }"
      flat
      bordered
    >
      <!-- 회원(이메일+닉네임+아바타) -->
      <template #body-cell-member="props">
        <q-td :props="props">
          <div class="row items-center no-wrap">
            <q-avatar size="32px" color="blue-1" text-color="primary">
              <img v-if="props.row.profileImage" :src="props.row.profileImage" alt="" />
              <q-icon v-else name="person" />
            </q-avatar>
            <div class="q-ml-sm">
              <div class="text-weight-medium">
                {{ props.row.nickname }}
                <q-chip v-if="isSelf(props.row)" dense size="sm" color="grey-3" text-color="grey-8">본인</q-chip>
              </div>
              <div class="text-caption text-grey-6">{{ props.row.email }}</div>
            </div>
          </div>
        </q-td>
      </template>

      <!-- 제공자 -->
      <template #body-cell-provider="props">
        <q-td :props="props">
          <q-chip dense square size="sm" :color="props.row.provider === 'APPLE' ? 'grey-9' : 'red-2'"
            :text-color="props.row.provider === 'APPLE' ? 'white' : 'red-9'">
            {{ props.row.provider }}
          </q-chip>
        </q-td>
      </template>

      <!-- 상태 -->
      <template #body-cell-status="props">
        <q-td :props="props">
          <q-select
            dense options-dense outlined emit-value map-options
            :model-value="props.row.status"
            :options="statusOptions"
            :disable="isSelf(props.row) || busyId === props.row.id"
            style="min-width: 110px"
            @update:model-value="(v: MemberStatus) => onStatus(props.row, v)"
          />
        </q-td>
      </template>

      <!-- 구독 티어 -->
      <template #body-cell-tier="props">
        <q-td :props="props">
          <q-select
            dense options-dense outlined emit-value map-options
            :model-value="props.row.subscriptionTier"
            :options="tierOptions"
            :disable="busyId === props.row.id"
            style="min-width: 120px"
            @update:model-value="(v: MemberTier) => onTier(props.row, v)"
          />
        </q-td>
      </template>

      <!-- 권한 -->
      <template #body-cell-role="props">
        <q-td :props="props">
          <q-select
            dense options-dense outlined emit-value map-options
            :model-value="props.row.role"
            :options="roleOptions"
            :disable="isSelf(props.row) || busyId === props.row.id"
            style="min-width: 110px"
            @update:model-value="(v: MemberRole) => onRole(props.row, v)"
          />
        </q-td>
      </template>

      <!-- 삭제 -->
      <template #body-cell-actions="props">
        <q-td :props="props">
          <q-btn
            flat dense round icon="delete" color="negative"
            :disable="isSelf(props.row) || busyId === props.row.id"
            @click="onDelete(props.row)"
          />
        </q-td>
      </template>
    </q-table>
  </q-page>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { useQuasar, type QTableColumn } from 'quasar'
import {
  adminMembersApi,
  type MemberRole,
  type MemberStatus,
  type MemberTier,
} from '@/api/adminMembers'
import type { Member } from '@/api/auth'
import { ApiError } from '@/api/http'
import { useAdminAuthStore } from '@/stores/adminAuth'

const $q = useQuasar()
const admin = useAdminAuthStore()

const members = ref<Member[]>([])
const loading = ref(false)
const loadError = ref(false)
const filter = ref('')
const busyId = ref<number | null>(null)

const statusOptions = [
  { label: '활성', value: 'ACTIVE' },
  { label: '휴면', value: 'DORMANT' },
  { label: '정지', value: 'BANNED' },
]
const tierOptions = [
  { label: 'FREE', value: 'FREE' },
  { label: '광고제거', value: 'AD_FREE' },
  { label: 'PREMIUM', value: 'PREMIUM' },
]
const roleOptions = [
  { label: '일반', value: 'USER' },
  { label: '관리자', value: 'ADMIN' },
]

const columns: QTableColumn<Member>[] = [
  { name: 'member', label: '회원', field: 'email', align: 'left', sortable: true },
  { name: 'provider', label: '가입', field: 'provider', align: 'center' },
  { name: 'status', label: '상태', field: 'status', align: 'center' },
  { name: 'tier', label: '구독', field: 'subscriptionTier', align: 'center' },
  { name: 'role', label: '권한', field: 'role', align: 'center' },
  {
    name: 'createdAt',
    label: '가입일',
    field: 'createdAt',
    align: 'center',
    sortable: true,
    format: (v: string) => new Date(v).toLocaleDateString('ko-KR'),
  },
  { name: 'actions', label: '', field: 'id', align: 'center' },
]

onMounted(load)

function isSelf(m: Member): boolean {
  return m.id === admin.member?.id
}

async function load() {
  loading.value = true
  loadError.value = false
  try {
    members.value = await adminMembersApi.list()
  } catch (e) {
    loadError.value = true
    console.error(e)
  } finally {
    loading.value = false
  }
}

/** 변경 API 공통 실행 — 성공 시 해당 행 갱신, 실패 시 알림. */
async function run(id: number, fn: () => Promise<Member>, done: string) {
  busyId.value = id
  try {
    const updated = await fn()
    const i = members.value.findIndex((m) => m.id === id)
    if (i >= 0) members.value[i] = updated
    $q.notify({ color: 'positive', message: done, icon: 'check', position: 'top' })
  } catch (e) {
    const msg = e instanceof ApiError ? e.message : '변경에 실패했습니다.'
    $q.notify({ color: 'negative', message: msg, icon: 'error', position: 'top' })
  } finally {
    busyId.value = null
  }
}

function onStatus(m: Member, status: MemberStatus) {
  if (status === m.status) return
  run(m.id, () => adminMembersApi.updateStatus(m.id, status), '상태를 변경했습니다.')
}

function onTier(m: Member, tier: MemberTier) {
  if (tier === m.subscriptionTier) return
  run(m.id, () => adminMembersApi.updateTier(m.id, tier), '구독 티어를 변경했습니다.')
}

function onRole(m: Member, role: MemberRole) {
  if (role === m.role) return
  run(m.id, () => adminMembersApi.updateRole(m.id, role), '권한을 변경했습니다.')
}

function onDelete(m: Member) {
  $q.dialog({
    title: '회원 삭제',
    message: `${m.nickname}(${m.email}) 회원을 삭제할까요? 되돌릴 수 없습니다.`,
    cancel: true,
    ok: { label: '삭제', color: 'negative' },
  }).onOk(async () => {
    busyId.value = m.id
    try {
      await adminMembersApi.remove(m.id)
      members.value = members.value.filter((x) => x.id !== m.id)
      $q.notify({ color: 'positive', message: '회원을 삭제했습니다.', icon: 'check', position: 'top' })
    } catch (e) {
      const msg = e instanceof ApiError ? e.message : '삭제에 실패했습니다.'
      $q.notify({ color: 'negative', message: msg, icon: 'error', position: 'top' })
    } finally {
      busyId.value = null
    }
  })
}
</script>
