<script setup lang="ts">
import { computed, type Component } from 'vue'
import { RouterLink, useRouter } from 'vue-router'
import {
  Activity,
  AlertTriangle,
  Bell,
  BookOpen,
  Bot,
  Boxes,
  Calendar,
  ChevronLeft,
  Command,
  FileText,
  LayoutDashboard,
  ListTodo,
  Settings,
  Shield,
  SlidersHorizontal,
  Workflow,
} from '@lucide/vue'
import { useOpenClawOverviewQuery } from '../../api/openclawRuntime'
import { useNotificationSnapshot } from '../../api/notifications'
import { useAuthStore } from '../../stores/auth'

defineProps<{
  mobileOpen?: boolean
}>()

defineEmits<{
  close: []
}>()
import NavGroup from './NavGroup.vue'
import { initials } from '../../utils/format'

const auth = useAuthStore()
const router = useRouter()
const overviewQuery = useOpenClawOverviewQuery()
const { query: notificationQuery } = useNotificationSnapshot({ limit: 1 })

interface NavItemDef {
  icon: Component
  label: string
  route: string
  count?: string
  active?: boolean
}

interface NavGroupDef {
  group: string
  items: NavItemDef[]
}

const navigation: NavGroupDef[] = [
  {
    group: 'Operations',
    items: [
      { icon: LayoutDashboard, label: 'Dashboard', route: '/dashboard' },
      { icon: Bot, label: 'Agenten', route: '/agents' },
      { icon: Boxes, label: 'Projects', route: '/projects' },
      { icon: ListTodo, label: 'Task Board', route: '/tasks' },
      { icon: Workflow, label: 'Run Control', route: '/runs' },
    ],
  },
  {
    group: 'Knowledge',
    items: [
      { icon: FileText, label: 'Memory', route: '/memory' },
      { icon: BookOpen, label: 'Docs & .md', route: '/docs' },
    ],
  },
  {
    group: 'Infrastructure',
    items: [
      { icon: SlidersHorizontal, label: 'Modelle', route: '/models' },
      { icon: Activity, label: 'Activity Log', route: '/activity' },
      { icon: Calendar, label: 'Calendar', route: '/calendar' },
    ],
  },
  {
    group: 'Governance',
    items: [
      { icon: Shield, label: 'Security', route: '/security' },
      { icon: AlertTriangle, label: 'Incidents', route: '/incidents' },
      { icon: Bell, label: 'Notifications', route: '/notifications' },
    ],
  },
]

const ownerInitials = computed(() =>
  auth.user?.displayName ? initials(auth.user.displayName) : 'OW'
)

async function logout() {
  await auth.logout()
  await router.replace('/login')
}

/**
 * Counts come from the canonical Vue Query server-state boundary. This
 * presentation island does not recreate a second agent or task store.
 */
const dynamicNavigation = computed<NavGroupDef[]>(() => {
  const overview = overviewQuery.data.value
  const activeTasks = overview?.tasks.items.filter(task =>
    !['completed', 'done', 'failed', 'cancelled'].includes(
      task.status.toLocaleLowerCase(),
    ),
  ).length ?? 0
  const unread = notificationQuery.data.value?.unreadCount

  return navigation.map(group => ({
    ...group,
    items: group.items.map(item => {
      let dynamicCount: string | undefined

      switch (item.label) {
        case 'Agenten':
          dynamicCount = overview ? String(overview.agents.items.length) : undefined
          break
        case 'Task Board':
          dynamicCount = overview ? String(activeTasks) : undefined
          break
        case 'Notifications':
          dynamicCount = unread === undefined ? undefined : String(unread)
          break
      }

      return {
        ...item,
        count: dynamicCount ?? item.count,
      }
    }),
  }))
})
</script>

