<template>
    <div class="vpn-server-status">
        <el-row :gutter="20">
            <el-col :span="8">
                <el-card shadow="hover">
                    <template #header>
                        <div class="card-header">
                            <span>服务器列表</span>
                        </div>
                    </template>
                    <div class="server-list">
                        <div
                            v-for="server in serverList"
                            :key="server.server_id"
                            class="server-item"
                            :class="{ active: selectedServer?.server_id === server.server_id }"
                            @click="selectServer(server)"
                        >
                            <div class="server-info">
                                <div class="server-name">
                                    <span class="status-indicator" :class="{ 'online': isServerOnline(server) }"></span>
                                    {{ server.name }}
                                </div>
                                <div class="server-ip">{{ server.server_ip }}</div>
                            </div>
                        </div>
                        <el-empty v-if="serverList.length === 0" description="暂无服务器" />
                    </div>
                </el-card>
            </el-col>

            <el-col :span="16">
                <el-card shadow="hover" v-if="selectedServer && selectedServer.vpn_status">
                    <template #header>
                        <div class="card-header">
                            <span>服务器状态</span>
                            <el-tag :type="getStatusType(selectedServer.vpn_status.status)" size="small">
                                {{ getStatusText(selectedServer.vpn_status.status) }}
                            </el-tag>
                        </div>
                    </template>

                    <el-descriptions :column="2" border>
                        <el-descriptions-item label="服务器名称">
                            {{ selectedServer.name }}
                        </el-descriptions-item>
                        <el-descriptions-item label="服务器ID">
                            {{ selectedServer.server_id }}
                        </el-descriptions-item>
                        <el-descriptions-item label="接收数据包">
                            {{ selectedServer.vpn_status.receive_packets }}
                        </el-descriptions-item>
                        <el-descriptions-item label="发送数据包">
                            {{ selectedServer.vpn_status.send_packets }}
                        </el-descriptions-item>
                        <el-descriptions-item label="接收字节">
                            {{ formatBytes(selectedServer.vpn_status.receive_bytes) }}
                        </el-descriptions-item>
                        <el-descriptions-item label="发送字节">
                            {{ formatBytes(selectedServer.vpn_status.send_bytes) }}
                        </el-descriptions-item>
                        <el-descriptions-item label="下行速率">
                            <span class="rate-text">↓ {{ formatRate(serverRate.download) }}</span>
                        </el-descriptions-item>
                        <el-descriptions-item label="上行速率">
                            <span class="rate-text">↑ {{ formatRate(serverRate.upload) }}</span>
                        </el-descriptions-item>
                        <el-descriptions-item label="在线用户数" :span="2">
                            {{ selectedServer.vpn_status.online_user_info?.length || 0 }}
                        </el-descriptions-item>
                    </el-descriptions>

                    <el-divider content-position="left">在线用户</el-divider>

                    <el-table :data="sortedUsers" stripe style="width: 100%">
                        <el-table-column prop="user_id" label="用户ID" width="100" />
                        <el-table-column prop="session_id" label="会话ID" min-width="180" show-overflow-tooltip />
                        <el-table-column prop="upload_packets" label="上传包" width="100" />
                        <el-table-column prop="download_packets" label="下载包" width="100" />
                        <el-table-column label="上传字节" width="120">
                            <template #default="{ row }">
                                {{ formatBytes(row.upload_bytes) }}
                            </template>
                        </el-table-column>
                        <el-table-column label="下载字节" width="120">
                            <template #default="{ row }">
                                {{ formatBytes(row.download_bytes) }}
                            </template>
                        </el-table-column>
                        <el-table-column label="上行速率" width="130">
                            <template #default="{ row }">
                                <span class="rate-text">↑ {{ formatRate(getUserRate(row.session_id).upload) }}</span>
                            </template>
                        </el-table-column>
                        <el-table-column label="下行速率" width="130">
                            <template #default="{ row }">
                                <span class="rate-text">↓ {{ formatRate(getUserRate(row.session_id).download) }}</span>
                            </template>
                        </el-table-column>
                    </el-table>
                </el-card>

                <el-card shadow="hover" v-else>
                    <el-empty description="请选择服务器查看状态" />
                </el-card>
            </el-col>
        </el-row>
    </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, onUnmounted } from 'vue';
