<script setup lang="ts">
const auth = useAuthStore()
const route = useRoute()
const { initMood } = useMood()

const navigationItems = [
  {
    label: 'Documents',
    icon: 'i-lucide-book-open',
    to: '/documents',
  },
  {
    label: 'Decisions',
    icon: 'i-lucide-scale',
    to: '/decisions',
  },
  {
    label: 'Mandats',
    icon: 'i-lucide-user-check',
    to: '/mandates',
  },
  {
    label: 'Protocoles',
    icon: 'i-lucide-settings',
    to: '/protocols',
  },
  {
    label: 'Sanctuaire',
    icon: 'i-lucide-archive',
    to: '/sanctuary',
  },
]

/** Mobile drawer state. */
const mobileMenuOpen = ref(false)

/** Close mobile menu on route change. */
watch(() => route.path, () => {
  mobileMenuOpen.value = false
})

/** WebSocket connection and notifications. */
const ws = useWebSocket()
const { setupWsNotifications } = useNotifications()

onMounted(async () => {
  initMood()
  auth.hydrateFromStorage()
  if (auth.token) {
    try {
      await auth.fetchMe()
    } catch {
      auth.logout()
    }
  }
  ws.connect()
  setupWsNotifications(ws)
})

onUnmounted(() => {
  ws.disconnect()
})

function isActive(to: string) {
  return route.path === to || route.path.startsWith(to + '/')
}
</script>

<template>
  <UApp>
    <OfflineBanner />

    <div
      class="app-shell"
      :style="{
        backgroundColor: 'var(--mood-bg)',
        color: 'var(--mood-text)',
      }"
    >
      <!-- Header -->
      <header class="app-header">
        <div class="app-header__inner">
          <!-- Left: Hamburger (mobile) + Logo -->
          <div class="app-header__left">
            <button
              class="app-header__menu-btn md:hidden"
              aria-label="Ouvrir le menu"
              @click="mobileMenuOpen = true"
            >
              <UIcon name="i-lucide-menu" class="text-xl" />
            </button>
            <NuxtLink to="/" class="app-header__logo">
              <UIcon name="i-lucide-gavel" class="app-header__logo-icon" />
              <span class="app-header__logo-g">ğ</span><span class="app-header__logo-paren">(</span><span class="app-header__logo-word">Decision</span><span class="app-header__logo-paren">)</span>
            </NuxtLink>
          </div>

          <!-- Center: Mood switcher (desktop) -->
          <MoodSwitcher class="hidden sm:flex" />

          <!-- Right: Auth -->
          <div class="app-header__right">
            <template v-if="auth.isAuthenticated">
              <span class="app-header__identity">
                {{ auth.identity?.display_name || auth.identity?.address?.slice(0, 10) + '...' }}
              </span>
              <span
                v-if="auth.identity?.is_smith"
                class="app-header__role app-header__role--smith"
              >
                Forgeron
              </span>
              <span
                v-if="auth.identity?.is_techcomm"
                class="app-header__role app-header__role--tech"
              >
                CoTec
              </span>
              <button
                class="app-header__icon-btn"
                aria-label="Se deconnecter"
                @click="auth.logout()"
              >
                <UIcon name="i-lucide-log-out" />
              </button>
            </template>
            <template v-else>
              <NuxtLink to="/login" class="app-header__connect-btn">
                <UIcon name="i-lucide-log-in" />
                <span>Connexion</span>
              </NuxtLink>
            </template>
          </div>
        </div>
      </header>

      <!-- Mobile navigation drawer -->
      <USlideover
        v-model:open="mobileMenuOpen"
        side="left"
        title="Navigation"
        :ui="{ width: 'max-w-xs' }"
      >
        <template #body>
          <nav class="app-mobile-nav">
            <NuxtLink
              v-for="item in navigationItems"
              :key="item.to"
              :to="item.to"
              class="app-mobile-nav__link"
              :class="{ 'app-mobile-nav__link--active': isActive(item.to) }"
              @click="mobileMenuOpen = false"
            >
              <UIcon :name="item.icon" class="text-lg" />
              <span>{{ item.label }}</span>
            </NuxtLink>
          </nav>
          <!-- Mood switcher in mobile drawer -->
          <div class="app-mobile-mood">
            <span class="app-mobile-mood__label">Ambiance</span>
            <MoodSwitcher />
          </div>
        </template>
      </USlideover>

      <!-- Main content with sidebar -->
      <div class="app-body">
        <!-- Desktop sidebar -->
        <aside class="app-sidebar">
          <nav class="app-sidebar__nav">
            <NuxtLink
              v-for="item in navigationItems"
              :key="item.to"
              :to="item.to"
              class="app-sidebar__link"
              :class="{ 'app-sidebar__link--active': isActive(item.to) }"
            >
              <UIcon :name="item.icon" class="text-lg" />
              <span>{{ item.label }}</span>
            </NuxtLink>
          </nav>
        </aside>

        <!-- Page content -->
        <main class="app-main">
          <ErrorBoundary>
            <NuxtPage />
          </ErrorBoundary>
        </main>
      </div>

      <!-- WebSocket error banner -->
      <Transition name="slide-up">
        <div
          v-if="ws.error.value"
          class="app-ws-banner"
          role="alert"
        >
          <UIcon name="i-lucide-plug-zap" class="text-lg" />
          <span>{{ ws.error.value }}</span>
          <button class="app-ws-banner__btn" @click="ws.disconnect(); ws.connect()">
            Reconnecter
          </button>
        </div>
      </Transition>

      <!-- Footer -->
      <footer class="app-footer">
        <span>ğ(Decision) v0.1.0</span>
        <span class="app-footer__sep">·</span>
        <span>Licence libre</span>
      </footer>
    </div>
  </UApp>