<template>
  <aside :class="['sidebar', { open: mobileOpen }]" aria-label="Nexus navigation">
    <button
      type="button"
      class="sidebar-close"
      aria-label="Close navigation"
      @click="$emit('close')"
    >
      <ChevronLeft :size="18" aria-hidden="true" />
    </button>
    <!-- Brand -->
    <div class="side-top">
      <div class="brand-mark"><Command :size="20" aria-hidden="true" /></div>
      <div>
        <div class="brand-name">NEXUS</div>
        <div class="brand-sub">Mission Control</div>
      </div>
    </div>

    <!-- Navigation -->
    <nav class="nav" aria-label="Primary">
      <NavGroup
        v-for="(group, idx) in dynamicNavigation"
        :key="idx"
        :label="group.group"
        :items="group.items"
      />
    </nav>

    <!-- Footer -->
    <div class="side-foot">
      <RouterLink to="/settings" class="settings-link" active-class="active">
        <Settings :size="17" aria-hidden="true" />
        <span>Settings</span>
      </RouterLink>
      <div class="owner-row">
        <div class="avatar">{{ ownerInitials }}</div>
        <div class="owner-info">
          <div class="owner-name">{{ auth.user?.displayName ?? 'Owner' }}</div>
          <div class="owner-role">{{ auth.user?.role ?? 'Owner' }}</div>
        </div>
      </div>
    </div>
  </aside>
</template>

<style scoped>
.sidebar {
  width: 248px;
  flex: 0 0 248px;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--space-2) 92%, transparent),
    color-mix(in srgb, var(--space-0) 92%, transparent)
  );
  border-right: 1px solid var(--line);
  backdrop-filter: blur(14px);
  padding: 0;
  position: relative;
  z-index: 2;
}

.side-top {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 18px 18px 16px;
}

.brand-mark {
  width: 38px;
  height: 38px;
  border-radius: 11px;
  display: grid;
  place-items: center;
  background: var(--grad);
  box-shadow: var(--glow-purple);
  flex: 0 0 auto;
}

.brand-mark :deep(svg) {
  width: 20px;
  height: 20px;
  color: var(--tx-on-accent);
}

.brand-name {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 700;
  font-size: 17px;
  letter-spacing: .14em;
  line-height: 1;
}

.brand-sub {
  font-size: 10.5px;
  color: var(--tx-3);
  letter-spacing: .05em;
  margin-top: 3px;
}

.nav {
  flex: 1;
  overflow-y: auto;
  padding: 6px 12px 12px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.side-foot {
  padding: 12px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
}

.settings-link {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  min-height: 38px;
  padding: 9px 11px;
  border: 1px solid transparent;
  border-radius: 10px;
  color: var(--tx-2);
  font-family: var(--font-body);
  font-size: 13.5px;
  font-weight: 500;
  text-decoration: none;
  transition: background .16s, border-color .16s, color .16s;
}

.settings-link:hover {
  background: color-mix(in srgb, var(--a-mid) 6%, transparent);
  color: var(--tx);
}

.settings-link.active {
  border-color: var(--line-2);
  background: var(--grad-soft);
  color: var(--tx);
}

.settings-link.active::before {
  content: '';
  position: absolute;
  left: -13px;
  width: 3px;
  height: 22px;
  border-radius: 0 999px 999px 0;
  background: var(--grad);
  box-shadow: var(--glow-purple);
}

.owner-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 0 0;
}

.sidebar-close {
  display: none;
}

@media (max-width: 767px) {
  .sidebar {
    position: fixed;
    left: 0;
    top: 0;
    z-index: 100;
    height: 100vh;
    width: 280px;
    transform: translateX(-100%);
    transition: transform 0.25s ease;
  }

  .sidebar.open {
    transform: translateX(0);
  }

  .sidebar-close {
    display: flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    top: 18px;
    right: 12px;
    width: 30px;
    height: 30px;
    border-radius: 8px;
    border: none;
    background: transparent;
    color: var(--tx-2);
    cursor: pointer;
    z-index: 1;
  }

  .sidebar-close:hover {
    background: color-mix(in srgb, var(--a-mid) 10%, transparent);
    color: var(--tx);
  }

  .sidebar-close :deep(svg) {
    width: 18px;
    height: 18px;
  }
}

.avatar {
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: var(--grad-soft);
  border: 1px solid var(--line-2);
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: 13px;
  color: var(--tx);
  flex-shrink: 0;
}

.owner-info {
  min-width: 0;
}

.owner-name {
  font-size: 12px;
  font-weight: 600;
  color: var(--tx);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.owner-role {
  font-size: 10px;
  color: var(--tx-3);
  margin-top: 1px;
  text-transform: capitalize;
}
</style>
