#include "panels.h"
#include "data.h"

#include <imgui.h>
#include <mutex>
#include <string>
#include <vector>

#include "core/icons_tabler.h"

namespace kanban {

static std::string join(const std::vector<std::string>& xs, const char* sep) {
    std::string out;
    for (size_t i = 0; i < xs.size(); ++i) {
        if (i) out += sep;
        out += xs[i];
    }
    return out;
}

static int find_idx(const std::vector<std::string>& xs, const std::string& v) {
    for (size_t i = 0; i < xs.size(); ++i) if (xs[i] == v) return (int)i;
    return -1;
}

static std::vector<std::string> split_csv(const std::string& s) {
    std::vector<std::string> out;
    std::string cur;
    for (char c : s) {
        if (c == ',') {
            // trim
            while (!cur.empty() && (cur.front() == ' ' || cur.front() == '\t')) cur.erase(cur.begin());
            while (!cur.empty() && (cur.back()  == ' ' || cur.back()  == '\t')) cur.pop_back();
            if (!cur.empty()) out.push_back(cur);
            cur.clear();
        } else {
            cur.push_back(c);
        }
    }
    while (!cur.empty() && (cur.front() == ' ' || cur.front() == '\t')) cur.erase(cur.begin());
    while (!cur.empty() && (cur.back()  == ' ' || cur.back()  == '\t')) cur.pop_back();
    if (!cur.empty()) out.push_back(cur);
    return out;
}

static std::string js_arr(const std::vector<std::string>& xs) {
    std::string out = "[";
    for (size_t i = 0; i < xs.size(); ++i) {
        if (i) out += ",";
        out += "\"";
        for (char c : xs[i]) {
            if (c == '"' || c == '\\') out += '\\';
            out += c;
        }
        out += "\"";
    }
    out += "]";
    return out;
}

static std::string js_str(const std::string& s) {
    std::string out = "\"";
    for (char c : s) {
        if (c == '"' || c == '\\') out += '\\';
        out += c;
    }
    out += "\"";
    return out;
}

void draw_detail() {
    if (!ImGui::Begin(TI_INFO_CIRCLE " Detail")) {
        ImGui::End();
        return;
    }

    Issue iss;
    Meta  meta;
    std::string sel_id;
    {
        std::lock_guard<std::mutex> g(state().mu);
        sel_id = state().selected_issue_id;
        iss    = state().selected_issue_detail;
        meta   = state().meta;
    }

    if (sel_id.empty()) {
        ImGui::TextDisabled("Click a card on the Board to load detail.");
        ImGui::End();
        return;
    }

    ImGui::Text("%s — %s", iss.id.c_str(), iss.title.c_str());
    ImGui::SameLine();
    if (ImGui::SmallButton(TI_REFRESH "##reload")) {
        refresh_issue_detail(sel_id);
    }
    ImGui::Separator();

    // Status combo
    int s_idx = find_idx(meta.statuses, iss.status);
    {
        std::vector<const char*> items;
        for (const auto& s : meta.statuses) items.push_back(s.c_str());
        if (!items.empty() && ImGui::Combo("Status", &s_idx, items.data(), (int)items.size())) {
            if (s_idx >= 0 && s_idx < (int)meta.statuses.size()) {
                patch_issue_status(sel_id, meta.statuses[s_idx]);
                refresh_issue_detail(sel_id);
            }
        }
    }

    // Priority combo
    int p_idx = find_idx(meta.priorities, iss.priority);
    {
        std::vector<const char*> items;
        for (const auto& s : meta.priorities) items.push_back(s.c_str());
        if (!items.empty() && ImGui::Combo("Priority", &p_idx, items.data(), (int)items.size())) {
            if (p_idx >= 0 && p_idx < (int)meta.priorities.size()) {
                std::string body = "{\"priority\":" + js_str(meta.priorities[p_idx]) + "}";
                patch_issue_fields(sel_id, body);
                refresh_issue_detail(sel_id);
            }
        }
    }

    // Scope combo
    int sc_idx = find_idx(meta.scopes, iss.scope);
    {
        std::vector<const char*> items;
        for (const auto& s : meta.scopes) items.push_back(s.c_str());
        if (!items.empty() && ImGui::Combo("Scope", &sc_idx, items.data(), (int)items.size())) {
            if (sc_idx >= 0 && sc_idx < (int)meta.scopes.size()) {
                std::string body = "{\"scope\":" + js_str(meta.scopes[sc_idx]) + "}";
                patch_issue_fields(sel_id, body);
                refresh_issue_detail(sel_id);
            }
        }
    }

    ImGui::Separator();

    // Tags / domain / depends / blocks via CSV editors
    auto edit_csv = [&](const char* label, std::vector<std::string>& field, const char* json_key) {
        static char buf[1024];
        std::string cur = join(field, ", ");
        std::snprintf(buf, sizeof(buf), "%s", cur.c_str());
        if (ImGui::InputText(label, buf, sizeof(buf), ImGuiInputTextFlags_EnterReturnsTrue)) {
            auto parts = split_csv(buf);
            std::string body = "{\"";
            body += json_key;
            body += "\":";
            body += js_arr(parts);
            body += "}";
            patch_issue_fields(sel_id, body);
            refresh_issue_detail(sel_id);
        }
    };
    // For each list, we render in its own scope to keep buf separate.
    // ImGui uses widget id to disambiguate; we add ## suffix.
    {
        static char buf[1024];
        std::string cur = join(iss.tags, ", ");
        std::snprintf(buf, sizeof(buf), "%s", cur.c_str());
        ImGui::PushID("tags");
        if (ImGui::InputText("Tags (CSV, Enter to save)", buf, sizeof(buf), ImGuiInputTextFlags_EnterReturnsTrue)) {
            auto parts = split_csv(buf);
            std::string body = "{\"tags\":" + js_arr(parts) + "}";
            patch_issue_fields(sel_id, body);
            refresh_issue_detail(sel_id);
        }
        ImGui::PopID();
    }
    {
        static char buf[1024];
        std::string cur = join(iss.domain, ", ");
        std::snprintf(buf, sizeof(buf), "%s", cur.c_str());
        ImGui::PushID("domain");
        if (ImGui::InputText("Domain (CSV, Enter to save)", buf, sizeof(buf), ImGuiInputTextFlags_EnterReturnsTrue)) {
            auto parts = split_csv(buf);
            std::string body = "{\"domain\":" + js_arr(parts) + "}";
            patch_issue_fields(sel_id, body);
            refresh_issue_detail(sel_id);
        }
        ImGui::PopID();
    }
    {
        static char buf[1024];
        std::string cur = join(iss.depends, ", ");
        std::snprintf(buf, sizeof(buf), "%s", cur.c_str());
        ImGui::PushID("depends");
        if (ImGui::InputText("Depends (CSV, Enter)", buf, sizeof(buf), ImGuiInputTextFlags_EnterReturnsTrue)) {
            auto parts = split_csv(buf);
            std::string body = "{\"depends\":" + js_arr(parts) + "}";
            patch_issue_fields(sel_id, body);
            refresh_issue_detail(sel_id);
        }
        ImGui::PopID();
    }
    {
        static char buf[1024];
        std::string cur = join(iss.blocks, ", ");
        std::snprintf(buf, sizeof(buf), "%s", cur.c_str());
        ImGui::PushID("blocks");
        if (ImGui::InputText("Blocks (CSV, Enter)", buf, sizeof(buf), ImGuiInputTextFlags_EnterReturnsTrue)) {
            auto parts = split_csv(buf);
            std::string body = "{\"blocks\":" + js_arr(parts) + "}";
            patch_issue_fields(sel_id, body);
            refresh_issue_detail(sel_id);
        }
        ImGui::PopID();
    }

    ImGui::Separator();
    ImGui::TextDisabled("%s", iss.file_path.c_str());

    if (ImGui::CollapsingHeader("Body (read-only)")) {
        ImGui::BeginChild("body_ro", ImVec2(0, 320), true);
        ImGui::TextWrapped("%s", iss.body.c_str());
        ImGui::EndChild();
    }

    (void)edit_csv;  // silence unused (we inline the variants instead)

    ImGui::End();
}

}  // namespace kanban
