const API_URL = "/api/queue/status";
    const STATS_API_URL = "/api/queue/platformStats";
    const platforms = [
        "BDAI", "DB", "DOUBA", "DP", "DPA", "DYAI",
        "KIMI", "TXYB", "TXYBA", "TYQW", "TYQWA", "WXYY"
    ];
    let currentPanel = "queue";
    let loadedPanels = {queue: false, trend: false};
    let trendChartMode = "platform";
    let lastTrendData = null;

    function showPanel(panel) {
        currentPanel = panel;
        document.getElementById("queuePanel").classList.toggle("active", panel === "queue");
        document.getElementById("trendPanel").classList.toggle("active", panel === "trend");
        document.getElementById("queueNavBtn").classList.toggle("active", panel === "queue");
        document.getElementById("trendNavBtn").classList.toggle("active", panel === "trend");
        document.getElementById("pageTitle").innerText = panel === "queue"
            ? "GEO 队列监控面板"
            : "GEO历史任务数量趋势";
        document.getElementById("pageDesc").innerText = panel === "queue"
            ? "查看各平台 stream_batch / batch 队列积压情况"
            : "按时间范围查看各平台历史任务趋势";
        hideError();

        if (!loadedPanels[panel]) {
            refreshCurrentPanel();
        }
    }

    function refreshCurrentPanel() {
        if (currentPanel === "queue") {
            loadQueueStatus();
        } else {
            loadPlatformStats();
        }
    }

    function hideError() {
        const errorBox = document.getElementById("errorBox");
        errorBox.style.display = "none";
        errorBox.innerText = "";
    }

    function showError(message) {
        const errorBox = document.getElementById("errorBox");
        errorBox.style.display = "block";
        errorBox.innerText = message;
    }

    function setTrendLoading(isLoading) {
        document.querySelector(".trend-panel").classList.toggle("loading", isLoading);
    }

    function getNumClass(num) {
        if (num === 0) {
            return "num-ok";
        }
        if (num < 500) {
            return "num-warn";
        }
        return "num-danger";
    }

    function getStatus(total) {
        if (total === 0) {
            return {text: "正常", className: "status status-ok"};
        }
        if (total < 500) {
            return {text: "轻微积压", className: "status status-warn"};
        }
        return {text: "严重积压", className: "status status-danger"};
    }

    function renderData(data) {
        const tbody = document.getElementById("queueTableBody");
        let totalCount = 0;
        let streamBatchCount = 0;
        let batchCount = 0;

        tbody.innerHTML = "";

        platforms.forEach(platform => {
            const streamKey = `${platform}:geo:stream_batch:list`;
            const batchKey = `${platform}:geo:batch:list`;
            const streamValue = Number(data[streamKey] || 0);
            const batchValue = Number(data[batchKey] || 0);
            const platformTotal = streamValue + batchValue;
            const status = getStatus(platformTotal);
            const tr = document.createElement("tr");

            streamBatchCount += streamValue;
            batchCount += batchValue;
            totalCount += platformTotal;
            tr.innerHTML = `
                <td class="platform">${platform}</td>
                <td class="num ${getNumClass(streamValue)}">${streamValue}</td>
                <td class="num ${getNumClass(batchValue)}">${batchValue}</td>
                <td class="num ${getNumClass(platformTotal)}">${platformTotal}</td>
                <td><span class="${status.className}">${status.text}</span></td>
            `;
            tbody.appendChild(tr);
        });

        document.getElementById("totalCount").innerText = totalCount;
        document.getElementById("streamBatchCount").innerText = streamBatchCount;
        document.getElementById("batchCount").innerText = batchCount;
        document.getElementById("commitCount").innerText = Number(data["geo:task_commit:list"] || 0);
        document.getElementById("lastTime").innerText = "最后刷新：" + new Date().toLocaleString();
    }

    function getStatsItems(responseData) {
        if (Array.isArray(responseData)) {
            return responseData;
        }
        if (responseData && Array.isArray(responseData.data)) {
            return responseData.data;
        }
        return [];
    }

    function normalizeStats(responseData) {
        return getStatsItems(responseData)
            .map(item => ({
                time: normalizeStatDate(item["时间"] || item.time || item.date || item.begin || ""),
                platform: item["平台"] || item.platform || item.name || "未知平台",
                count: Number(item["数量"] || item.count || item.value || 0)
            }))
            .filter(item => item.time && Number.isFinite(item.count));
    }

    function normalizeStatDate(value) {
        return String(value || "").slice(0, 10);
    }

    function createSvgEl(tag, attrs = {}) {
        const el = document.createElementNS("http://www.w3.org/2000/svg", tag);
        Object.keys(attrs).forEach(key => el.setAttribute(key, attrs[key]));
        return el;
    }

    function renderPlatformTrend(responseData) {
        const chart = document.getElementById("platformTrendChart");
        const summary = document.getElementById("trendSummary");
        const statsNote = document.getElementById("statsNote");
        const colors = ["#2563eb", "#16a34a", "#f59e0b", "#dc2626", "#7c3aed", "#0891b2", "#db2777", "#475569"];
        const items = normalizeStats(responseData);

        chart.innerHTML = "";
        summary.innerHTML = "";

        if (!items.length) {
            statsNote.innerText = "暂无趋势数据";
            chart.innerHTML = '<div class="chart-empty">当前时间范围暂无历史任务趋势数据</div>';
            return;
        }

        const chartLabels = [...new Set(items.map(item => item.time))].sort();
        const cardLabels = [...chartLabels].reverse();
        const oldestDate = chartLabels[0];
        const newestDate = chartLabels[chartLabels.length - 1];
        const platformTotals = new Map();
        const pointMap = new Map();

        items.forEach(item => {
            platformTotals.set(item.platform, (platformTotals.get(item.platform) || 0) + item.count);
            const pointKey = `${item.platform}__${item.time}`;
            pointMap.set(pointKey, (pointMap.get(pointKey) || 0) + item.count);
        });

        const platformList = [...platformTotals.entries()]
            .sort((a, b) => b[1] - a[1])
            .map(([platform]) => platform);
        const maxCount = Math.max(...pointMap.values(), 1);
        const platformColorMap = new Map(platformList.map((platform, index) => [platform, colors[index % colors.length]]));
        const dayTotals = chartLabels.map(label => ({
            date: label,
            total: platformList.reduce((sum, platform) => sum + (pointMap.get(`${platform}__${label}`) || 0), 0)
        }));

        lastTrendData = {
            labels: chartLabels,
            platformList,
            pointMap,
            platformColorMap,
            dayTotals
        };

        const grid = document.createElement("div");
        grid.className = "daily-grid";

        cardLabels.forEach(label => {
            const dayItems = platformList.map(platform => ({
                platform,
                value: pointMap.get(`${platform}__${label}`) || 0,
                color: platformColorMap.get(platform)
            }));
            const dayTotal = dayItems.reduce((sum, item) => sum + item.value, 0);
            const card = document.createElement("div");
            const head = document.createElement("div");
            const date = document.createElement("div");
            const total = document.createElement("div");
            const list = document.createElement("div");

            card.className = "day-card";
            head.className = "day-card-head";
            date.className = "day-date";
            total.className = "day-total";
            list.className = "day-list";
            date.innerText = label;
            total.innerText = `总量 ${dayTotal}`;
            head.appendChild(date);
            head.appendChild(total);

            dayItems.forEach(item => {
                const row = document.createElement("div");
                const name = document.createElement("div");
                const bar = document.createElement("div");
                const barInner = document.createElement("div");
                const count = document.createElement("div");

                row.className = "day-row";
                name.className = "day-platform";
                bar.className = "day-bar";
                barInner.className = "day-bar-inner";
                count.className = "day-count";
                name.innerText = item.platform;
                barInner.style.width = `${Math.max(2, Math.round((item.value / maxCount) * 100))}%`;
                barInner.style.background = item.color;
                count.innerText = item.value;
                bar.appendChild(barInner);
                row.appendChild(name);
                row.appendChild(bar);
                row.appendChild(count);
                list.appendChild(row);
            });

            card.appendChild(head);
            card.appendChild(list);
            grid.appendChild(card);
        });

        chart.appendChild(grid);
        renderTrendSummary();
        statsNote.innerText = `共 ${platformList.length} 个平台，${oldestDate} 至 ${newestDate}`;
        document.getElementById("lastTime").innerText = "最后刷新：" + new Date().toLocaleString();
    }

    function renderTrendSummary() {
        if (!lastTrendData) {
            return;
        }

        const summary = document.getElementById("trendSummary");
        const titleText = trendChartMode === "total" ? "每日总量趋势" : "各平台每日趋势";
        const series = trendChartMode === "total"
            ? [{
                name: "总量",
                color: "#2563eb",
                values: lastTrendData.dayTotals.map(item => item.total)
            }]
            : lastTrendData.platformList.map(platform => ({
                name: platform,
                color: lastTrendData.platformColorMap.get(platform),
                values: lastTrendData.labels.map(label => lastTrendData.pointMap.get(`${platform}__${label}`) || 0)
            }));
        const maxValue = Math.max(...series.flatMap(item => item.values), 1);
        const width = Math.max(summary.clientWidth - 32, 720);
        const height = 220;
        const padding = {top: 26, right: 18, bottom: 40, left: 52};
        const plotWidth = width - padding.left - padding.right;
        const plotHeight = height - padding.top - padding.bottom;
        const xScale = index => lastTrendData.labels.length > 1
            ? padding.left + (plotWidth / (lastTrendData.labels.length - 1)) * index
            : padding.left + plotWidth / 2;
        const yScale = value => padding.top + plotHeight - (value / maxValue) * plotHeight;
        const head = document.createElement("div");
        const title = document.createElement("span");
        const actions = document.createElement("div");
        const range = document.createElement("span");
        const switchWrap = document.createElement("div");
        const platformBtn = document.createElement("button");
        const totalBtn = document.createElement("button");
        const svg = createSvgEl("svg", {viewBox: `0 0 ${width} ${height}`, role: "img"});
        const tooltip = document.createElement("div");

        summary.innerHTML = "";
        head.className = "trend-summary-title";
        title.className = "trend-summary-title-main";
        actions.className = "trend-summary-actions";
        range.className = "trend-summary-range";
        switchWrap.className = "trend-switch";
        platformBtn.className = `trend-switch-btn ${trendChartMode === "platform" ? "active" : ""}`;
        totalBtn.className = `trend-switch-btn ${trendChartMode === "total" ? "active" : ""}`;
        title.innerText = titleText;
        range.innerText = `${lastTrendData.labels[lastTrendData.labels.length - 1]} 至 ${lastTrendData.labels[0]}`;
        platformBtn.innerText = "平台";
        totalBtn.innerText = "总量";
        platformBtn.onclick = () => setTrendChartMode("platform");
        totalBtn.onclick = () => setTrendChartMode("total");
        switchWrap.appendChild(platformBtn);
        switchWrap.appendChild(totalBtn);
        head.appendChild(title);
        actions.appendChild(range);
        actions.appendChild(switchWrap);
        head.appendChild(actions);
        tooltip.className = "trend-tooltip";

        for (let i = 0; i <= 3; i++) {
            const value = Math.round((maxValue / 3) * i);
            const y = yScale(value);
            svg.appendChild(createSvgEl("line", {
                x1: padding.left,
                y1: y,
                x2: width - padding.right,
                y2: y,
                stroke: i === 0 ? "#cbd5e1" : "#e5e7eb",
                "stroke-width": "1"
            }));
            const axisText = createSvgEl("text", {
                x: padding.left - 10,
                y: y + 4,
                "text-anchor": "end",
                class: "trend-label"
            });
            axisText.textContent = value;
            svg.appendChild(axisText);
        }

        series.forEach(line => {
            const points = line.values.map((value, index) => ({
                date: lastTrendData.labels[index],
                value,
                x: xScale(index),
                y: yScale(value)
            }));

            svg.appendChild(createSvgEl("polyline", {
                points: points.map(point => `${point.x},${point.y}`).join(" "),
                fill: "none",
                stroke: line.color,
                "stroke-width": trendChartMode === "total" ? "3" : "2",
                "stroke-opacity": trendChartMode === "total" ? "1" : "0.78",
                "stroke-linecap": "round",
                "stroke-linejoin": "round"
            }));

            points.forEach(point => {
                svg.appendChild(createSvgEl("circle", {
                    cx: point.x,
                    cy: point.y,
                    r: trendChartMode === "total" ? "5" : "3",
                    fill: line.color,
                    stroke: "#fff",
                    "stroke-width": "2"
                }));

                if (trendChartMode === "total") {
                    const totalText = createSvgEl("text", {
                        x: point.x,
                        y: Math.max(14, point.y - 10),
                        "text-anchor": "middle",
                        class: "trend-total-label"
                    });
                    totalText.textContent = point.value;
                    svg.appendChild(totalText);
                }
            });
        });

        lastTrendData.labels.forEach((label, index) => {
            const dateText = createSvgEl("text", {
                x: xScale(index),
                y: height - 12,
                "text-anchor": "middle",
                class: "trend-label"
            });
            dateText.textContent = label.slice(5);
            svg.appendChild(dateText);
        });

        lastTrendData.labels.forEach((label, index) => {
            const left = index === 0 ? padding.left : (xScale(index - 1) + xScale(index)) / 2;
            const right = index === lastTrendData.labels.length - 1
                ? width - padding.right
                : (xScale(index) + xScale(index + 1)) / 2;
            const hit = createSvgEl("rect", {
                x: left,
                y: padding.top,
                width: Math.max(12, right - left),
                height: plotHeight,
                fill: "transparent",
                "pointer-events": "all",
                class: "trend-hover-hit"
            });

            hit.addEventListener("mouseenter", event => showTrendDayTooltip(event, label));
            hit.addEventListener("mousemove", moveTrendDayTooltip);
            hit.addEventListener("mouseleave", hideTrendDayTooltip);
            svg.appendChild(hit);
        });

        summary.appendChild(head);
        summary.appendChild(svg);
        summary.appendChild(tooltip);
    }

    function setTrendChartMode(mode) {
        trendChartMode = mode;
        renderTrendSummary();
    }

    function moveTrendDayTooltip(event) {
        const tooltip = document.querySelector(".trend-tooltip");

        if (!tooltip) {
            return;
        }

        const offset = 14;
        const tooltipWidth = tooltip.offsetWidth || 280;
        const tooltipHeight = tooltip.offsetHeight || 120;
        let left = event.clientX + offset;
        let top = event.clientY + offset;

        if (left + tooltipWidth > window.innerWidth - 12) {
            left = event.clientX - tooltipWidth - offset;
        }
        if (top + tooltipHeight > window.innerHeight - 12) {
            top = event.clientY - tooltipHeight - offset;
        }

        tooltip.style.left = `${Math.max(12, left)}px`;
        tooltip.style.top = `${Math.max(12, top)}px`;
    }

    function showTrendDayTooltip(event, date) {
        const tooltip = document.querySelector(".trend-tooltip");

        if (!tooltip || !lastTrendData) {
            return;
        }

        const dayItems = lastTrendData.platformList.map(platform => ({
            platform,
            value: lastTrendData.pointMap.get(`${platform}__${date}`) || 0,
            color: lastTrendData.platformColorMap.get(platform)
        })).sort((a, b) => b.value - a.value);
        const dayTotal = dayItems.reduce((sum, item) => sum + item.value, 0);
        tooltip.innerHTML = "";

        const title = document.createElement("div");
        const total = document.createElement("div");
        const totalValue = document.createElement("strong");
        const list = document.createElement("div");

        title.className = "trend-tooltip-title";
        title.innerText = date;
        total.className = "trend-tooltip-total";
        total.innerHTML = "<span>当天总量</span>";
        totalValue.innerText = dayTotal;
        total.appendChild(totalValue);
        list.className = "trend-tooltip-list";

        dayItems.forEach(item => {
            const row = document.createElement("div");
            const dot = document.createElement("span");
            const name = document.createElement("span");
            const count = document.createElement("span");

            row.className = "trend-tooltip-row";
            dot.className = "trend-tooltip-dot";
            dot.style.background = item.color;
            name.className = "trend-tooltip-name";
            name.innerText = item.platform;
            count.className = "trend-tooltip-count";
            count.innerText = item.value;
            row.appendChild(dot);
            row.appendChild(name);
            row.appendChild(count);
            list.appendChild(row);
        });

        tooltip.appendChild(title);
        tooltip.appendChild(total);
        tooltip.appendChild(list);
        tooltip.style.display = "block";
        moveTrendDayTooltip(event);
    }

    function hideTrendDayTooltip() {
        const tooltip = document.querySelector(".trend-tooltip");

        if (tooltip) {
            tooltip.style.display = "none";
        }
    }

    function toDateInputValue(date) {
        const offsetDate = new Date(date.getTime() - date.getTimezoneOffset() * 60000);
        return offsetDate.toISOString().slice(0, 10);
    }

    function setQuickRange(days, shouldLoad = true) {
        const beginInput = document.getElementById("beginTime");
        const endInput = document.getElementById("endTime");
        const now = new Date();
        const start = new Date(now);

        start.setDate(start.getDate() - days + 1);
        start.setHours(0, 0, 0, 0);
        beginInput.value = toDateInputValue(start);
        endInput.value = toDateInputValue(now);
        document.getElementById("range3Btn").classList.toggle("active", days === 3);
        document.getElementById("range7Btn").classList.toggle("active", days === 7);
        document.getElementById("range30Btn").classList.toggle("active", days === 30);

        if (shouldLoad && currentPanel === "trend") {
            loadPlatformStats();
        } else if (shouldLoad) {
            loadedPanels.trend = false;
        }
    }

    function clearQuickRangeActive() {
        document.getElementById("range3Btn").classList.remove("active");
        document.getElementById("range7Btn").classList.remove("active");
        document.getElementById("range30Btn").classList.remove("active");
    }

    function handleDateRangeChange() {
        clearQuickRangeActive();
        loadedPanels.trend = false;

        if (currentPanel === "trend") {
            loadPlatformStats();
        }
    }

    function buildStatsUrl() {
        const begin = document.getElementById("beginTime").value;
        const end = document.getElementById("endTime").value;

        if (!begin || !end) {
            throw new Error("请选择开始时间和结束时间");
        }
        if (begin > end) {
            throw new Error("开始时间不能晚于结束时间");
        }

        return `${STATS_API_URL}?${new URLSearchParams({begin, end}).toString()}`;
    }

    async function fetchJson(url) {
        const res = await fetch(url, {method: "GET", cache: "no-store"});

        if (!res.ok) {
            throw new Error("接口请求失败，状态码：" + res.status);
        }

        return res.json();
    }

    async function loadQueueStatus() {
        hideError();

        try {
            renderData(await fetchJson(API_URL));
            loadedPanels.queue = true;
        } catch (e) {
            showError("队列数据加载失败：" + e.message);
        }
    }

    async function loadPlatformStats() {
        const statsNote = document.getElementById("statsNote");
        hideError();
        statsNote.innerText = "加载中";
        trendChartMode = "platform";
        setTrendLoading(true);

        try {
            renderPlatformTrend(await fetchJson(buildStatsUrl()));
            loadedPanels.trend = true;
        } catch (e) {
            statsNote.innerText = "加载失败";
            showError("历史任务趋势加载失败：" + e.message);
        } finally {
            setTrendLoading(false);
        }
    }

    document.getElementById("beginTime").addEventListener("change", handleDateRangeChange);
    document.getElementById("endTime").addEventListener("change", handleDateRangeChange);
    setQuickRange(3, false);
    loadQueueStatus();
