<template>
    <div class="servers-container">
        <h1>Мониторинг серверов</h1>
        <div v-if="isLoading" class="loading">Загрузка данных...</div>
        <div v-if="error" class="error-message">{{ error }}</div>

        <div class="ping-info">
            Ваш пинг до сервера:
            <span v-if="clientProxyPing !== null">{{ clientProxyPing }} мс</span>
            <span v-else>измерение...</span>
        </div>

        <div class="server-list">
            <div v-for="server in servers" :key="server.id" class="server-card">
                <h3>{{ server.name }}</h3>
                <p class="motd" v-html="formatMotd(server.motd)"></p>
                <div class="status">
                    <span class="online-status" :class="{ 'is-online': server.player_count !== null }">
                        {{ server.player_count !== null ? "Online" : "Offline" }}
                    </span>
                    <span class="players" v-if="server.player_count !== null"> {{ server.player_count }} / {{ server.max_players }} </span>
                </div>
                <div class="ping">
                    Общий пинг:
                    <span v-if="totalPing(server) !== null">{{ totalPing(server) }} мс</span>
                    <span v-else>N/A</span>
                </div>
                <div class="version">{{ server.version_name }}</div>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";
import apiClient from "@/api/axios";

// Тип для сервера, можно вынести в types.ts
interface GameServer {
    id: number;
    name: string;
    motd: string | null;
    player_count: number | null;
    max_players: number | null;
    version_name: string | null;
    ping_proxy_server: number | null;
}

const servers = ref<GameServer[]>([]);
const isLoading = ref(true);
const error = ref<string | null>(null);
const clientProxyPing = ref<number | null>(null);

let ws: WebSocket | null = null;
let pingInterval: number | null = null;

const fetchServers = async () => {
    try {
        const response = await apiClient.get<GameServer[]>("/servers");
        servers.value = response.data;
    } catch (e) {
        error.value = "Не удалось загрузить список серверов.";
    } finally {
        isLoading.value = false;
    }
};

const setupWebSocket = () => {
    const wsProtocol = window.location.protocol === "https:" ? "wss:" : "ws:";
    const wsUrl = `${wsProtocol}//${window.location.host}/ws/ping`;

    ws = new WebSocket(wsUrl);

    ws.onopen = () => {
        console.log("WebSocket connection established.");
        pingInterval = window.setInterval(() => {
            if (ws?.readyState === WebSocket.OPEN) {
                ws.send(Date.now().toString());
            }
        }, 5000);
    };

    ws.onmessage = (event) => {
        const serverTimestamp = parseInt(event.data, 10);
        clientProxyPing.value = Date.now() - serverTimestamp;
    };

    ws.onclose = () => {
        console.log("WebSocket connection closed.");
        if (pingInterval) clearInterval(pingInterval);
    };

    ws.onerror = (err) => {
        console.error("WebSocket error:", err);
        error.value = "Ошибка подключения к WebSocket.";
    };
};

const totalPing = (server: GameServer) => {
    if (clientProxyPing.value !== null && server.ping_proxy_server !== null) {
        return clientProxyPing.value + server.ping_proxy_server;
    }
    return null;
};

// Функция для форматирования MOTD с кодами цвета Minecraft
const formatMotd = (motd: string | null) => {
    if (!motd) return "";
    return motd.replace(/§[0-9a-fk-or]/g, "");
};

onMounted(() => {
    fetchServers();
    setupWebSocket();
});

onUnmounted(() => {
    if (ws) {
        ws.close();
    }
    if (pingInterval) {
        clearInterval(pingInterval);
    }
});
</script>

<style scoped>
/* ... добавьте стили для карточек серверов ... */
.server-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 1rem;
}
.server-card {
    border: 1px solid #ccc;
    border-radius: 8px;
    padding: 1rem;
}
.ping-info {
    margin-bottom: 1rem;
    font-weight: bold;
}
</style>
