<script setup>
const route = useRoute()

const isPostEditorRoute = computed(() => route.path === '/admin/posts/new'
  || (route.path.startsWith('/admin/posts/') && route.path !== '/admin/posts/preview'))

const editorDocumentClass = 'admin-post-editor-document'
const adminUserMenuOpen = ref(false)

const { data: adminMember } = await useFetch('/api/auth/me', {
  default: () => ({
    username: '',
    email: '',
    avatarUrl: ''
  })
})

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

const memberCount = computed(() => adminMembers.value.length)
const adminDisplayName = computed(() => adminMember.value?.username || adminMember.value?.email || '관리자')
const adminDisplayEmail = computed(() => adminMember.value?.email || '')
const adminAvatarUrl = computed(() => adminMember.value?.avatarUrl || '')
const adminAvatarInitial = computed(() => adminDisplayName.value.slice(0, 1).toUpperCase() || 'A')

/**
 * 관리자 내비게이션 활성 경로 확인
 * @param {string} path - 확인할 경로
 * @returns {boolean} 활성 여부
 */
const isAdminNavActive = (path) => route.path === path || route.path.startsWith(`${path}/`)

/**
 * 관리자 사용자 메뉴 닫기
 * @returns {void}
 */
const closeAdminUserMenu = () => {
  adminUserMenuOpen.value = false
}

/**
 * 관리자 사용자 메뉴 토글
 * @returns {void}
 */
const toggleAdminUserMenu = () => {
  adminUserMenuOpen.value = !adminUserMenuOpen.value
}

/**
 * 외부 클릭 시 관리자 사용자 메뉴 닫기
 * @param {PointerEvent} event - 포인터 이벤트
 * @returns {void}
 */
const onAdminDocumentPointerDown = (event) => {
  if (!adminUserMenuOpen.value || !(event.target instanceof HTMLElement)) {
    return
  }

  if (event.target.closest('[data-admin-user-menu]')) {
    return
  }

  closeAdminUserMenu()
}

/**
 * 글쓰기 전체 화면 문서 스크롤 잠금 적용
 * @returns {void}
 */
const syncPostEditorDocumentClass = () => {
  if (!import.meta.client) {
    return
  }

  document.documentElement.classList.toggle(editorDocumentClass, isPostEditorRoute.value)
  document.body.classList.toggle(editorDocumentClass, isPostEditorRoute.value)
}

watchEffect(syncPostEditorDocumentClass)

onMounted(() => {
  document.addEventListener('pointerdown', onAdminDocumentPointerDown)
})

onBeforeUnmount(() => {
  if (!import.meta.client) {
    return
  }

  document.documentElement.classList.remove(editorDocumentClass)
  document.body.classList.remove(editorDocumentClass)
  document.removeEventListener('pointerdown', onAdminDocumentPointerDown)
})

/**
 * 관리자 로그아웃
 * @returns {Promise<void>} 로그아웃 처리 결과
 */
const logoutAdmin = async () => {
  await $fetch('/admin/api/auth/logout', {
    method: 'POST'
  })
  closeAdminUserMenu()
  await navigateTo('/admin/login')
}
</script>

