<script setup>
import { computed, onMounted, ref } from 'vue'
import { boardApi } from '@/api/boardApi'
import { useDialog } from '@/composables/dialog'

const dialog = useDialog()

const items = ref([])
const loading = ref(false)
const error = ref(null)
const busyKey = ref(null) // 처리 중인 대상 키 (버튼 비활성화용)

const CATEGORY_LABEL = { community: '커뮤니티', saving: '짠테크 수다방', tips: '재테크 팁' }

const blockedCount = computed(() => items.value.filter((i) => i.blocked).length)

function keyOf(it) {
  return `${it.targetType}:${it.targetId}`
}
function isSpam(it) {
  return it.blockReason === '스팸 키워드 감지'
}
function categoryLabel(c) {
  return CATEGORY_LABEL[c] || c || '게시판'
}
function linkTo(it) {
  return `/board/${it.category || 'community'}/${it.postId}`
}
function formatTime(s) {
  if (!s) return ''
  const d = new Date(s)
  if (Number.isNaN(d.getTime())) return s
  return d.toLocaleString('ko-KR', {
    year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit',
  })
}

async function load() {
  loading.value = true
  error.value = null
  try {
    items.value = await boardApi.reports()
  } catch (e) {
    error.value = e.response?.data?.message || '신고 목록을 불러오지 못했습니다.'
  } finally {
    loading.value = false
  }
}

async function run(it, fn, successMsg) {
  busyKey.value = keyOf(it)
  try {
    await fn()
    await load()
    if (successMsg) await dialog.alert(successMsg)
  } catch (e) {
    await dialog.alert(e.response?.data?.message || '처리에 실패했습니다.')
  } finally {
    busyKey.value = null
  }
}

// 글 블라인드 (사유 입력)
async function blockPost(it) {
  const reason = await dialog.prompt('블라인드 사유를 입력하세요. (열람 제한 안내에 표시)', {
    title: '글 블라인드',
    okText: '블라인드',
    defaultValue: '신고 누적으로 블라인드 처리되었습니다.',
  })
  if (reason === null) return
  await run(it, () => boardApi.block(it.postId, reason || null), '블라인드 처리했습니다.')
}

// 블라인드 해제 (글/댓글) — 신고 기록도 초기화됨
async function unblock(it) {
  const ok = await dialog.confirm('블라인드를 해제하고 신고 기록을 초기화할까요?', {
    title: '블라인드 해제',
    okText: '해제',
  })
  if (!ok) return
  const call = it.targetType === 'POST'
    ? () => boardApi.unblock(it.postId)
    : () => boardApi.unblockComment(it.targetId)
  await run(it, call, '블라인드를 해제했습니다.')
}

// 신고 무시 — 블라인드 없이 신고 기록만 삭제
async function dismiss(it) {
  const ok = await dialog.confirm('이 신고를 무시하고 목록에서 제거할까요? (블라인드하지 않고 신고 기록만 삭제)', {
    title: '신고 무시',
    okText: '무시',
    danger: true,
  })
  if (!ok) return
  await run(it, () => boardApi.dismissReport(it.targetType, it.targetId))
}

onMounted(load)
</script>

<template>
  <div class="report-admin">
    <div class="head">
      <p class="desc">
        신고 누적 <strong>5건</strong> 이상 또는 스팸 키워드 포함 시 자동 블라인드됩니다.
        관리자는 여기서 내용을 검토해 <b>블라인드</b> 하거나, 정상 글이면 <b>신고 무시</b>로 정리할 수 있습니다.
      </p>
      <button class="reload" type="button" :disabled="loading" @click="load">↻ 새로고침</button>
    </div>

    <p v-if="error" class="msg error">{{ error }}</p>
    <p v-if="loading" class="msg">불러오는 중…</p>

    <p v-else-if="!items.length" class="msg empty">🎉 신고된 글·댓글이 없습니다.</p>

    <template v-else>
      <p class="count">
        총 <strong>{{ items.length }}</strong>건
        <span v-if="blockedCount"> · 블라인드 {{ blockedCount }}건</span>
      </p>

      <ul class="list">
        <li v-for="it in items" :key="keyOf(it)" class="card" :class="{ blocked: it.blocked }">
          <div class="row1">
            <span class="badge" :class="it.targetType === 'POST' ? 'post' : 'comment'">
              {{ it.targetType === 'POST' ? '글' : '댓글' }}
            </span>
            <span class="cat">{{ categoryLabel(it.category) }}</span>
            <span v-if="isSpam(it)" class="badge spam">🤖 스팸감지</span>
            <span v-else class="report-count">🚩 {{ it.reportCount }}</span>
            <span v-if="it.blocked" class="badge blind">블라인드됨</span>
            <span class="time">{{ formatTime(it.lastReportedAt) }}</span>
          </div>

          <RouterLink :to="linkTo(it)" class="title-link">
            <span v-if="it.targetType === 'COMMENT'" class="on-post">[{{ it.title }}] 의 댓글</span>
            <span v-else class="ttl">{{ it.title }}</span>
          </RouterLink>
          <p class="content">{{ it.content }}</p>
          <p class="author">작성자: {{ it.authorName || '알 수 없음' }}</p>
          <p v-if="it.blockReason" class="block-reason">사유: {{ it.blockReason }}</p>

          <div class="actions">
            <RouterLink :to="linkTo(it)" class="btn ghost">글 보기</RouterLink>
            <button
              v-if="it.targetType === 'POST' && !it.blocked"
              class="btn danger"
              type="button"
              :disabled="busyKey === keyOf(it)"
              @click="blockPost(it)"
            >
              블라인드
            </button>
            <button
              v-if="it.blocked"
              class="btn"
              type="button"
              :disabled="busyKey === keyOf(it)"
              @click="unblock(it)"
            >
              블라인드 해제
            </button>
            <button
              v-if="!it.blocked && !isSpam(it)"
              class="btn ghost"
              type="button"
              :disabled="busyKey === keyOf(it)"
              @click="dismiss(it)"
            >
              신고 무시
            </button>
          </div>
        </li>
      </ul>
    </template>
  </div>
