<script setup>
defineProps({
  menuOpen: {
    type: Boolean,
    required: true
  }
})

const { isDarkMode, toggleTheme } = useThemeMode()

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

const { data: navigation } = await useFetch('/api/navigation', {
  default: () => ({
    primary: [],
    footer: []
  })
})

const STORAGE_KEY = 'sori-primary-nav-expanded'

/**
 * 트리에서 하위가 있는 노드 id를 모은다.
 * @param {Array<Object>} list - 노드 목록
 * @returns {string[]} id 목록
 */
const collectBranchIds = (list) => {
  const out = []
  for (const node of list || []) {
    if (node.children?.length) {
      out.push(String(node.id))
      out.push(...collectBranchIds(node.children))
    }
  }
  return out
}

/**
 * localStorage에서 펼침 상태를 읽는다.
 * @returns {string[]|null} id 배열
 */
const readStoredExpanded = () => {
  if (typeof window === 'undefined') {
    return null
  }
  try {
    const raw = window.localStorage.getItem(STORAGE_KEY)
    if (!raw) {
      return null
    }
    const parsed = JSON.parse(raw)
    return Array.isArray(parsed) ? parsed.map(String) : null
  } catch {
    return null
  }
}

/**
 * 펼침 상태를 localStorage에 저장한다.
 * @param {Set<string>} set - id 집합
 * @returns {void}
 */
const persistExpanded = (set) => {
  if (typeof window === 'undefined') {
    return
  }
  window.localStorage.setItem(STORAGE_KEY, JSON.stringify([...set]))
}

const primaryNavExpandedSet = ref(new Set())

/**
 * 트리 구조에 맞게 펼침 집합을 맞춘다.
 * @param {Array<Object>} nodes - primary 트리
 * @param {boolean} useStorage - 최초·복원 시 저장값 반영
 * @returns {void}
 */
const syncPrimaryNavExpanded = (nodes, useStorage = false) => {
  const allBranch = new Set(collectBranchIds(nodes))
  if (useStorage) {
    const stored = readStoredExpanded()
    if (stored && stored.length) {
      const next = new Set()
      for (const id of stored) {
        if (allBranch.has(id)) {
          next.add(id)
        }
      }
      primaryNavExpandedSet.value = next.size ? next : allBranch
      return
    }
  }
  const next = new Set()
  for (const id of primaryNavExpandedSet.value) {
    if (allBranch.has(id)) {
      next.add(id)
    }
  }
  primaryNavExpandedSet.value = next.size ? next : allBranch
}

/**
 * 상단 네비 폴더 펼침 토글
 * @param {string} id - 노드 id
 * @returns {void}
 */
const togglePrimaryNavBranch = (id) => {
  const key = String(id)
  const next = new Set(primaryNavExpandedSet.value)
  if (next.has(key)) {
    next.delete(key)
  } else {
    next.add(key)
  }
  primaryNavExpandedSet.value = next
  persistExpanded(next)
}

provide('sidebarPrimaryNavExpandedSet', primaryNavExpandedSet)
provide('sidebarPrimaryNavToggle', togglePrimaryNavBranch)

watch(
  () => navigation.value?.primary,
  (nodes) => {
    syncPrimaryNavExpanded(nodes || [], false)
  },
  { deep: true }
)

onMounted(() => {
  syncPrimaryNavExpanded(navigation.value?.primary || [], true)
})
</script>

