<script setup lang="ts">
import { ref, computed, onBeforeUnmount, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
import { useUserStore } from '@/stores/user'
import CoinChip from '@/components/ui/CoinChip.vue'
import AppIcon from '@/components/ui/AppIcon.vue'
import ModalDialog from '@/components/ui/ModalDialog.vue'
import { formatUserName } from '@/utils/formatUserName'
import type { UserRole } from '@/types'

const auth = useAuthStore()
const userStore = useUserStore()
const router = useRouter()
const isProfileMenuOpen = ref(false)
const isCoinDialogOpen = ref(false)
const isLevelDialogOpen = ref(false)
const isSlotsDialogOpen = ref(false)
const profileMenuRef = ref<HTMLElement | null>(null)

const unreadCount = computed(() => userStore.unreadCount())
const showStudentChips = computed(() => auth.user?.activeRole === 'student')
const enrollmentSlotText = computed(() => {
  const user = auth.user
  if (!user || user.activeRole !== 'student') return ''
  if (typeof user.enrollmentSlotLimit !== 'number') return ''
  return `${user.activeEnrollments ?? 0}/${user.enrollmentSlotLimit}`
})
const roleLabels: Record<UserRole, string> = {
  student: 'Студент',
  teacher: 'Преподаватель',
  admin: 'Администратор',
}
const roleTargets: Record<UserRole, string> = {
  student: '/',
  teacher: '/teacher',
  admin: '/admin',
}

const roleButtons = computed(() => {
  if (!auth.user) return []

  return auth.user.roles
    .filter((role) => role !== auth.user?.activeRole)
    .map((role) => ({
      role,
      label: roleLabels[role],
      to: roleTargets[role],
    }))
})

function closeProfileMenu() {
  isProfileMenuOpen.value = false
}

function closeCoinDialog() {
  isCoinDialogOpen.value = false
}

function closeLevelDialog() {
  isLevelDialogOpen.value = false
}

function closeSlotsDialog() {
  isSlotsDialogOpen.value = false
}

function toggleProfileMenu() {
  closeCoinDialog()
  closeLevelDialog()
  closeSlotsDialog()
  isProfileMenuOpen.value = !isProfileMenuOpen.value
}

function openCoinDialog() {
  closeProfileMenu()
  isCoinDialogOpen.value = true
}

function openLevelDialog() {
  closeProfileMenu()
  closeCoinDialog()
  closeSlotsDialog()
  isLevelDialogOpen.value = true
}

function openSlotsDialog() {
  closeProfileMenu()
  closeCoinDialog()
  closeLevelDialog()
  isSlotsDialogOpen.value = true
}

function openMyLecturesFromSlotsDialog() {
  closeSlotsDialog()
  router.push('/my-lectures')
}

function openProfile() {
  closeProfileMenu()
  router.push('/profile')
}

function switchToRole(role: UserRole, to: string) {
  if (auth.setActiveRole(role)) {
    closeProfileMenu()
    router.push(to)
  }
}

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

function handleDocumentPointerDown(event: PointerEvent) {
  const target = event.target
  if (!(target instanceof Node)) return

  if (!profileMenuRef.value?.contains(target)) closeProfileMenu()
}

onMounted(() => {
  document.addEventListener('pointerdown', handleDocumentPointerDown)
  if (auth.user?.roles.includes('student')) void userStore.fetchStats().catch(() => undefined)
})

onBeforeUnmount(() => {
  document.removeEventListener('pointerdown', handleDocumentPointerDown)
})
</script>

<template>
  <header class="topbar">
    <div class="topbar-brand">
      <span class="brand-name">UniVerse</span>
    </div>

    <div class="topbar-center"></div>

    <div class="topbar-right">
      <CoinChip
        v-if="auth.user && showStudentChips"
        :amount="auth.user.coins"
        aria-haspopup="dialog"
        @click="openCoinDialog"
      />

      <button
        v-if="auth.user && showStudentChips"
        class="level-chip"
        type="button"
        aria-haspopup="dialog"
        @click="openLevelDialog"
      >
        <AppIcon class="level-icon" icon="star" :size="15" />
        <span class="level-label">Ур.</span>
        <span class="level-value">{{ auth.user.level }}</span>
      </button>

      <button
        v-if="enrollmentSlotText"
        class="slot-chip"
        type="button"
        aria-haspopup="dialog"
        title="Занятые слоты записи / доступные слоты"
        @click="openSlotsDialog"
      >
        <AppIcon class="slot-icon" icon="calendar" :size="15" />
        <span class="slot-value">{{ enrollmentSlotText }}</span>
      </button>

      <button
        class="notif-btn"
        type="button"
        aria-label="Уведомления"
        @click="$router.push('/notifications')"
      >
        <AppIcon icon="bell" :size="18" />
        <span class="notif-dot" v-if="auth.user && unreadCount > 0">
          {{ unreadCount }}
        </span>
      </button>

      <div ref="profileMenuRef" class="profile-menu">
        <button
          class="avatar"
          type="button"
          :aria-expanded="isProfileMenuOpen"
          aria-haspopup="menu"
          @click="toggleProfileMenu"
          @keydown.esc.prevent="closeProfileMenu"
        >
          <AppIcon class="avatar-icon" icon="user" :size="18" />
          <span class="avatar-name" v-if="auth.user">{{ formatUserName(auth.user.name) }}</span>
        </button>

        <div
          v-if="isProfileMenuOpen"
          class="profile-dropdown"
          role="menu"
          @keydown.esc.prevent="closeProfileMenu"
        >
          <button class="profile-menu-item" type="button" role="menuitem" @click="openProfile">
            <AppIcon icon="user" :size="16" />
            Профиль
          </button>

          <div class="profile-menu-section" v-if="roleButtons.length">
            <span class="profile-menu-caption">Сменить роль</span>
            <button
              v-for="item in roleButtons"
              :key="item.role"
              class="profile-menu-item"
              type="button"
              role="menuitem"
              @click="switchToRole(item.role, item.to)"
            >
              <AppIcon
                :icon="
                  item.role === 'admin' ? 'shield' : item.role === 'teacher' ? 'chart-bar' : 'home'
                "
                :size="16"
              />
              {{ item.label }}
            </button>
          </div>

          <button class="profile-menu-item danger" type="button" role="menuitem" @click="logout">
            <AppIcon icon="logout" :size="16" />
            Выйти
          </button>
        </div>
      </div>
    </div>

    <ModalDialog v-model="isCoinDialogOpen" title="Монеты UniVerse" icon="coin" size="sm">
      <p>
        В будущем монеты можно будет использовать во внутреннем магазине. Сейчас магазин еще не
        запущен, поэтому монеты просто копятся на вашем балансе.
      </p>
      <template #footer>
        <button class="btn-primary" type="button" @click="closeCoinDialog">ОК</button>
      </template>
    </ModalDialog>

    <ModalDialog v-model="isLevelDialogOpen" title="Уровень студента" icon="star" size="sm">
      <p>
        Уровень показывает ваш прогресс в UniVerse. Он растет вместе с активностью: посещением
        открытых лекций, полезными отзывами и достижениями.
      </p>
      <template #footer>
        <button class="btn-primary" type="button" @click="closeLevelDialog">Понятно</button>
      </template>
    </ModalDialog>

    <ModalDialog v-model="isSlotsDialogOpen" title="Слоты записи" icon="calendar" size="sm">
      <p>
        Слоты показывают, сколько открытых лекций уже занято в вашем текущем лимите. Когда лимит
        заполнен, освободите слот отменой записи или повышайте уровень, чтобы получить больше
        возможностей.
      </p>
      <template #footer>
        <button class="btn-secondary" type="button" @click="openMyLecturesFromSlotsDialog">
          Мои записи
        </button>
        <button class="btn-primary" type="button" @click="closeSlotsDialog">Понятно</button>
      </template>
    </ModalDialog>
  </header>
</template>

<style scoped>
.topbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: var(--topbar-height);
  background: var(--color-white-a80);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--color-border-glass);
  box-shadow: 0 2px 20px var(--color-black-a06);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  z-index: 100;
  gap: 12px;
}
.topbar-brand {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
  cursor: pointer;
}
.brand-name {
  font-size: 20px;
  font-weight: 800;
  background: var(--gradient-brand);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}
