<script setup lang="ts">
/**
 * Sprint 4 Phase B/1 (audit O-refactor-04 хвост): topbar выделен из AppLayout.
 * Crumb + search-trigger (заглушка ⌘K) + bell с notifications dropdown + user-chip menu.
 * Stores: auth + notifications (используются напрямую, без prop-drilling).
 */
import { computed } from 'vue';
import { useRouter } from 'vue-router';
import { useAuthStore } from '../../stores/auth';
import { useNotificationsStore } from '../../stores/notifications';
import { useCommandPalette } from '../../composables/useCommandPalette';

defineProps<{
    pageTitle: string;
}>();

const emit = defineEmits<{
    'toggle-drawer': [];
}>();

const auth = useAuthStore();
const notifications = useNotificationsStore();
const router = useRouter();
const { openPalette } = useCommandPalette();

const unreadDisplay = computed(() => {
    if (notifications.unreadCount === 0) return '';
    if (notifications.unreadCount > 99) return '99+';
    return String(notifications.unreadCount);
});

function eventIcon(event: string): string {
    const map: Record<string, string> = {
        new_lead: 'mdi-account-plus-outline',
        low_balance: 'mdi-wallet-outline',
        zero_balance: 'mdi-alert-circle-outline',
        topup_success: 'mdi-cash-plus',
        invoice_paid: 'mdi-receipt-text-check-outline',
        new_device_login: 'mdi-shield-account-outline',
        marketing: 'mdi-bullhorn-outline',
        project_rule: 'mdi-clock-edit-outline',
    };
    return map[event] ?? 'mdi-bell-outline';
}

function formatRelative(iso: string | null): string {
    if (!iso) return '';
    const ms = Date.now() - new Date(iso).getTime();
    const min = Math.floor(ms / 60_000);
    if (min < 1) return 'только что';
    if (min < 60) return `${min} мин назад`;
    const hr = Math.floor(min / 60);
    if (hr < 24) return `${hr} ч назад`;
    const days = Math.floor(hr / 24);
    return `${days} д назад`;
}

async function handleNotificationClick(id: number, dealId: number | null): Promise<void> {
    await notifications.markRead(id);
    if (dealId !== null) {
        // Audit F3: deep-link на конкретный drawer через ?openId=.
        await router.push({ path: '/deals', query: { openId: dealId } });
    }
}

const userInitials = computed(() => {
    const u = auth.user;
    if (!u) return '?';
    const first = u.first_name?.[0] ?? '';
    const last = u.last_name?.[0] ?? '';
    const initials = (first + last).toUpperCase();
    return initials || u.email.slice(0, 2).toUpperCase();
});

const userShortName = computed(() => {
    const u = auth.user;
    if (!u) return 'Гость';
    if (u.first_name && u.last_name) {
        return `${u.first_name} ${u.last_name[0]}.`;
    }
    return u.first_name || u.email;
});

async function handleLogout(): Promise<void> {
    await auth.logout();
    await router.push('/login');
}
</script>

