<script setup>
definePageMeta({
  layout: 'admin'
})

const deletingId = ref('')
const errorMessage = ref('')
const statusFilter = ref('all')
const tagFilter = ref('all')
const featuredFilter = ref('all')
const sortOrder = ref('newest')

const { data: posts, refresh } = await useFetch('/admin/api/posts', {
  default: () => []
})

const { data: tags } = await useFetch('/admin/api/tags', {
  default: () => []
})

const { data: siteSettings } = await useFetch('/admin/api/settings', {
  default: () => ({ showPostUpdatedAt: false })
})

/**
 * 게시물 발행일 라벨을 반환한다.
 * @param {Object} post - 게시물
 * @returns {string} 발행일 또는 '-'
 */
const getPublishDateLabel = (post) => {
  if (!post.publishedAt) {
    return '-'
  }

  return formatPostDateTime(post.publishedAt)
}

/**
 * 게시물 수정일 보조 라벨을 반환한다.
 * @param {Object} post - 게시물
 * @returns {string} 수정일 라벨 또는 빈 문자열
 */
const getUpdatedDateLabel = (post) => {
  if (!siteSettings.value?.showPostUpdatedAt || !wasPostUpdatedAfterPublish(post)) {
    return ''
  }

  return `수정: ${formatPostDateTime(post.updatedAt)}`
}

/**
 * 목록 정렬용 시각(ms). 발행일이 있으면 발행일, 없으면 수정일(초안 등).
 * @param {Object} post - 게시물
 * @returns {number} 정렬 기준 시각
 */
const getListSortTimestamp = (post) => {
  const sortAt = post.publishedAt || post.updatedAt || post.createdAt

  return new Date(sortAt || 0).getTime()
}

/**
 * 게시물 공개 여부 확인
 * @param {Object} post - 게시물
 * @returns {boolean} 공개 여부
 */
const isPublicPost = (post) => post.status === 'published'
  && (!post.publishedAt || new Date(post.publishedAt) <= new Date())

/**
 * 게시물 상태 필터 키 생성
 * @param {Object} post - 게시물
 * @returns {'published' | 'scheduled' | 'draft'} 상태 키
 */
const getPostStatusKey = (post) => {
  if (post.status === 'published' && !isPublicPost(post)) {
    return 'scheduled'
  }

  if (post.status === 'published') {
    return 'published'
  }

  return 'draft'
}

/**
 * 게시물 상태 표시 문자열 생성
 * @param {Object} post - 게시물
 * @returns {string} 상태 표시 문자열
 */
const getPostStatusLabel = (post) => {
  const statusKey = getPostStatusKey(post)

  if (statusKey === 'scheduled') {
    return '예약'
  }

  if (statusKey === 'published') {
    return '발행'
  }

  return '초안'
}

/**
 * 게시물 상태 텍스트 클래스 생성
 * @param {Object} post - 게시물
 * @returns {string} 상태 텍스트 클래스
 */
const getPostStatusClass = (post) => {
  const statusKey = getPostStatusKey(post)

  if (statusKey === 'scheduled') {
    return 'font-bold text-[#30cf43]'
  }

  if (statusKey === 'draft') {
    return 'font-bold text-[#fb2d8d]'
  }

  if (statusKey === 'published') {
    return 'text-[#99A3AD]'
  }

  return 'font-bold text-[#8e9cac]'
}

/**
 * 태그 슬러그의 표시 이름을 조회한다.
 * @param {string} slug - 태그 슬러그
 * @returns {string} 태그 표시 이름
 */
const getTagName = (slug) => tags.value.find((tag) => tag.slug === slug)?.name || slug

const usedTagSlugs = computed(() => {
  const slugs = new Set()
  for (const post of posts.value) {
    for (const tag of post.tags || []) {
      slugs.add(tag)
    }
  }
  return [...slugs].sort((a, b) => getTagName(a).localeCompare(getTagName(b), 'ko'))
})

/** 전체 게시물 수 */
const totalPostCount = computed(() => posts.value.length)

/** 추천(`isFeatured`) 게시물 수 */
const featuredPostCount = computed(() => posts.value.filter((post) => post.isFeatured).length)

/** 필터가 적용됐는지 */
const hasActiveListFilters = computed(() => statusFilter.value !== 'all'
  || tagFilter.value !== 'all'
  || featuredFilter.value !== 'all')