</template>

<style scoped>
.report-admin {
  padding: 0.5rem 0 2rem;
}
.head {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  margin-bottom: 1rem;
}
.desc {
  flex: 1;
  margin: 0;
  font-size: 0.9rem;
  color: var(--color-text-soft, #666);
  line-height: 1.5;
}
.reload {
  flex-shrink: 0;
  border: 1px solid var(--color-border);
  background: var(--color-background-soft);
  color: var(--color-text);
  border-radius: 8px;
  padding: 0.4rem 0.7rem;
  cursor: pointer;
  font-size: 0.85rem;
}
.msg {
  padding: 1rem;
  color: var(--color-text-soft, #666);
}
.msg.error {
  color: #e5484d;
}
.msg.empty {
  text-align: center;
  padding: 3rem 1rem;
}
.count {
  margin: 0 0 0.75rem;
  font-size: 0.9rem;
  color: var(--color-text-soft, #666);
}
.list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.card {
  border: 1px solid var(--color-border);
  border-radius: 12px;
  padding: 0.85rem 1rem;
  background: var(--color-background);
}
.card.blocked {
  border-color: #e5484d55;
  background: #e5484d0d;
}
.row1 {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 0.5rem;
}
.badge {
  font-size: 0.72rem;
  font-weight: 700;
  padding: 0.12rem 0.45rem;
  border-radius: 6px;
}
.badge.post {
  background: #00bc7e22;
  color: #00996a;
}
.badge.comment {
  background: #3b82f622;
  color: #2563eb;
}
.badge.blind {
  background: #e5484d22;
  color: #e5484d;
}
.badge.spam {
  background: #f9731622;
  color: #ea580c;
}
.block-reason {
  margin: 0 0 0.4rem;
  font-size: 0.75rem;
  color: #ea580c;
}
.cat {
  font-size: 0.78rem;
  color: var(--color-text-soft, #888);
}
.report-count {
  font-size: 0.8rem;
  font-weight: 700;
  color: #e5484d;
}
.time {
  margin-left: auto;
  font-size: 0.75rem;
  color: var(--color-text-soft, #999);
}
.title-link {
  display: block;
  color: var(--color-text);
  text-decoration: none;
  font-weight: 600;
  margin-bottom: 0.25rem;
}
.title-link:hover {
  text-decoration: underline;
}
.on-post {
  color: var(--color-text-soft, #777);
  font-weight: 500;
}
.content {
  margin: 0 0 0.4rem;
  font-size: 0.88rem;
  color: var(--color-text-soft, #555);
  white-space: pre-wrap;
  word-break: break-word;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.author {
  margin: 0 0 0.6rem;
  font-size: 0.78rem;
  color: var(--color-text-soft, #999);
}
.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}
.btn {
  border: 1px solid var(--color-border);
  background: var(--color-background-soft);
  color: var(--color-text);
  border-radius: 8px;
  padding: 0.35rem 0.75rem;
  cursor: pointer;
  font-size: 0.82rem;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
}
.btn:disabled {
  opacity: 0.5;
  cursor: default;
}
.btn.ghost {
  background: transparent;
}
.btn.danger {
  border-color: #e5484d;
  color: #e5484d;
}
</style>
