/**
 * @file StatsPanel.cpp
 * @brief Statistics table implementation.
 */

#include "StatsPanel.h"
#include "App.h"

#include "imgui.h"
#include "implot.h"

#include <cstdio>

namespace StreamHubClient {

void RenderStatsPanel(App& app) {
    const auto& sources = app.sources();

    ImGuiTableFlags flags =
        ImGuiTableFlags_Borders |
        ImGuiTableFlags_RowBg   |
        ImGuiTableFlags_ScrollX |
        ImGuiTableFlags_SizingFixedFit;

    if (!ImGui::BeginTable("##statstbl", 9, flags)) { return; }

    ImGui::TableSetupScrollFreeze(1, 1);
    ImGui::TableSetupColumn("Source");
    ImGui::TableSetupColumn("State");
    ImGui::TableSetupColumn("Cycles Rx");
    ImGui::TableSetupColumn("Lost");
    ImGui::TableSetupColumn("Rate Hz");
    ImGui::TableSetupColumn("Frags/cyc");
    ImGui::TableSetupColumn("Bytes/cyc");
    ImGui::TableSetupColumn("Cycle ms (avg±std)");
    ImGui::TableSetupColumn("Cycle ms (min/max)");
    ImGui::TableHeadersRow();

    for (const auto& src : sources) {
        const SourceStats& st = src.stats;

        ImGui::TableNextRow();
        ImGui::TableNextColumn(); ImGui::TextUnformatted(src.id.c_str());

        /* State cell with color */
        ImGui::TableNextColumn();
        ImVec4 stColor = (st.state == "connected")
            ? ImVec4(0.2f,0.9f,0.3f,1.f)
            : ImVec4(0.9f,0.3f,0.3f,1.f);
        ImGui::TextColored(stColor, "%s", st.state.c_str());

        ImGui::TableNextColumn(); ImGui::Text("%llu", (unsigned long long)st.totalReceived);
        ImGui::TableNextColumn(); ImGui::Text("%llu", (unsigned long long)st.totalLost);
        ImGui::TableNextColumn(); ImGui::Text("%.2f ± %.2f", st.rateHz, st.rateStdHz);
        ImGui::TableNextColumn(); ImGui::Text("%.1f", st.fragsPerCycle);
        ImGui::TableNextColumn(); ImGui::Text("%.0f", st.bytesPerCycle);
        ImGui::TableNextColumn(); ImGui::Text("%.3f ± %.3f", st.cycleAvgMs, st.cycleStdMs);
        ImGui::TableNextColumn(); ImGui::Text("%.3f / %.3f", st.cycleMinMs, st.cycleMaxMs);
    }

    ImGui::EndTable();

    /* ── Cycle-time histograms (20 bins, mirrors web UI) ────────────── */
    for (const auto& src : sources) {
        const SourceStats& st = src.stats;
        if (st.cycleHistMax <= st.cycleHistMin) { continue; }

        char title[160];
        snprintf(title, sizeof(title), "Cycle time %s##hist_%s",
                 src.id.c_str(), src.id.c_str());
        if (ImPlot::BeginPlot(title, ImVec2(-1.f, 140.f),
                              ImPlotFlags_NoMouseText | ImPlotFlags_NoMenus)) {
            const double binW =
                (st.cycleHistMax - st.cycleHistMin) / 20.0;
            double xs[20];
            for (int b = 0; b < 20; b++) {
                xs[b] = st.cycleHistMin + (b + 0.5) * binW;
            }
            ImPlot::SetupAxes("cycle ms", "count",
                              ImPlotAxisFlags_AutoFit,
                              ImPlotAxisFlags_AutoFit);
            ImPlot::PlotBars("##bars", xs, st.cycleHist, 20, binW * 0.9);
            ImPlot::EndPlot();
        }
    }

    ImGui::Spacing();
    if (ImGui::Button("Refresh")) {
        app.ws().sendText(BuildGetStats());
    }
}

} /* namespace StreamHubClient */
