<template>
    <div ref="noticeRef" class="notice" @click="toggleDropdown" @mouseenter="openDropdown" @mouseleave="closeDropdown"
        v-click-outside="forceCloseDropdown">
        <div class="notice-trigger">
            <img src="@/assets/imgs/notice.svg" alt="notice" />
            <span v-if="unreadCount > 0" class="notice-badge">{{ unreadCount > 99 ? '99+' : unreadCount }}</span>
        </div>

        <!-- 下拉通知列表 -->
        <Teleport to="body">
            <div class="notice-dropdown" :class="{ 'show': dropdownVisible }" :style="dropdownStyle"
                v-if="dropdownVisible" @mouseenter="openDropdown" @mouseleave="closeDropdown">
                <div class="notice-header">
                    <h3>通知</h3>
                    <span class="notice-count" v-if="unreadCount > 0">{{ unreadCount }}条未读</span>
                </div>
                <div class="notice-list" v-loading="loading">
                    <div v-if="noticeList.length === 0 && !loading" class="notice-empty">
                        暂无通知
                    </div>
                    <div v-for="item in noticeList" :key="item.messageID" class="notice-item" :class="{ 'unread': !item.isRead }"
                        @click="handleNoticeClick(item)">
                        <div class="notice-content">
                            <div class="notice-title">{{ item.title }}</div>
                            <div class="notice-time">{{ formatTime(item.actualSendTime || item.createTime) }}</div>
                        </div>
                    </div>
                </div>
                <div class="notice-footer" v-if="noticeList.length > 0">
                    <span class="view-all" @click="viewAll">查看全部</span>
                </div>
            </div>
        </Teleport>
    </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import { ElMessage } from 'element-plus';
import { messageApi } from '@/apis/message';
import type { MessageUserVO, PageParam } from '@/types';

// 状态
const dropdownVisible = ref(false);
const noticeRef = ref<HTMLElement | null>(null);
const dropdownPosition = ref({ top: 0, left: 0 });
const closeTimer = ref<number | null>(null);
const loading = ref(false);
const lastLoadTime = ref(0); // 上次加载时间戳
const hasLoadedOnce = ref(false); // 是否已经加载过一次

const router = useRouter();

// 通知列表
const noticeList = ref<MessageUserVO[]>([]);

// 未读数量
const unreadCount = ref(0);

// 下拉菜单样式
const dropdownStyle = computed(() => {
    return {
        position: 'fixed' as const,
        top: `${dropdownPosition.value.top}px`,
        left: `${dropdownPosition.value.left}px`,
        width: '320px',
    };
});

// 加载消息列表
async function loadMessages(force = false) {
    // 如果正在加载，直接返回
    if (loading.value) return;
    
    // 如果不是强制刷新，且已经加载过，且距离上次加载时间少于2秒，则不重复加载
    const now = Date.now();
    if (!force && hasLoadedOnce.value && (now - lastLoadTime.value) < 2000) {
        return;
    }
    
    loading.value = true;
    lastLoadTime.value = now;
    try {
        const pageParam: PageParam = {
            pageNumber: 1,
            pageSize: 10,
            orderBy: 'actualSendTime',
            orderDirection: 'desc'
        };
        
        const result = await messageApi.getMyMessages(pageParam);
        if (result.success) {
            noticeList.value = result.dataList || [];
            hasLoadedOnce.value = true;
        } else {
            ElMessage.error(result.message || '加载失败');
        }
    } catch (error) {
        console.error('加载消息列表失败:', error);
        ElMessage.error('加载失败');
    } finally {
        loading.value = false;
    }
}

// 加载未读数量
async function loadUnreadCount() {
    try {
        const result = await messageApi.getUnreadCount();
        if (result.success) {
            unreadCount.value = result.data || 0;
        }
    } catch (error) {
        console.error('加载未读数量失败:', error);
    }
}

// 方法
function openDropdown() {
    if (closeTimer.value) {
        clearTimeout(closeTimer.value);
        closeTimer.value = null;
    }

    // 如果已经打开，不重复处理（避免鼠标移动时重复触发）
    if (dropdownVisible.value) {
        return;
    }

    dropdownVisible.value = true;
    
    // 计算下拉菜单位置（居中显示）
    if (noticeRef.value) {
        const rect = noticeRef.value.getBoundingClientRect();
        const dropdownWidth = 320;
        dropdownPosition.value = {
            top: rect.bottom + 4,
            left: rect.left + rect.width / 2 - dropdownWidth / 2, // 居中
        };
    }
    
    // 每次打开下拉菜单时都加载数据（因为 hasLoadedOnce 在关闭时会被重置）
    loadMessages();
    loadUnreadCount();
}

function toggleDropdown() {
    if (dropdownVisible.value) {
        forceCloseDropdown();
    } else {
        openDropdown();
    }
}