<template>
    <v-app-bar :elevation="0" color="surface" class="app-topbar" :height="56">
        <v-app-bar-nav-icon class="d-md-none" aria-label="Открыть меню навигации" @click="emit('toggle-drawer')" />

        <div class="crumb">
            <strong>{{ pageTitle }}</strong>
        </div>

        <v-spacer />

        <v-btn
            variant="outlined"
            size="small"
            prepend-icon="mdi-magnify"
            class="searchbar mr-2"
            data-testid="topbar-search-btn"
            @click="openPalette"
        >
            Поиск
            <template #append>
                <kbd class="search-kbd">⌘K</kbd>
            </template>
        </v-btn>

        <v-menu
            offset="8"
            :close-on-content-click="false"
            location="bottom end"
        >
            <template #activator="{ props: bellProps }">
                <v-btn
                    v-bind="bellProps"
                    icon
                    size="small"
                    variant="text"
                    aria-label="Уведомления"
                    data-testid="notifications-btn"
                >
                    <v-icon>mdi-bell-outline</v-icon>
                    <span
                        v-if="notifications.unreadCount > 0"
                        class="notification-pip"
                        data-testid="notifications-pip"
                        aria-hidden="true"
                    >
                        {{ unreadDisplay }}
                    </span>
                </v-btn>
            </template>
            <v-card class="notifications-menu" min-width="360" max-width="420" elevation="3">
                <div class="notifications-header">
                    <strong>Уведомления</strong>
                    <v-btn
                        v-if="notifications.unreadCount > 0"
                        size="x-small"
                        variant="text"
                        data-testid="mark-all-read-btn"
                        @click="notifications.markAllRead()"
                    >
                        Прочитать все
                    </v-btn>
                </div>
                <v-divider />
                <div v-if="notifications.items.length === 0" class="notifications-empty">
                    <v-icon size="32" class="mb-2">mdi-bell-off-outline</v-icon>
                    <div>Нет уведомлений</div>
                </div>
                <v-list v-else density="compact" class="notifications-list" data-testid="notifications-list">
                    <v-list-item
                        v-for="item in notifications.sortedItems.slice(0, 10)"
                        :key="item.id"
                        :class="{ 'notification-unread': item.read_at === null }"
                        data-testid="notification-item"
                        @click="handleNotificationClick(item.id, item.deal_id)"
                    >
                        <template #prepend>
                            <v-icon :icon="eventIcon(item.event)" size="20" />
                        </template>
                        <v-list-item-title class="text-body-2">{{ item.title }}</v-list-item-title>
                        <v-list-item-subtitle class="text-caption">
                            {{ item.body }}
                        </v-list-item-subtitle>
                        <template #append>
                            <span class="notification-time">{{ formatRelative(item.created_at) }}</span>
                        </template>
                    </v-list-item>
                </v-list>
            </v-card>
        </v-menu>

        <v-menu offset="8">
            <template #activator="{ props }">
                <v-btn v-bind="props" variant="text" size="small" class="user-chip ml-2" aria-label="Меню пользователя">
                    <v-avatar size="28" color="primary" class="mr-2">
                        <span class="text-caption">{{ userInitials }}</span>
                    </v-avatar>
                    <span class="text-body-2">{{ userShortName }}</span>
                </v-btn>
            </template>
            <v-list density="compact" min-width="200">
                <v-list-item v-if="auth.user" :title="auth.user.email" disabled />
                <v-divider v-if="auth.user" />
                <v-list-item :to="'/settings'" prepend-icon="mdi-cog-outline" title="Настройки" />
                <v-list-item prepend-icon="mdi-logout" title="Выйти" @click="handleLogout" />
            </v-list>
        </v-menu>
    </v-app-bar>
</template>

<style scoped>
.app-topbar {
    background: linear-gradient(180deg, var(--liderra-noir) 0%, #04261e 100%) !important;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08) !important;
    color: #e8e2d4 !important;
}
.app-topbar :deep(.v-toolbar__content) {
    padding-left: 240px;
    color: #e8e2d4;
}
.app-topbar :deep(.v-icon) {
    color: #b8b0a0;
}
.crumb {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 14px;
    margin-left: 8px;
    color: #e8e2d4;
}
.crumb strong {
    color: var(--liderra-ivory);
    font-weight: 600;
}
.searchbar {
    text-transform: none;
    color: #b8b0a0 !important;
    border-color: rgba(255, 255, 255, 0.12) !important;
}
.search-kbd {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 10px;
    padding: 1px 5px;
    border: 1px solid rgba(255, 255, 255, 0.16);
    border-radius: 3px;
    background: rgba(255, 255, 255, 0.06);
    color: #9b9484;
    margin-left: 6px;
}
.user-chip :deep(.v-btn__content) {
    color: #e8e2d4;
}
.notification-pip {
    position: absolute;
    top: 4px;
    right: 4px;
    min-width: 16px;
    height: 16px;
    padding: 0 5px;
    border-radius: 8px;
    background: #b94837;
    color: #fff;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-feature-settings: 'tnum';
    font-size: 10px;
    line-height: 16px;
    text-align: center;
    font-weight: 600;
}
.notifications-menu {
    background: #ffffff;
}
.notifications-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
}
.notifications-empty {
    padding: 32px 16px;
    text-align: center;
    color: #66635c;
    font-size: 13px;
}
.notifications-list {
    max-height: 420px;
    overflow-y: auto;
}
.notification-unread {
    background: #f0f8f5;
}
.notification-time {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-feature-settings: 'tnum';
    font-size: 11px;
    color: #66635c;
    white-space: nowrap;
    margin-left: 8px;
}
.user-chip {
    text-transform: none;
}
</style>