const filteredPosts = computed(() => {
  const filtered = posts.value.filter((post) => {
    const matchesStatus = statusFilter.value === 'all' || getPostStatusKey(post) === statusFilter.value
    const matchesTag = tagFilter.value === 'all' || (post.tags || []).includes(tagFilter.value)
    const matchesFeatured = featuredFilter.value === 'all'
      || (featuredFilter.value === 'featured' && post.isFeatured)

    return matchesStatus && matchesTag && matchesFeatured
  })

  return [...filtered].sort((a, b) => {
    const left = getListSortTimestamp(a)
    const right = getListSortTimestamp(b)

    return sortOrder.value === 'oldest' ? left - right : right - left
  })
})

/**
 * 게시물 삭제
 * @param {Object} post - 삭제할 게시물
 * @returns {Promise<void>} 삭제 처리 결과
 */
const deletePost = async (post) => {
  if (!confirm(`"${post.title}" 글을 삭제할까요?`)) {
    return
  }

  deletingId.value = post.id
  errorMessage.value = ''

  try {
    await $fetch(`/admin/api/posts/${post.id}`, {
      method: 'DELETE'
    })
    await refresh()
  } catch (error) {
    errorMessage.value = error?.data?.message || '글을 삭제하지 못했습니다.'
  } finally {
    deletingId.value = ''
  }
}
</script>