function closeDropdown() {
    closeTimer.value = setTimeout(() => {
        dropdownVisible.value = false;
        closeTimer.value = null;
        // 关闭时重置加载标志，下次打开时会重新加载
        hasLoadedOnce.value = false;
    }, 200);
}

function forceCloseDropdown() {
    if (closeTimer.value) {
        clearTimeout(closeTimer.value);
        closeTimer.value = null;
    }
    dropdownVisible.value = false;
    // 关闭时重置加载标志，下次打开时会重新加载
    hasLoadedOnce.value = false;
}

async function handleNoticeClick(item: MessageUserVO) {
    // 如果未读，标记为已读
    if (!item.isRead && item.messageID) {
        try {
            await messageApi.markAsRead(item.messageID);
            item.isRead = true;
            // 更新未读数量
            if (unreadCount.value > 0) {
                unreadCount.value--;
            }
        } catch (error) {
            console.error('标记已读失败:', error);
        }
    }
    
    // 跳转到消息详情页
    if (item.messageID) {
        router.push(`/user/message/detail/${item.messageID}`);
    }
    forceCloseDropdown();
}

function viewAll() {
    router.push('/user/message');
    forceCloseDropdown();
}

function formatTime(time?: string | number): string {
    if (!time) return '';
    const date = new Date(time);
    const now = new Date();
    const diff = now.getTime() - date.getTime();
    const minutes = Math.floor(diff / 60000);
    const hours = Math.floor(diff / 3600000);
    const days = Math.floor(diff / 86400000);

    if (minutes < 1) return '刚刚';
    if (minutes < 60) return `${minutes}分钟前`;
    if (hours < 24) return `${hours}小时前`;
    if (days < 7) return `${days}天前`;

    return date.toLocaleDateString('zh-CN', { month: 'short', day: 'numeric' });
}

// 点击外部关闭指令
const vClickOutside = {
    mounted(el: any, binding: any) {
        el._clickOutside = (event: Event) => {
            if (!(el === event.target || el.contains(event.target as Node))) {
                binding.value();
            }
        };
        document.addEventListener('click', el._clickOutside);
    },
    unmounted(el: any) {
        document.removeEventListener('click', el._clickOutside);
        delete el._clickOutside;
    }
};

onMounted(() => {
    loadUnreadCount();
});
</script>

<style scoped lang="scss">
.notice {
    position: relative;
    cursor: pointer;
    user-select: none;
}

.notice-trigger {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 8px;
    border-radius: 4px;
    transition: background-color 0.2s ease;

    &:hover {
        background-color: #f5f5f5;
    }

    img {
        width: 20px;
        height: 20px;
    }

    .notice-badge {
        position: absolute;
        top: 4px;
        right: 4px;
        min-width: 16px;
        height: 16px;
        padding: 0 4px;
        background: #ff4d4f;
        color: white;
        border-radius: 8px;
        font-size: 11px;
        line-height: 16px;
        text-align: center;
        font-weight: 500;
    }
}

.notice-dropdown {
    background: white;
    border-radius: 4px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
    border: 1px solid #e8e8e8;
    z-index: 10000;
    overflow: hidden;
    opacity: 0;
    transform: scaleY(0);
    transform-origin: top center;
    transition: opacity 0.2s ease, transform 0.2s ease;
    max-height: 400px;
    display: flex;
    flex-direction: column;

    &.show {
        opacity: 1;
        transform: scaleY(1);
    }
}

.notice-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 16px;
    border-bottom: 1px solid #e8e8e8;

    h3 {
        margin: 0;
        font-size: 16px;
        font-weight: 600;
        color: #333;
    }

    .notice-count {
        font-size: 12px;
        color: #ff4d4f;
    }
}

.notice-list {
    flex: 1;
    overflow-y: auto;
    max-height: 300px;
}

.notice-empty {
    padding: 40px 20px;
    text-align: center;
    color: #999;
    font-size: 14px;
}

.notice-item {
    padding: 12px 16px;
    border-bottom: 1px solid #f0f0f0;
    cursor: pointer;
    transition: background-color 0.2s ease;

    &:hover {
        background-color: #f5f5f5;
    }

    &.unread {
        background-color: #f0f7ff;

        .notice-title {
            font-weight: 600;
        }
    }

    &:last-child {
        border-bottom: none;
    }
}

.notice-content {
    .notice-title {
        font-size: 14px;
        color: #333;
        line-height: 1.5;
        margin-bottom: 4px;
        overflow: hidden;
        text-overflow: ellipsis;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        line-clamp: 2;
        -webkit-box-orient: vertical;
    }

    .notice-time {
        font-size: 12px;
        color: #999;
    }
}

.notice-footer {
    padding: 8px 16px;
    border-top: 1px solid #e8e8e8;
    text-align: center;

    .view-all {
        font-size: 14px;
        color: #C62828;
        cursor: pointer;

        &:hover {
            text-decoration: underline;
        }
    }
}
</style>