<template>
  <aside
    id="menu"
    class="left-sidebar site-sidebar flex flex-col overflow-hidden border-r border-[var(--site-line)] transition-[width,opacity,transform,border-color] duration-300 ease-out max-lg:fixed max-lg:left-0 max-lg:top-[57px] max-lg:z-[60] max-lg:h-[calc(100dvh-57px)] max-lg:max-h-[calc(100dvh-57px)] max-lg:w-[min(287px,calc(100vw-24px))] max-lg:shadow-[0_16px_48px_rgba(0,0,0,0.18)] lg:sticky lg:top-[57px] lg:z-10 lg:h-[calc(100vh-57px)] lg:max-h-[calc(100vh-57px)] lg:self-start"
    :class="menuOpen
      ? 'max-lg:translate-x-0 max-lg:pointer-events-auto lg:w-[287px] lg:opacity-100'
      : 'max-lg:-translate-x-full max-lg:pointer-events-none lg:w-0 lg:opacity-0 lg:border-transparent'"
  >
    <div class="left-sidebar__scroll site-sidebar-scroll min-h-0 flex-1">
      <div class="left-sidebar__block site-sidebar-section py-3 pl-4 pr-3 sm:pl-5 xl:pl-0">
        <nav class="left-sidebar__nav" data-nav="menu">
          <SidebarPrimaryNavList :nodes="navigation.primary" />
        </nav>
      </div>

      <div class="left-sidebar__block site-sidebar-section px-5 py-4 pr-3 xl:pl-0">
        <div class="left-sidebar__section-title flex items-center justify-between pr-2 text-xs font-semibold uppercase tracking-[0.01em] site-muted">
          <span>Categories</span>
          <span class="text-sm">⌃</span>
        </div>
        <div class="left-sidebar__category-grid mt-1.5 grid grid-cols-2 gap-x-2 gap-y-[2px] text-[0.8rem] font-medium">
          <NuxtLink
            v-for="tag in tags"
            :key="tag.id"
            class="left-sidebar__category site-panel-hover group flex items-center gap-2 rounded-[10px] py-2 pr-3 pl-0 leading-tight transition-[padding,background-color,color] duration-200 hover:px-3"
            :to="`/tag/${tag.slug}`"
          >
            <span class="left-sidebar__category-color h-4 w-1 rounded-sm rounded-l-none transition-all duration-200 group-hover:h-2 group-hover:w-2 group-hover:rounded-full" :style="{ backgroundColor: tag.color }" />
            <span class="left-sidebar__category-name flex-1 truncate transition-transform duration-200 group-hover:translate-x-[3px]">{{ tag.name }}</span>
            <span
              v-if="tag.postCount"
              class="left-sidebar__category-count invisible text-xs font-medium opacity-0 transition-opacity duration-200 group-hover:visible group-hover:opacity-100"
            >
              {{ tag.postCount }}
            </span>
          </NuxtLink>
        </div>
      </div>

      <div class="left-sidebar__block site-sidebar-section px-5 py-5 pr-3 xl:pl-0">
        <div class="left-sidebar__section-title flex items-center justify-between text-xs font-semibold uppercase site-muted">
          <span>Authors</span>
          <span>⌃</span>
        </div>
        <div class="left-sidebar__authors mt-4 grid gap-4 text-sm">
          <div class="left-sidebar__author flex items-center gap-3">
            <span class="h-8 w-8 rounded-full bg-[#e7c49d]" />
            <span><strong class="block">sori</strong><span class="site-soft">Editor</span></span>
          </div>
          <div class="left-sidebar__author flex items-center gap-3">
            <span class="h-8 w-8 rounded-full bg-[#98b7d5]" />
            <span><strong class="block">zenn</strong><span class="site-soft">Writer</span></span>
          </div>
        </div>
      </div>
    </div>

    <footer class="left-sidebar__footer flex shrink-0 items-center justify-between px-4 py-4 text-xs sm:px-5">
      <nav class="left-sidebar__footer-nav flex gap-4">
        <NuxtLink
          v-for="item in navigation.footer"
          :key="item.id"
          class="site-interactive"
          :to="item.url"
        >
          {{ item.label }}
        </NuxtLink>
      </nav>
      <button
        class="left-sidebar__theme-dot site-panel-hover site-interactive grid h-7 w-7 place-items-center rounded-full"
        type="button"
        :aria-label="isDarkMode ? '라이트 모드로 전환' : '다크 모드로 전환'"
        :title="isDarkMode ? '라이트 모드' : '다크 모드'"
        @click="toggleTheme"
      >
        <span v-if="isDarkMode">☀</span>
        <span v-else>☾</span>
      </button>
    </footer>
  </aside>
</template>