.topbar-center {
  flex: 1;
  max-width: 400px;
}
.topbar-right {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}
.level-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 28px;
  padding: 0 11px;
  border: 1px solid var(--color-primary-a20);
  border-radius: 20px;
  background: var(--color-primary-a10);
  color: var(--color-primary-dark);
  cursor: pointer;
  font: inherit;
  white-space: nowrap;
  transition:
    background-color 0.18s ease,
    border-color 0.18s ease,
    box-shadow 0.18s ease;
}
.level-icon {
  color: var(--color-primary);
}
.level-label {
  color: var(--color-text-secondary);
  font-size: 12px;
  font-weight: 700;
}
.level-value {
  color: var(--color-primary-dark);
  font-size: 14px;
  font-weight: 800;
}
.slot-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 28px;
  padding: 0 10px;
  border: 1px solid var(--color-primary-a20);
  border-radius: 20px;
  background: var(--color-primary-a10);
  color: var(--color-success-text);
  cursor: pointer;
  font: inherit;
  white-space: nowrap;
  transition:
    background-color 0.18s ease,
    border-color 0.18s ease,
    box-shadow 0.18s ease;
}
.level-chip:hover,
.slot-chip:hover {
  background: var(--color-primary-a18);
  border-color: var(--color-primary-a40);
}
.level-chip:focus-visible,
.slot-chip:focus-visible {
  outline: 2px solid var(--color-primary-a45);
  outline-offset: 2px;
  box-shadow: 0 0 0 3px var(--color-primary-a12);
}
.slot-icon {
  color: var(--color-primary);
}
.slot-value {
  font-size: 13px;
  font-weight: 800;
}
.notif-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  background: transparent;
  border: 0;
  color: var(--color-text-secondary);
  cursor: pointer;
  padding: 0;
  border-radius: 50%;
  transition: background 0.2s;
}
.notif-btn:hover {
  background: var(--color-black-a05);
}
.notif-dot {
  position: absolute;
  top: -2px;
  right: -2px;
  background: var(--color-error);
  color: var(--color-white);
  font-size: 9px;
  font-weight: 700;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.profile-menu {
  position: relative;
}
.avatar {
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  padding: 5px 10px;
  border-radius: 20px;
  border: 1px solid var(--color-border-glass);
  background: var(--color-white-a50);
  color: var(--color-text);
  font: inherit;
  transition: all 0.2s;
}
.avatar:hover,
.avatar[aria-expanded='true'] {
  border-color: var(--color-primary-a50);
  background: var(--color-white-a80);
  box-shadow: 0 0 0 3px var(--color-primary-a12);
}
.avatar:focus-visible,
.profile-menu-item:focus-visible {
  outline: 2px solid var(--color-primary-a45);
  outline-offset: 2px;
}
.avatar-icon {
  color: var(--color-text-secondary);
}
.avatar-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text);
}
.profile-dropdown {
  position: fixed;
  top: calc(var(--topbar-height) + 10px);
  right: 20px;
  min-width: 220px;
  padding: 8px;
  border: 1px solid var(--color-border-glass);
  border-radius: var(--radius-sm);
  background: var(--color-white-a96);
  box-shadow: 0 18px 38px var(--color-slate-900-a14);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  display: flex;
  flex-direction: column;
  gap: 4px;
  z-index: 120;
}
.profile-menu-section {
  border-top: 1px solid var(--color-slate-900-a08);
  border-bottom: 1px solid var(--color-slate-900-a08);
  margin: 4px 0;
  padding: 6px 0;
}
.profile-menu-caption {
  display: block;
  padding: 3px 10px 5px;
  color: var(--color-text-secondary);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
}
.profile-menu-item {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 10px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text);
  cursor: pointer;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  text-align: left;
  transition:
    background 0.2s,
    color 0.2s;
}
.profile-menu-item:hover {
  background: var(--color-primary-a10);
  color: var(--color-primary-dark);
}
.profile-menu-item.danger {
  color: var(--color-danger-text);
}
.profile-menu-item.danger:hover {
  background: var(--color-error-a10);
  color: var(--color-danger-text);
}

@media (max-width: 640px) {
  .topbar-center {
    display: none;
  }
  .brand-name {
    display: none;
  }
  .avatar-name {
    display: none;
  }
}
</style>
