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

const searchText = ref('')
const editingUrl = ref('')
const editingName = ref('')
const deletingUrl = ref('')
const errorMessage = ref('')

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

const filteredMediaItems = computed(() => {
  const query = searchText.value.trim().toLowerCase()

  if (!query) {
    return mediaItems.value
  }

  return mediaItems.value.filter((item) => [
    item.name,
    item.url,
    item.category,
    ...item.usage.map((usage) => usage.title)
  ].some((value) => value.toLowerCase().includes(query)))
})

/**
 * 파일 크기 표시 문자열 생성
 * @param {number} size - 파일 크기
 * @returns {string} 표시 문자열
 */
const formatFileSize = (size) => {
  if (size < 1024) {
    return `${size} B`
  }

  if (size < 1024 * 1024) {
    return `${(size / 1024).toFixed(1)} KB`
  }

  return `${(size / 1024 / 1024).toFixed(1)} MB`
}

/**
 * 미디어 수정 상태 시작
 * @param {Object} item - 미디어 항목
 * @returns {void}
 */
const startRename = (item) => {
  editingUrl.value = item.url
  editingName.value = item.title
  errorMessage.value = ''
}

/**
 * 미디어 파일명 변경 취소
 * @returns {void}
 */
const cancelRename = () => {
  editingUrl.value = ''
  editingName.value = ''
}

/**
 * 미디어 파일명 변경
 * @returns {Promise<void>}
 */
const renameMedia = async () => {
  const editingItem = mediaItems.value.find((item) => item.url === editingUrl.value)

  if (editingItem?.usage.length) {
    errorMessage.value = '사용 중인 미디어는 파일명을 변경할 수 없습니다.'
    return
  }

  errorMessage.value = ''

  try {
    await $fetch('/admin/api/media', {
      method: 'PUT',
      body: {
        url: editingUrl.value,
        name: editingName.value
      }
    })
    cancelRename()
    await refresh()
  } catch (error) {
    errorMessage.value = error?.data?.message || '파일명을 변경하지 못했습니다.'
  }
}

/**
 * 미디어 삭제
 * @param {Object} item - 미디어 항목
 * @returns {Promise<void>}
 */
const deleteMedia = async (item) => {
  if (item.usage.length) {
    errorMessage.value = '사용 중인 미디어는 삭제할 수 없습니다.'
    return
  }

  if (!confirm(`"${item.name}" 파일을 삭제할까요?`)) {
    return
  }

  deletingUrl.value = item.url
  errorMessage.value = ''

  try {
    await $fetch('/admin/api/media', {
      method: 'DELETE',
      body: {
        url: item.url
      }
    })
    await refresh()
  } catch (error) {
    errorMessage.value = error?.data?.message || '파일을 삭제하지 못했습니다.'
  } finally {
    deletingUrl.value = ''
  }
}
</script>

<template>
  <section class="admin-media bg-paper p-6">
    <div class="admin-media__header flex flex-wrap items-center justify-between gap-4">
      <div>
        <p class="admin-media__eyebrow text-xs font-semibold uppercase text-muted">
          Media
        </p>
        <h1 class="admin-media__title mt-2 text-3xl font-semibold">
          미디어
        </h1>
      </div>
      <input
        v-model="searchText"
        class="admin-media__search w-full rounded border border-line bg-white px-3 py-2 text-sm md:w-72"
        type="search"
        placeholder="파일명 또는 경로 검색"
      >
    </div>

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

    <div v-if="filteredMediaItems.length" class="admin-media__grid mt-8 grid gap-4 sm:grid-cols-2 xl:grid-cols-3">
      <article v-for="item in filteredMediaItems" :key="item.url" class="admin-media__item border border-line bg-white">
        <img class="admin-media__image aspect-[4/3] w-full bg-surface object-cover" :src="item.url" :alt="item.title">
        <div class="admin-media__body grid gap-3 p-4 text-sm">
          <div v-if="editingUrl === item.url" class="admin-media__rename grid gap-2">
            <input
              v-model="editingName"
              class="admin-media__rename-input rounded border border-line px-3 py-2 text-sm"
              type="text"
              @keydown.enter.prevent="renameMedia"
            >
            <div class="admin-media__rename-actions flex gap-2">
              <button class="admin-media__rename-save rounded bg-[#15171a] px-3 py-1.5 text-xs font-semibold text-white" type="button" @click="renameMedia">
                저장
              </button>
              <button class="admin-media__rename-cancel rounded border border-line px-3 py-1.5 text-xs font-semibold" type="button" @click="cancelRename">
                취소
              </button>
            </div>
          </div>
          <template v-else>
            <strong class="admin-media__name break-all text-ink">{{ item.name }}</strong>
            <p class="admin-media__path break-all text-xs text-muted">{{ item.url }}</p>
          </template>

          <p class="admin-media__meta text-xs text-muted">
            {{ item.category }} · {{ formatFileSize(item.size) }}
          </p>
          <div class="admin-media__usage rounded bg-surface p-3 text-xs">
            <strong class="admin-media__usage-title text-ink">
              사용 현황 {{ item.usage.length }}곳
            </strong>
            <ul v-if="item.usage.length" class="admin-media__usage-list mt-2 grid gap-1.5 text-muted">
              <li v-for="usage in item.usage" :key="`${item.url}-${usage.type}-${usage.id}-${usage.location}`" class="admin-media__usage-item">
                <NuxtLink
                  v-if="usage.adminUrl"
                  class="admin-media__usage-link font-semibold text-ink hover:opacity-70"
                  :to="usage.adminUrl"
                >
                  {{ usage.title }}
                </NuxtLink>
                <span v-else class="admin-media__usage-name font-semibold text-ink">{{ usage.title }}</span>
                <span class="admin-media__usage-meta"> · {{ usage.typeLabel }} · {{ usage.label }}</span>
              </li>
            </ul>
            <p v-else class="admin-media__usage-empty mt-2 text-muted">
              사용 중인 곳이 없습니다.
            </p>
          </div>
          <div class="admin-media__actions flex gap-2">
            <button
              class="admin-media__rename-button rounded border border-line px-3 py-1.5 text-xs font-semibold disabled:opacity-50"
              type="button"
              :disabled="item.usage.length > 0"
              @click="startRename(item)"
            >
              파일명 변경
            </button>
            <button
              class="admin-media__delete rounded border border-red-200 px-3 py-1.5 text-xs font-semibold text-red-700 disabled:opacity-50"
              type="button"
              :disabled="deletingUrl === item.url || item.usage.length > 0"
              @click="deleteMedia(item)"
            >
              {{ deletingUrl === item.url ? '삭제 중' : '삭제' }}
            </button>
          </div>
        </div>
      </article>
    </div>

    <p v-else class="admin-media__empty mt-8 border border-dashed border-line bg-white p-8 text-center text-sm text-muted">
      표시할 미디어가 없습니다.
    </p>
  </section>
</template>
