#include "core/log_window.h"
#include "core/logger.h"

#include "imgui.h"

#include <cstring>

namespace fn_ui {

namespace {

bool        g_open                  = false;
bool        g_show_debug            = true;
bool        g_show_info             = true;
bool        g_show_warn             = true;
bool        g_show_error            = true;
bool        g_autoscroll            = true;
char        g_filter_buf[128]       = "";

// Tamano previo del buffer — usado para detectar entradas nuevas y forzar
// scroll-to-bottom solo cuando llegan logs (no en cada frame).
std::size_t g_prev_buffer_size      = 0;

ImVec4 color_for_level(fn_log::Level level) {
    switch (level) {
        case fn_log::Level::Debug: return ImVec4(0.55f, 0.60f, 0.66f, 1.0f); // gris azulado
        case fn_log::Level::Info:  return ImVec4(0.78f, 0.82f, 0.86f, 1.0f); // texto
        case fn_log::Level::Warn:  return ImVec4(0.95f, 0.74f, 0.31f, 1.0f); // ambar
        case fn_log::Level::Error: return ImVec4(0.95f, 0.43f, 0.43f, 1.0f); // rojo
    }
    return ImVec4(1, 1, 1, 1);
}

bool level_visible(fn_log::Level level) {
    switch (level) {
        case fn_log::Level::Debug: return g_show_debug;
        case fn_log::Level::Info:  return g_show_info;
        case fn_log::Level::Warn:  return g_show_warn;
        case fn_log::Level::Error: return g_show_error;
    }
    return true;
}

bool matches_filter(const char* text) {
    if (g_filter_buf[0] == '\0') return true;
    return std::strstr(text, g_filter_buf) != nullptr;
}

} // namespace

bool log_window_is_open()        { return g_open; }
void log_window_set_open(bool v) { g_open = v; }
void log_window_toggle()         { g_open = !g_open; }

bool log_window_menu_item(const char* label) {
    if (ImGui::MenuItem(label)) {
        g_open = true;
        return true;
    }
    return false;
}

void log_window_render() {
    if (!g_open) return;

    ImGui::SetNextWindowSize(ImVec2(720, 420), ImGuiCond_FirstUseEver);
    if (!ImGui::Begin("Logs", &g_open, ImGuiWindowFlags_NoCollapse)) {
        ImGui::End();
        return;
    }

    // --- Toolbar: filtros por nivel + busqueda + acciones ---
    ImGui::Checkbox("Debug", &g_show_debug); ImGui::SameLine();
    ImGui::Checkbox("Info",  &g_show_info);  ImGui::SameLine();
    ImGui::Checkbox("Warn",  &g_show_warn);  ImGui::SameLine();
    ImGui::Checkbox("Error", &g_show_error);

    ImGui::SameLine();
    ImGui::Dummy(ImVec2(12, 0));
    ImGui::SameLine();
    ImGui::SetNextItemWidth(220.0f);
    ImGui::InputTextWithHint("##log_filter", "filtro (substring)", g_filter_buf, sizeof(g_filter_buf));

    ImGui::SameLine();
    ImGui::Checkbox("Auto-scroll", &g_autoscroll);

    ImGui::SameLine();
    if (ImGui::Button("Clear")) {
        fn_log::buffer_clear();
        g_prev_buffer_size = 0;
    }

    // Path del archivo activo (si hay)
    const char* path = fn_log::logger_path();
    if (path && *path) {
        ImGui::SameLine();
        ImGui::TextDisabled(" → %s", path);
    }

    ImGui::Separator();

    // --- Region scroll con todas las entradas filtradas ---
    const float footer_h = ImGui::GetFrameHeightWithSpacing();
    if (ImGui::BeginChild("##log_scroll",
                          ImVec2(0, -footer_h),
                          true,
                          ImGuiWindowFlags_HorizontalScrollbar)) {
        ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4, 1));

        std::size_t total = fn_log::buffer_size();
        std::size_t shown = 0;
        for (std::size_t i = 0; i < total; ++i) {
            const fn_log::Entry* e = fn_log::buffer_at(i);
            if (!e) continue;
            if (!level_visible(e->level)) continue;
            if (!matches_filter(e->text)) continue;

            ImVec4 col = color_for_level(e->level);
            ImGui::PushStyleColor(ImGuiCol_Text, col);
            ImGui::TextUnformatted(e->text);
            ImGui::PopStyleColor();
            ++shown;
        }

        ImGui::PopStyleVar();

        // Auto-scroll: solo cuando llegan entradas nuevas
        if (g_autoscroll && total != g_prev_buffer_size) {
            ImGui::SetScrollHereY(1.0f);
        }
        g_prev_buffer_size = total;

        // Footer dentro del child para que se vea pegado abajo si esta vacio
        if (shown == 0) {
            ImGui::TextDisabled("Sin entradas que coincidan con los filtros.");
        }
    }
    ImGui::EndChild();

    // --- Status footer ---
    ImGui::TextDisabled("%zu entradas en buffer (cap %zu)",
                        fn_log::buffer_size(), fn_log::kBufferCapacity);

    ImGui::End();
}

} // namespace fn_ui