import { ElMessage } from 'element-plus';
import { GetVPNServerConfigHandler, GetVPNServerOnlineListHandler } from '@/api/vpn';
import { ServerConfig, VPNStatus, OnlineUserInfo } from '@/types/vpn';

interface ServerRate {
    upload: number;
    download: number;
}

interface UserRateData {
    [sessionId: string]: {
        upload: number;
        download: number;
        lastUploadBytes: number;
        lastDownloadBytes: number;
        lastUpdateTime: number;
    };
}

const serverList = ref<ServerConfig[]>([]);
const selectedServer = ref<ServerConfig | null>(null);
const onlineServersData = ref<ServerConfig[]>([]);
let timer: number | null = null;

const serverRate = reactive<ServerRate>({
    upload: 0,
    download: 0
});

const userRateData = reactive<UserRateData>({});

let lastServerData: {
    receive_bytes: number;
    send_bytes: number;
    last_update_time: number;
} | null = null;

const formatBytes = (bytes: number): string => {
    if (bytes === 0) return '0 B';
    const k = 1024;
    const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};

const formatRate = (bytesPerSecond: number): string => {
    if (bytesPerSecond === 0) return '0 B/s';
    const k = 1024;
    const sizes = ['B/s', 'KB/s', 'MB/s', 'GB/s'];
    const i = Math.floor(Math.log(bytesPerSecond) / Math.log(k));
    return parseFloat((bytesPerSecond / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};

const getStatusType = (status: number) => {
    return status === 2 ? 'success' : 'danger';
};

const getStatusText = (status: number) => {
    return status === 2 ? '在线' : '离线';
};

const isServerOnline = (server: ServerConfig): boolean => {
    const onlineServer = onlineServersData.value.find(s => s.server_id === server.server_id);
    return onlineServer?.vpn_status?.status === 2;
};

const getServerConfig = async () => {
    try {
        const response = await GetVPNServerConfigHandler();
        serverList.value = response.data || [];
    } catch (error) {
        ElMessage.error('获取服务器配置失败');
        console.error(error);
    }
};

const getOnlineServers = async () => {
    try {
        const response = await GetVPNServerOnlineListHandler();
        if (response.data && Array.isArray(response.data)) {
            onlineServersData.value = response.data;
            
            if (selectedServer.value) {
                const onlineServer = onlineServersData.value.find(
                    s => s.server_id === selectedServer.value.server_id
                );
                if (onlineServer) {
                    calculateServerRate(onlineServer.vpn_status);
                    calculateUserRates(onlineServer.vpn_status?.online_user_info || []);
                    selectedServer.value.vpn_status = onlineServer.vpn_status;
                }
            }
        }
    } catch (error) {
        console.error('获取在线服务器状态失败:', error);
    }
};

const calculateServerRate = (vpnStatus: VPNStatus | undefined) => {
    if (!vpnStatus) return;
    
    const now = Date.now();
    
    if (lastServerData) {
        const timeDiff = (now - lastServerData.last_update_time) / 1000;
        if (timeDiff > 0) {
            const downloadDiff = vpnStatus.receive_bytes - lastServerData.receive_bytes;
            const uploadDiff = vpnStatus.send_bytes - lastServerData.send_bytes;
            
            serverRate.download = Math.max(0, downloadDiff / timeDiff);
            serverRate.upload = Math.max(0, uploadDiff / timeDiff);
        }
    }
    
    lastServerData = {
        receive_bytes: vpnStatus.receive_bytes,
        send_bytes: vpnStatus.send_bytes,
        last_update_time: now
    };
};

const calculateUserRates = (users: OnlineUserInfo[]) => {
    const now = Date.now();
    const currentSessionIds = new Set<string>();
    
    users.forEach(user => {
        currentSessionIds.add(user.session_id);
        
        if (userRateData[user.session_id]) {
            const timeDiff = (now - userRateData[user.session_id].lastUpdateTime) / 1000;
            if (timeDiff > 0) {
                const uploadDiff = user.upload_bytes - userRateData[user.session_id].lastUploadBytes;
                const downloadDiff = user.download_bytes - userRateData[user.session_id].lastDownloadBytes;
                
                userRateData[user.session_id].upload = Math.max(0, uploadDiff / timeDiff);
                userRateData[user.session_id].download = Math.max(0, downloadDiff / timeDiff);
            }
            userRateData[user.session_id].lastUploadBytes = user.upload_bytes;
            userRateData[user.session_id].lastDownloadBytes = user.download_bytes;
            userRateData[user.session_id].lastUpdateTime = now;
        } else {
            userRateData[user.session_id] = {
                upload: 0,
                download: 0,
                lastUploadBytes: user.upload_bytes,
                lastDownloadBytes: user.download_bytes,
                lastUpdateTime: now
            };
        }
    });
    
    Object.keys(userRateData).forEach(sessionId => {
        if (!currentSessionIds.has(sessionId)) {
            delete userRateData[sessionId];
        }
    });
};

const getUserRate = (sessionId: string) => {
    return userRateData[sessionId] || { upload: 0, download: 0 };
};

const sortedUsers = computed(() => {
    if (!selectedServer.value?.vpn_status?.online_user_info) {
        return [];
    }
    
    return [...selectedServer.value.vpn_status.online_user_info].sort((a, b) => {
        const rateA = getUserRate(a.session_id);
        const rateB = getUserRate(b.session_id);
        const totalA = rateA.upload + rateA.download;
        const totalB = rateB.upload + rateB.download;
        return totalB - totalA;
    });
});

const selectServer = (server: ServerConfig) => {
    selectedServer.value = server;
    lastServerData = null;
    serverRate.upload = 0;
    serverRate.download = 0;
    
    const onlineServer = onlineServersData.value.find(s => s.server_id === server.server_id);
    if (onlineServer?.vpn_status) {
        selectedServer.value.vpn_status = onlineServer.vpn_status;
        calculateServerRate(onlineServer.vpn_status);
        calculateUserRates(onlineServer.vpn_status.online_user_info || []);
    }
};

const startTimer = () => {
    getOnlineServers();
    timer = window.setInterval(() => {
        getOnlineServers();
    }, 6000);
};

const stopTimer = () => {
    if (timer !== null) {
        clearInterval(timer);
        timer = null;
    }
};

onMounted(async () => {
    await getServerConfig();
    startTimer();
});

onUnmounted(() => {
    stopTimer();
});
</script>

<style scoped>
.vpn-server-status {
    padding: 20px;
}

.card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.server-list {
    max-height: 600px;
    overflow-y: auto;
}

.server-item {
    padding: 12px;
    border: 1px solid #e4e7ed;
    border-radius: 4px;
    margin-bottom: 8px;
    cursor: pointer;
    transition: all 0.3s;
}

.server-item:hover {
    border-color: #409eff;
    background-color: #f5f7fa;
}

.server-item.active {
    border-color: #409eff;
    background-color: #ecf5ff;
}

.server-info {
    display: flex;
    flex-direction: column;
}

.server-name {
    font-weight: 500;
    display: flex;
    align-items: center;
    gap: 8px;
}

.server-ip {
    font-size: 12px;
    color: #909399;
    margin-top: 4px;
}

.status-indicator {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background-color: #909399;
}

.status-indicator.online {
    background-color: #67c23a;
    box-shadow: 0 0 4px #67c23a;
}

.rate-text {
    font-weight: 500;
    color: #409eff;
}
</style>
