/**
 * @file SourcePanel.cpp
 * @brief Source browser sidebar implementation.
 */

#include "SourcePanel.h"
#include "App.h"
#include "Protocol.h"

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

#include <cstdio>
#include <algorithm>

namespace StreamHubClient {

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

    ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4.f, 2.f));

    if (ImGui::CollapsingHeader("Sources", ImGuiTreeNodeFlags_DefaultOpen)) {
        for (int srcIdx = 0; srcIdx < static_cast<int>(sources.size()); srcIdx++) {
            Source& src = sources[srcIdx];

            /* State color indicator */
            ImVec4 stateColor = (src.state == "connected")
                ? ImVec4(0.1f, 0.9f, 0.3f, 1.f)
                : ImVec4(0.8f, 0.3f, 0.3f, 1.f);

            ImGui::PushID(srcIdx);
            ImGui::TextColored(stateColor, ICON_FA_CIRCLE);
            ImGui::SameLine();

            std::string treeLabel = src.label.empty() ? src.id : src.label;
            bool nodeOpen = ImGui::TreeNodeEx(treeLabel.c_str(),
                ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanAvailWidth);

            /* Per-source context menu: remove */
            if (ImGui::BeginPopupContextItem("##srccmenu")) {
                if (ImGui::MenuItem(ICON_FA_TRASH_CAN " Remove source")) {
                    app.ws().sendText(BuildRemoveSource(src.id));
                }
                ImGui::EndPopup();
            }

            if (nodeOpen) {
                for (int sigIdx = 0; sigIdx < static_cast<int>(src.signals.size()); sigIdx++) {
                    Signal& sig = src.signals[sigIdx];
                    ImGui::PushID(sigIdx);

                    /* Color swatch */
                    ImVec4 col = sig.color;
                    if (ImGui::ColorButton("##col", col,
                            ImGuiColorEditFlags_NoTooltip |
                            ImGuiColorEditFlags_NoBorder,
                            ImVec2(12.f, 12.f))) {
                        ImGui::OpenPopup("##sigcolor");
                    }
                    if (ImGui::BeginPopup("##sigcolor")) {
                        ImGui::ColorPicker4("Signal Color", reinterpret_cast<float*>(&sig.color),
                                            ImGuiColorEditFlags_NoAlpha);
                        ImGui::EndPopup();
                    }
                    ImGui::SameLine();

                    /* Unit / type label */
                    char label[128];
                    if (sig.meta.numElements > 1) {
                        snprintf(label, sizeof(label), "%s [%u]",
                                 sig.meta.name.c_str(), sig.meta.numElements);
                    } else {
                        snprintf(label, sizeof(label), "%s", sig.meta.name.c_str());
                    }
                    if (!sig.meta.unit.empty()) {
                        strncat(label, " (", sizeof(label) - strlen(label) - 1);
                        strncat(label, sig.meta.unit.c_str(), sizeof(label) - strlen(label) - 1);
                        strncat(label, ")", sizeof(label) - strlen(label) - 1);
                    }

                    ImGui::Selectable(label, false, 0, ImVec2(0, 0));

                    /* Drag-and-drop source: payload = (srcIdx, sigIdx) */
                    if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceAllowNullID)) {
                        struct DragPayload { int srcIdx; int sigIdx; };
                        DragPayload payload{srcIdx, sigIdx};
                        ImGui::SetDragDropPayload("SIGNAL_REF", &payload, sizeof(payload));
                        ImGui::TextUnformatted(sig.meta.name.c_str());
                        ImGui::EndDragDropSource();
                    }

                    ImGui::PopID();
                }
                ImGui::TreePop();
            }
            ImGui::PopID();
        }
    }

    ImGui::PopStyleVar();

    /* ── Add / Save sources (inline at the bottom of the sidebar) ──────── */
    ImGui::Spacing();
    ImGui::Separator();
    ImGui::Spacing();

    if (ImGui::Button(ICON_FA_PLUS " Add Source", ImVec2(-1.f, 0.f))) {
        app.showAddSrc() = true;
    }
    if (ImGui::Button(ICON_FA_FLOPPY_DISK " Save Sources", ImVec2(-1.f, 0.f))) {
        app.ws().sendText(BuildSaveSources());
    }
}

} /* namespace StreamHubClient */