</template>

<style scoped>
/* === Shell === */
.app-shell {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

/* === Header === */
.app-header {
  position: sticky;
  top: 0;
  z-index: 30;
  background: var(--mood-surface);
}

.app-header__inner {
  max-width: 80rem;
  margin: 0 auto;
  padding: 0 1.25rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 3.5rem;
}

.app-header__left {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.app-header__menu-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  background: none;
  color: var(--mood-text-muted);
  cursor: pointer;
  border-radius: 12px;
}
.app-header__menu-btn:hover {
  color: var(--mood-text);
  background: var(--mood-accent-soft);
}

.app-header__logo {
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.app-header__logo-icon {
  font-size: 1.375rem;
  color: var(--mood-accent);
  transform: scaleX(-1);
}

.app-header__logo-g {
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--mood-accent);
  line-height: 1;
  font-style: italic;
}

.app-header__logo-paren {
  font-size: 1.125rem;
  font-weight: 300;
  color: var(--mood-text-muted);
  opacity: 0.5;
}

.app-header__logo-word {
  font-size: 1.125rem;
  font-weight: 700;
  color: var(--mood-text);
}

.app-header__right {
  display: flex;
  align-items: center;
  gap: 0.625rem;
}

.app-header__identity {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--mood-text);
  max-width: 6rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (min-width: 640px) {
  .app-header__identity {
    max-width: 12rem;
  }
}

.app-header__role {
  font-size: 0.75rem;
  font-weight: 700;
  padding: 3px 10px;
  border-radius: 20px;
  display: none;
}

@media (min-width: 640px) {
  .app-header__role {
    display: inline;
  }
}

.app-header__role--smith {
  background: rgba(24, 132, 59, 0.15);
  color: var(--mood-success);
}

.app-header__role--tech {
  background: rgba(24, 86, 168, 0.15);
  color: var(--mood-status-vote, #1856a8);
}

.app-header__icon-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  background: none;
  color: var(--mood-text-muted);
  cursor: pointer;
  border-radius: 12px;
  font-size: 1rem;
}
.app-header__icon-btn:hover {
  color: var(--mood-text);
  background: var(--mood-accent-soft);
}

.app-header__connect-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.5rem 0.875rem;
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--mood-accent-text);
  background: var(--mood-accent);
  border-radius: 24px;
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}

@media (min-width: 640px) {
  .app-header__connect-btn {
    gap: 0.5rem;
    padding: 0.5rem 1.25rem;
    font-size: 0.9375rem;
  }
}
.app-header__connect-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px var(--mood-shadow);
}

/* === Sidebar === */
.app-body {
  display: flex;
  flex: 1;
}

.app-sidebar {
  width: 14rem;
  flex-shrink: 0;
  background: var(--mood-surface);
  display: none;
}

@media (min-width: 768px) {
  .app-sidebar {
    display: block;
  }
}

.app-sidebar__nav {
  position: sticky;
  top: 3.5rem;
  padding: 1rem 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.app-sidebar__link {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.625rem 0.875rem;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--mood-text-muted);
  text-decoration: none;
  border-radius: 12px;
  transition: all 0.12s ease;
}

.app-sidebar__link:hover {
  color: var(--mood-text);
  background: var(--mood-accent-soft);
}

.app-sidebar__link--active {
  color: var(--mood-accent);
  background: var(--mood-accent-soft);
  font-weight: 700;
}

/* === Mobile nav === */
.app-mobile-nav {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 0.75rem;
}

.app-mobile-nav__link {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  padding: 1rem 1.25rem;
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--mood-text-muted);
  text-decoration: none;
  border-radius: 14px;
  min-height: 3rem;
}
.app-mobile-nav__link:hover,
.app-mobile-nav__link:active {
  background: var(--mood-accent-soft);
  color: var(--mood-text);
}
.app-mobile-nav__link--active {
  color: var(--mood-accent);
  background: var(--mood-accent-soft);
  font-weight: 700;
}

.app-mobile-mood {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1.25rem;
  margin-top: 0.5rem;
  border-top: 1px solid var(--mood-accent-soft);
}

.app-mobile-mood__label {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--mood-text-muted);
}

/* === Main === */
.app-main {
  flex: 1;
  min-width: 0;
  padding: 1.5rem 1.25rem;
}

@media (min-width: 640px) {
  .app-main {
    padding: 2rem 1.75rem;
  }
}

@media (min-width: 1024px) {
  .app-main {
    padding: 2rem 2.5rem;
  }
}

/* === WS Banner === */
.app-ws-banner {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.625rem;
  padding: 0.625rem 1rem;
  background: var(--mood-error);
  color: white;
  font-size: 0.875rem;
  font-weight: 600;
}

.app-ws-banner__btn {
  margin-left: 0.5rem;
  padding: 0.375rem 0.75rem;
  background: rgba(255,255,255,0.2);
  border-radius: 20px;
  color: white;
  font-size: 0.8125rem;
  font-weight: 700;
  cursor: pointer;
}
.app-ws-banner__btn:hover {
  background: rgba(255,255,255,0.3);
}

/* === Footer === */
.app-footer {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 1rem;
  font-size: 0.8125rem;
  color: var(--mood-text-muted);
}

.app-footer__sep {
  opacity: 0.3;
}

/* === Transitions === */
.slide-up-enter-active,
.slide-up-leave-active {
  transition: all 0.3s ease;
}
.slide-up-enter-from,
.slide-up-leave-to {
  transform: translateY(100%);
  opacity: 0;
}
</style>