<template>
  <div
    class="admin-layout bg-[#f7f8fa] text-ink"
    :class="isPostEditorRoute ? 'h-screen overflow-hidden bg-white' : 'min-h-screen'"
  >
    <aside
      v-if="!isPostEditorRoute"
      class="admin-layout__sidebar fixed inset-y-0 left-0 hidden w-80 flex-col border-r border-[#e6e8eb] bg-[#f7f8fa] px-5 py-6 text-[#15171a] lg:flex"
    >
      <NuxtLink class="admin-layout__brand flex items-center gap-3 px-2 text-[0.95rem] font-semibold tracking-[-0.01em]" to="/admin">
        <span class="admin-layout__brand-mark flex h-8 w-8 items-center justify-center rounded-full border border-[#d8dce1] bg-white shadow-[0_1px_2px_rgba(15,23,42,0.05)]">
          <span class="h-5 w-5 rounded-full border-2 border-[#15171a]" />
        </span>
        <span>sori.studio</span>
      </NuxtLink>
      <nav class="admin-layout__nav mt-10 grid gap-1.5 text-sm font-medium text-[#5d6673]">
        <div
          class="admin-layout__nav-item group flex items-center rounded-md transition-colors"
          :class="isAdminNavActive('/admin/posts') ? 'bg-[#e9ecef] text-[#15171a]' : 'hover:bg-[#eceff2] hover:text-[#15171a]'"
        >
          <NuxtLink class="admin-layout__nav-link flex min-w-0 flex-1 items-center gap-3 px-3 py-2" to="/admin/posts">
            <svg class="admin-layout__nav-icon h-4 w-4 shrink-0" viewBox="0 0 24 24" aria-hidden="true">
              <path d="M12.667 14.136l-3.712.531.53-3.713 9.546-9.546a2.25 2.25 0 013.182 3.182z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" />
              <path d="M19.122 14.25v7.5a1.5 1.5 0 01-1.5 1.5h-15a1.5 1.5 0 01-1.5-1.5v-15a1.5 1.5 0 011.5-1.5h7.5" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" />
            </svg>
            <span class="truncate">게시글</span>
          </NuxtLink>
          <NuxtLink
            class="admin-layout__nav-create mr-2 flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-[#5d6673] transition-colors hover:bg-white hover:text-[#15171a] hover:shadow-[0_1px_2px_rgba(15,23,42,0.08)]"
            to="/admin/posts/new"
            aria-label="새 게시글 작성"
          >
            <svg class="h-3.5 w-3.5" viewBox="0 0 16 16" fill="none" aria-hidden="true">
              <path d="M8 1v14M1 8h14" stroke="currentColor" stroke-width="2" stroke-linecap="round" />
            </svg>
          </NuxtLink>
        </div>
        <NuxtLink
          class="admin-layout__nav-link flex items-center gap-3 rounded-md px-3 py-2 transition-colors hover:bg-[#eceff2] hover:text-[#15171a]"
          :class="isAdminNavActive('/admin/pages') ? 'bg-[#e9ecef] text-[#15171a]' : ''"
          to="/admin/pages"
        >
          <svg class="admin-layout__nav-icon h-4 w-4 shrink-0" viewBox="0 0 24 24" aria-hidden="true">
            <path d="M16.5 21.513a1.5 1.5 0 01-1.9 1.446L4.1 20.042A1.5 1.5 0 013 18.6V2.487a1.5 1.5 0 011.9-1.446l10.5 3.391a1.5 1.5 0 011.1 1.445z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" />
            <path d="M4.5.987h15a1.5 1.5 0 011.5 1.5v15.75a1.5 1.5 0 01-1.5 1.5h-3" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" />
          </svg>
          <span>페이지</span>
        </NuxtLink>
        <NuxtLink
          class="admin-layout__nav-link flex items-center gap-3 rounded-md px-3 py-2 transition-colors hover:bg-[#eceff2] hover:text-[#15171a]"
          :class="isAdminNavActive('/admin/tags') ? 'bg-[#e9ecef] text-[#15171a]' : ''"
          to="/admin/tags"
        >
          <svg class="admin-layout__nav-icon h-4 w-4 shrink-0" viewBox="0 0 24 24" aria-hidden="true">
            <path d="M1.061 2.56v6.257a3 3 0 00.878 2.121L13.5 22.5a1.5 1.5 0 002.121 0l6.879-6.88a1.5 1.5 0 000-2.121L10.939 1.938a3 3 0 00-2.121-.878H2.561a1.5 1.5 0 00-1.5 1.5z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" />
          </svg>
          <span>태그</span>
        </NuxtLink>
        <NuxtLink
          class="admin-layout__nav-link flex items-center gap-3 rounded-md px-3 py-2 transition-colors hover:bg-[#eceff2] hover:text-[#15171a]"
          :class="isAdminNavActive('/admin/media') ? 'bg-[#e9ecef] text-[#15171a]' : ''"
          to="/admin/media"
        >
          <svg class="admin-layout__nav-icon h-4 w-4 shrink-0" xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="currentColor" aria-hidden="true">
            <path d="M305-193.85v-191.54l153.46 95.77L305-193.85Zm215-373.84q-47.44 0-80.64-33.18-33.21-33.18-33.21-80.58t33.21-80.67q33.2-33.26 80.64-33.26h43.85v47.69H520q-27.56 0-46.86 19.32-19.29 19.32-19.29 46.92t19.29 46.83q19.3 19.24 46.86 19.24h43.85v47.69H520Zm116.15 0v-47.69H680q27.56 0 46.86-19.33 19.29-19.32 19.29-46.92t-19.29-46.83q-19.3-19.23-46.86-19.23h-43.85v-47.69H680q47.44 0 80.64 33.17 33.21 33.18 33.21 80.58t-33.21 80.67q-33.2 33.27-80.64 33.27h-43.85Zm-110-90v-47.69h147.7v47.69h-147.7Zm106.7 239.61v-60h194.84q5.39 0 8.85-3.46t3.46-8.85v-335.38q0-5.38-3.46-8.84-3.46-3.47-8.85-3.47H372.31q-5.39 0-8.85 3.47-3.46 3.46-3.46 8.84v336.15h-60v-336.15q0-29.82 21.24-51.07 21.24-21.24 51.07-21.24h455.38q29.83 0 51.07 21.24Q900-855.59 900-825.77v335.38q0 29.83-21.24 51.07-21.24 21.24-51.07 21.24H632.85ZM132.31-61.92q-29.83 0-51.07-21.24Q60-104.41 60-134.23V-445q0-29.83 21.24-51.07 21.24-21.24 51.07-21.24h455.38q29.83 0 51.07 21.24Q660-474.83 660-445v310.77q0 29.82-21.24 51.07-21.24 21.24-51.07 21.24H132.31Zm0-60h455.38q5.39 0 8.85-3.47 3.46-3.46 3.46-8.84V-445q0-5.39-3.46-8.85t-8.85-3.46H132.31q-5.39 0-8.85 3.46T120-445v310.77q0 5.38 3.46 8.84 3.46 3.47 8.85 3.47ZM600-658.08ZM360-289.62Z" />
          </svg>
          <span>미디어</span>
        </NuxtLink>
        <NuxtLink
          class="admin-layout__nav-link flex items-center gap-3 rounded-md px-3 py-2 transition-colors hover:bg-[#eceff2] hover:text-[#15171a]"
          :class="isAdminNavActive('/admin/navigation') ? 'bg-[#e9ecef] text-[#15171a]' : ''"
          to="/admin/navigation"
        >
          <svg class="admin-layout__nav-icon h-4 w-4 shrink-0" xmlns="http://www.w3.org/2000/svg" viewBox="-0.75 -0.75 24 24" aria-hidden="true">
            <path d="M2.109375 0.7059375h18.28125s1.40625 0 1.40625 1.40625v18.28125s0 1.40625 -1.40625 1.40625H2.109375s-1.40625 0 -1.40625 -1.40625v-18.28125s0 -1.40625 1.40625 -1.40625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" />
            <path d="m6.328125 7.0340625 9.84375 0" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" />
            <path d="m6.328125 11.252812500000001 9.84375 0" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" />
            <path d="m6.328125 15.471562500000001 9.84375 0" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" />
          </svg>
          <span>네비게이션</span>
        </NuxtLink>
        <NuxtLink
          class="admin-layout__nav-link flex items-center gap-3 rounded-md px-3 py-2 transition-colors hover:bg-[#eceff2] hover:text-[#15171a]"
          :class="isAdminNavActive('/admin/members') ? 'bg-[#e9ecef] text-[#15171a]' : ''"
          to="/admin/members"
        >
          <svg class="admin-layout__nav-icon h-4 w-4 shrink-0" viewBox="0 0 24 24" aria-hidden="true">
            <circle cx="7.5" cy="7.875" r="4.125" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" />
            <path d="M.75 20.25a6.75 6.75 0 0113.5 0" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" />
            <circle cx="17.727" cy="10.125" r="3.375" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" />
            <path d="M15.813 15.068a5.526 5.526 0 017.437 5.182" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" />
          </svg>
          <span class="min-w-0 flex-1">멤버</span>
          <span class="admin-layout__member-count ml-auto rounded-full bg-[#e1e5e9] px-2 py-0.5 text-xs font-semibold text-[#5d6673]">
            {{ memberCount }}
          </span>
        </NuxtLink>
      </nav>
      <div class="admin-layout__bottom relative mt-auto pt-6" data-admin-user-menu>
        <div
          v-if="adminUserMenuOpen"
          class="admin-layout__user-popover absolute bottom-14 left-0 right-0 overflow-hidden rounded-xl border border-[#e2e5e9] bg-white text-[#15171a] shadow-[0_18px_50px_rgba(15,23,42,0.16)]"
        >
          <div class="admin-layout__user-summary flex items-center gap-3 border-b border-[#eceff2] px-4 py-4">
            <img
              v-if="adminAvatarUrl"
              class="admin-layout__user-avatar h-11 w-11 rounded-full border border-[#e2e5e9] object-cover"
              :src="adminAvatarUrl"
              :alt="adminDisplayName"
            >
            <span v-else class="admin-layout__user-avatar flex h-11 w-11 items-center justify-center rounded-full border border-[#e2e5e9] bg-[#15171a] text-sm font-semibold text-white">
              {{ adminAvatarInitial }}
            </span>
            <span class="min-w-0">
              <span class="block truncate text-sm font-semibold">{{ adminDisplayName }}</span>
              <span class="block truncate text-xs text-[#657080]">{{ adminDisplayEmail }}</span>
            </span>
          </div>
          <div class="admin-layout__user-actions grid py-2 text-sm text-[#3f4650]">
            <NuxtLink class="admin-layout__user-action px-4 py-2.5 hover:bg-[#f3f5f7]" to="/settings" @click="closeAdminUserMenu">
              내 프로필
            </NuxtLink>
            <button class="admin-layout__user-action px-4 py-2.5 text-left hover:bg-[#f3f5f7]" type="button" @click="logoutAdmin">
              로그아웃
            </button>
          </div>
        </div>
        <div class="admin-layout__bottom-row flex items-center justify-between gap-3 px-2">
          <button class="admin-layout__user-trigger flex min-w-0 items-center gap-2 rounded-md px-1.5 py-1.5 transition-colors hover:bg-[#eceff2]" type="button" :aria-expanded="adminUserMenuOpen" @click="toggleAdminUserMenu">
            <img
              v-if="adminAvatarUrl"
              class="admin-layout__user-trigger-avatar h-8 w-8 rounded-full border border-[#d8dce1] object-cover"
              :src="adminAvatarUrl"
              :alt="adminDisplayName"
            >
            <span v-else class="admin-layout__user-trigger-avatar flex h-8 w-8 items-center justify-center rounded-full border border-[#d8dce1] bg-[#15171a] text-xs font-semibold text-white">
              {{ adminAvatarInitial }}
            </span>
            <svg class="h-3 w-3 shrink-0 text-[#5d6673]" fill="none" viewBox="0 0 26 24" aria-hidden="true">
              <path clip-rule="evenodd" d="M1.043 6.604a1 1 0 011.414 0L13 17.146 23.543 6.604a1 1 0 011.414 1.414l-10.72 10.719a1.75 1.75 0 01-2.474 0L1.042 8.018a1 1 0 010-1.414zm11.78 10.72v-.001zm.355 0v-.001z" fill="currentColor" />
            </svg>
          </button>
          <NuxtLink class="admin-layout__bottom-settings flex h-9 w-9 items-center justify-center rounded-md text-[#3f4650] transition-colors hover:bg-[#eceff2] hover:text-[#15171a]" to="/admin/settings" aria-label="설정">
            <svg class="h-5 w-5" viewBox="0 0 24 24" aria-hidden="true">
              <path d="M10.546 2.438a1.957 1.957 0 002.908 0L14.4 1.4a1.959 1.959 0 013.41 1.413l-.071 1.4a1.958 1.958 0 002.051 2.054l1.4-.071a1.959 1.959 0 011.41 3.41l-1.042.94a1.96 1.96 0 000 2.909l1.042.94a1.959 1.959 0 01-1.413 3.41l-1.4-.071a1.958 1.958 0 00-2.056 2.056l.071 1.4A1.959 1.959 0 0114.4 22.6l-.941-1.041a1.959 1.959 0 00-2.908 0L9.606 22.6A1.959 1.959 0 016.2 21.192l.072-1.4a1.958 1.958 0 00-2.056-2.056l-1.4.071A1.958 1.958 0 011.4 14.4l1.041-.94a1.96 1.96 0 000-2.909L1.4 9.606A1.958 1.958 0 012.809 6.2l1.4.071a1.958 1.958 0 002.058-2.06L6.2 2.81A1.959 1.959 0 019.606 1.4z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" />
              <circle cx="12" cy="12.001" r="4.5" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" />
            </svg>
          </NuxtLink>
        </div>
      </div>
    </aside>
    <main
      class="admin-layout__main bg-paper"
      :class="[
        isPostEditorRoute ? 'h-screen overflow-hidden' : 'min-h-screen px-8 py-8 xl:px-12 xl:py-10',
        { 'lg:ml-80': !isPostEditorRoute }
      ]"
    >
      <slot />
    </main>
  </div>
</template>