<template>
  <section class="admin-posts bg-paper p-6">
    <div class="admin-posts__header flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
      <div>
        <p class="admin-posts__eyebrow text-xs font-semibold uppercase text-muted">
          Posts
        </p>
        <h1 class="admin-posts__title mt-2 text-3xl font-semibold">
          글 목록
        </h1>
        <p class="admin-posts__count mt-2 text-sm text-muted">
          총 {{ totalPostCount }}개
          <template v-if="featuredPostCount > 0">
            <span class="admin-posts__count-separator text-[#c8ced3]"> · </span>
            <span class="admin-posts__count-featured">추천 {{ featuredPostCount }}개</span>
          </template>
          <template v-if="hasActiveListFilters && filteredPosts.length !== totalPostCount">
            <span class="admin-posts__count-separator text-[#c8ced3]"> · </span>
            <span class="admin-posts__count-filtered">표시 {{ filteredPosts.length }}개</span>
          </template>
        </p>
      </div>
      <div class="admin-posts__header-actions flex min-w-0 flex-1 flex-wrap items-center justify-start gap-2 lg:flex-nowrap lg:justify-end">
        <div class="admin-posts__filters flex min-w-0 flex-wrap items-center gap-2">
          <label class="admin-posts__filter">
            <span class="sr-only">상태 필터</span>
            <select v-model="statusFilter" class="admin-posts__filter-select h-10 rounded border border-line bg-white px-3 text-sm text-[#394047] outline-none transition-colors hover:border-[#c8ced3] focus:border-[#8e9cac]">
              <option value="all">전체 상태</option>
              <option value="published">발행</option>
              <option value="draft">초안</option>
              <option value="scheduled">예약</option>
            </select>
          </label>
          <label class="admin-posts__filter">
            <span class="sr-only">태그 필터</span>
            <select v-model="tagFilter" class="admin-posts__filter-select h-10 rounded border border-line bg-white px-3 text-sm text-[#394047] outline-none transition-colors hover:border-[#c8ced3] focus:border-[#8e9cac]">
              <option value="all">전체 태그</option>
              <option v-for="tag in usedTagSlugs" :key="tag" :value="tag">
                {{ getTagName(tag) }}
              </option>
            </select>
          </label>
          <label class="admin-posts__filter">
            <span class="sr-only">추천 필터</span>
            <select v-model="featuredFilter" class="admin-posts__filter-select h-10 rounded border border-line bg-white px-3 text-sm text-[#394047] outline-none transition-colors hover:border-[#c8ced3] focus:border-[#8e9cac]">
              <option value="all">전체 글</option>
              <option value="featured">추천만</option>
            </select>
          </label>
          <label class="admin-posts__filter">
            <span class="sr-only">정렬</span>
            <select v-model="sortOrder" class="admin-posts__filter-select h-10 rounded border border-line bg-white px-3 text-sm text-[#394047] outline-none transition-colors hover:border-[#c8ced3] focus:border-[#8e9cac]">
              <option value="newest">최신순</option>
              <option value="oldest">오래된순</option>
            </select>
          </label>
        </div>
        <NuxtLink class="admin-posts__new shrink-0 rounded bg-[#15171a] px-4 py-2 text-sm font-semibold text-white" to="/admin/posts/new">
          새 글
        </NuxtLink>
      </div>
    </div>

    <p v-if="errorMessage" class="admin-posts__error mt-6 rounded border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700">
      {{ errorMessage }}
    </p>

    <div class="admin-posts__table mt-8 overflow-hidden border border-line">
      <table class="admin-posts__table-inner w-full border-collapse text-left text-sm">
        <thead class="admin-posts__table-head bg-[#f5f5f2] text-xs uppercase text-muted">
          <tr>
            <th class="admin-posts__cell admin-posts__cell-featured w-10 px-2 py-3 text-center">
              <span class="sr-only">추천</span>
              <span class="inline-flex size-4 items-center justify-center text-[#f5a623]" aria-hidden="true">★</span>
            </th>
            <th class="admin-posts__cell px-4 py-3">제목</th>
            <th class="admin-posts__cell px-4 py-3">상태</th>
            <th class="admin-posts__cell px-4 py-3">태그</th>
            <th class="admin-posts__cell px-4 py-3">발행일</th>
            <th class="admin-posts__cell px-4 py-3">관리</th>
          </tr>
        </thead>
        <tbody class="admin-posts__table-body divide-y divide-line bg-white">
          <tr v-for="post in filteredPosts" :key="post.id" class="admin-posts__row">
            <td class="admin-posts__cell admin-posts__cell-featured w-10 px-2 py-4 text-center">
              <span
                v-if="post.isFeatured"
                class="admin-posts__featured-star inline-flex size-8 items-center justify-center text-[#f5a623]"
                title="추천 글"
                aria-label="추천 글"
              >
                <svg class="size-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
                  <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
                </svg>
              </span>
            </td>
            <td class="admin-posts__cell px-4 py-4">
              <div class="admin-posts__title-row flex flex-wrap items-center gap-x-2 gap-y-1">
                <NuxtLink class="admin-posts__title-link font-semibold hover:opacity-70" :to="`/admin/posts/${post.id}`">
                  {{ post.title || '(제목 없음)' }}
                </NuxtLink>
                <span class="admin-posts__comment-count text-xs font-medium text-muted">
                  댓글 {{ post.commentCount || 0 }}
                </span>
              </div>
              <p class="admin-posts__slug mt-1 text-xs text-muted">
                /post/{{ post.slug }}
              </p>
            </td>
            <td class="admin-posts__cell px-4 py-4">
              <span
                class="admin-posts__status-text text-xs"
                :class="getPostStatusClass(post)"
              >
                {{ getPostStatusLabel(post) }}
              </span>
            </td>
            <td class="admin-posts__cell px-4 py-4">
              <div v-if="post.tags.length" class="admin-posts__tag-list flex flex-wrap gap-1.5">
                <span
                  v-for="tag in post.tags"
                  :key="tag"
                  class="admin-posts__tag-badge inline-flex h-6 items-center rounded-[3px] bg-[#ecd2de] px-2 text-xs font-semibold text-[#e04e87]"
                >
                  {{ tag }}
                </span>
              </div>
              <span v-else class="admin-posts__tag-empty text-muted">-</span>
            </td>
            <td class="admin-posts__cell px-4 py-4">
              <p class="admin-posts__publish-date text-[#394047]">
                {{ getPublishDateLabel(post) }}
              </p>
              <p v-if="getUpdatedDateLabel(post)" class="admin-posts__updated-date mt-1 text-xs text-muted">
                {{ getUpdatedDateLabel(post) }}
              </p>
            </td>
            <td class="admin-posts__cell px-4 py-4">
              <button
                class="admin-posts__delete-icon inline-flex size-9 items-center justify-center rounded text-muted opacity-35 transition-all hover:opacity-100 hover:text-red-600 focus-visible:outline focus-visible:ring-2 focus-visible:ring-[#8e9cac] focus-visible:ring-offset-1 disabled:pointer-events-none disabled:opacity-20"
                type="button"
                :disabled="deletingId === post.id"
                :aria-label="deletingId === post.id ? '삭제 중' : '삭제'"
                @click="deletePost(post)"
              >
                <span v-if="deletingId === post.id" class="admin-posts__delete-progress text-[10px] font-semibold text-muted" aria-hidden="true">…</span>
                <svg
                  v-else
                  class="size-5 shrink-0"
                  xmlns="http://www.w3.org/2000/svg"
                  viewBox="0 0 24 24"
                  fill="currentColor"
                  aria-hidden="true"
                >
                  <path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" />
                </svg>
              </button>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
    <p v-if="filteredPosts.length === 0" class="admin-posts__empty mt-6 text-sm text-muted">
      {{ posts.length === 0 ? '아직 작성된 글이 없습니다.' : '조건에 맞는 글이 없습니다.' }}
    </p>
  </section>
</template>
