#include "demos.h"
#include "demo.h"

#include "core/button.h"
#include "core/icon_button.h"
#include "core/toolbar.h"
#include "core/modal_dialog.h"
#include "core/text_input.h"
#include "core/select.h"
#include "core/toast.h"
#include "core/tree_view.h"
#include "core/badge.h"
#include "core/empty_state.h"
#include "core/page_header.h"
#include "core/dashboard_panel.h"
#include "core/tokens.h"
#include "core/icons_tabler.h"
#include "viz/kpi_card.h"

#include <imgui.h>
#include <cstdio>

using namespace fn_ui;
using V = ButtonVariant;
using S = ButtonSize;

namespace gallery {

// ---------------------------------------------------------------------------
// button
// ---------------------------------------------------------------------------

void demo_button() {
    demo_header("button", "v1.0.0",
        "Boton con 4 variantes semanticas y 3 tamanos. Usa tokens para colores, "
        "radius y padding — estilo consistente en toda la app.");

    section("Variants x Sizes");
    const V variants[] = {V::Primary, V::Secondary, V::Subtle, V::Danger};
    const char* variant_names[] = {"Primary", "Secondary", "Subtle", "Danger"};
    const S sizes[] = {S::Sm, S::Md, S::Lg};
    const char* size_names[] = {"sm", "md", "lg"};

    if (ImGui::BeginTable("##btn_grid", 5, ImGuiTableFlags_SizingFixedFit)) {
        ImGui::TableSetupColumn("size");
        for (int c = 0; c < 4; c++) ImGui::TableSetupColumn(variant_names[c]);
        ImGui::TableHeadersRow();

        for (int s = 0; s < 3; s++) {
            ImGui::TableNextRow();
            ImGui::TableSetColumnIndex(0);
            variant_label(size_names[s]);
            for (int v = 0; v < 4; v++) {
                ImGui::TableSetColumnIndex(v + 1);
                char id[32];
                std::snprintf(id, sizeof(id), "%s##%d%d", variant_names[v], s, v);
                button(id, variants[v], sizes[s]);
            }
        }
        ImGui::EndTable();
    }

    code_block(
        "#include \"core/button.h\"\n"
        "using fn_ui::button;\n"
        "using V = fn_ui::ButtonVariant;\n\n"
        "if (button(\"Save\",   V::Primary))   save();\n"
        "if (button(\"Cancel\", V::Subtle))    close();\n"
        "if (button(\"Delete\", V::Danger))    confirm();"
    );
}

// ---------------------------------------------------------------------------
// icon_button
// ---------------------------------------------------------------------------

void demo_icon_button() {
    demo_header("icon_button", "v1.0.0",
        "Boton cuadrado 28x28 con un glyph centrado y tooltip opcional. "
        "Usa los TI_* de core/icons_tabler.h (Tabler Icons cargado automaticamente "
        "por fn::run_app via icon_font.cpp).");

    section("Tabler icon set");
    struct { const char* id; const char* glyph; const char* tip; } ic[] = {
        {"##rl", TI_REFRESH,        "Reload"},
        {"##ad", TI_PLUS,           "Add"},
        {"##dl", TI_TRASH,          "Delete"},
        {"##dn", TI_CHEVRON_DOWN,   "Dropdown"},
        {"##cf", TI_SETTINGS,       "Settings"},
        {"##ok", TI_CHECK,          "Check"},
        {"##cl", TI_X,              "Close"},
        {"##ed", TI_PENCIL,         "Edit"},
        {"##sv", TI_DEVICE_FLOPPY,  "Save"},
        {"##sr", TI_SEARCH,         "Search"},
        {"##hp", TI_HELP,           "Help"},
        {"##hm", TI_HOME,           "Home"},
    };
    for (auto& b : ic) {
        icon_button(b.id, b.glyph, b.tip);
        ImGui::SameLine();
    }
    ImGui::NewLine();

    code_block(
        "#include \"core/icons_tabler.h\"\n\n"
        "if (icon_button(\"##reload\", TI_REFRESH, \"Reload\"))\n"
        "    reload_data();\n\n"
        "// Mas de 5000 iconos disponibles — ver core/icons_tabler.h"
    );
}

// ---------------------------------------------------------------------------
// toolbar
// ---------------------------------------------------------------------------

void demo_toolbar() {
    demo_header("toolbar", "v1.0.0",
        "Grupo horizontal con spacing consistente y separadores verticales sutiles. "
        "El caller usa ImGui::SameLine entre items y toolbar_separator entre grupos.");

    section("Example with two groups");
    toolbar_begin();
        button(TI_PLUS " New",          V::Primary);   ImGui::SameLine();
        button(TI_FOLDER_OPEN " Open",  V::Secondary); ImGui::SameLine();
        button(TI_DEVICE_FLOPPY " Save",V::Secondary);
      toolbar_separator();
        icon_button("##set",   TI_SETTINGS, "Settings");
        ImGui::SameLine();
        icon_button("##help",  TI_HELP,     "Help");
    toolbar_end();

    code_block(
        "#include \"core/icons_tabler.h\"\n\n"
        "toolbar_begin();\n"
        "    button(TI_PLUS \" New\",         V::Primary);   ImGui::SameLine();\n"
        "    button(TI_FOLDER_OPEN \" Open\", V::Secondary);\n"
        "  toolbar_separator();\n"
        "    icon_button(\"##set\", TI_SETTINGS, \"Settings\");\n"
        "toolbar_end();"
    );
}

// ---------------------------------------------------------------------------
// modal_dialog
// ---------------------------------------------------------------------------

void demo_modal() {
    demo_header("modal_dialog", "v1.0.0",
        "Popup modal centrada con estilo surface+border. Close con Escape o click en X. "
        "Patron begin/end — modal_dialog_end debe llamarse siempre.");

    static bool show = false;
    if (button("Open modal", V::Primary)) show = true;

    if (modal_dialog_begin("Demo modal", &show, ImVec2(380, 0))) {
        ImGui::TextWrapped(
            "Modal centrada en el viewport principal, con estilo tokens.");
        ImGui::Dummy(ImVec2(0, fn_tokens::spacing::sm));
        static char buf[64] = {};
        text_input("Name", buf, sizeof(buf), "escribe algo");
        ImGui::Separator();
        if (button("Cancel", V::Subtle))  show = false;
        ImGui::SameLine();
        if (button("Done",   V::Primary)) show = false;
    }
    modal_dialog_end();

    code_block(
        "static bool show = false;\n"
        "if (button(\"Open\", Primary)) show = true;\n"
        "if (modal_dialog_begin(\"Title\", &show, ImVec2(380,0))) {\n"
        "    // ... campos del form ...\n"
        "    if (button(\"Done\", Primary)) show = false;\n"
        "}\n"
        "modal_dialog_end();"
    );
}

// ---------------------------------------------------------------------------
// text_input
// ---------------------------------------------------------------------------

void demo_text_input() {
    demo_header("text_input", "v1.0.0",
        "Label muted + input estilizado con tokens. Full-width dentro del contenedor. "
        "Placeholder opcional mostrado en text_dim cuando el buffer esta vacio.");

    static char name[128] = {};
    static char desc[256] = {};
    static char tags[128] = {};

    ImGui::BeginChild("##ti_wrap", ImVec2(420, 0), ImGuiChildFlags_AutoResizeY);
    text_input("Name",        name, sizeof(name), "my-new-thing");
    ImGui::Dummy(ImVec2(0, fn_tokens::spacing::xs));
    text_input("Description", desc, sizeof(desc));
    ImGui::Dummy(ImVec2(0, fn_tokens::spacing::xs));
    text_input("Tags (CSV)",  tags, sizeof(tags), "imgui,ui,form");
    ImGui::EndChild();

    code_block(
        "static char name[128] = {};\n"
        "text_input(\"Name\", name, sizeof(name), \"my-new-thing\");\n"
        "// true on change — se usa mas para validar en vivo\n"
        "// que para leer el valor (que vive en el buffer)."
    );
}

// ---------------------------------------------------------------------------
// select
// ---------------------------------------------------------------------------

void demo_select() {
    demo_header("select", "v1.0.0",
        "Dropdown con label muted y opcion (none) opcional. Mismo estilo tokens que text_input.");

    static int lang_idx = 0;
    static int domain_idx = -1;
    const char* langs[]   = {"go", "py", "ts", "sh", "cpp"};
    const char* domains[] = {"core", "infra", "finance", "datascience", "viz"};

    ImGui::BeginChild("##sl_wrap", ImVec2(420, 0), ImGuiChildFlags_AutoResizeY);
    select("Language", &lang_idx, langs, 5);
    ImGui::Dummy(ImVec2(0, fn_tokens::spacing::xs));
    select("Domain (optional)", &domain_idx, domains, 5, true);
    ImGui::EndChild();

    code_block(
        "static int lang = 0;\n"
        "const char* langs[] = {\"go\",\"py\",\"ts\",\"sh\",\"cpp\"};\n"
        "select(\"Language\", &lang, langs, 5);"
    );
}

// ---------------------------------------------------------------------------
// toast + inbox
// ---------------------------------------------------------------------------

void demo_toast() {
    demo_header("toast", "v1.1.0",
        "Notificaciones efimeras (~3.5s con fade-out) + inbox con campana. "
        "La campana muestra badge con no-leidos y popover con las ultimas 50.");

    section("Trigger toasts");
    if (button("Info",    V::Secondary)) toast_push(ToastKind::Info,    "this is an info toast");
    ImGui::SameLine();
    if (button("Success", V::Primary))   toast_push(ToastKind::Success, "operation completed");
    ImGui::SameLine();
    if (button("Warning", V::Secondary)) toast_push(ToastKind::Warning, "heads up about something");
    ImGui::SameLine();
    if (button("Error",   V::Danger))    toast_push(ToastKind::Error,   "operation failed: reason");

    section("Inbox (bell with unread badge)");
    toast_inbox_button("##inbox_demo");

    code_block(
        "toast_push(ToastKind::Success, \"Reindexed 891 functions\");\n"
        "toast_push(ToastKind::Error,   \"HTTP 503: server down\");\n\n"
        "// En la toolbar:\n"
        "toast_inbox_button(\"##inbox\");\n\n"
        "// Una vez por frame al final del render:\n"
        "toast_render();"
    );
}

// ---------------------------------------------------------------------------
// tree_view
// ---------------------------------------------------------------------------

void demo_tree_view() {
    demo_header("tree_view", "v1.0.0",
        "Tree low-level para jerarquias (ej. projects -> apps/analysis/vaults). "
        "Sin estado interno: el caller gestiona seleccion y pasa 'selected' por parametro.");

    static std::string selected;

    section("Projects (fake)");
    ImGui::BeginChild("##tv", ImVec2(360, 200), ImGuiChildFlags_Borders);

    struct FakeProject { const char* id; const char* name; const char* apps[3]; };
    const FakeProject projs[] = {
        {"app_turismo",    "app_turismo",    {"guide_es", "offline_maps", nullptr}},
        {"element_agents", "element_agents", {"matrix_bot", nullptr, nullptr}},
        {"fn_monitoring",  "fn_monitoring",  {"sqlite_api", "registry_dashboard", nullptr}},
    };
    for (auto& p : projs) {
        bool sel = (selected == p.id);
        if (tree_branch_begin(p.id, p.name, sel)) {
            if (tree_node_clicked()) selected = p.id;
            for (int i = 0; i < 3 && p.apps[i]; i++) {
                bool asel = (selected == p.apps[i]);
                tree_leaf(p.apps[i], p.apps[i], asel);
                if (tree_node_clicked()) selected = p.apps[i];
            }
            tree_branch_end();
        } else if (tree_node_clicked()) {
            selected = p.id;
        }
    }
    ImGui::EndChild();

    ImGui::PushStyleColor(ImGuiCol_Text, fn_tokens::colors::text_muted);
    ImGui::Text("Selected: %s", selected.empty() ? "(none)" : selected.c_str());
    ImGui::PopStyleColor();

    code_block(
        "static std::string sel;\n"
        "if (tree_branch_begin(p.id, p.name, sel == p.id)) {\n"
        "    if (tree_node_clicked()) sel = p.id;\n"
        "    for (auto& a : p.apps) {\n"
        "        tree_leaf(a.id, a.name, sel == a.id);\n"
        "        if (tree_node_clicked()) sel = a.id;\n"
        "    }\n"
        "    tree_branch_end();\n"
        "}"
    );
}

// ---------------------------------------------------------------------------
// kpi_card
// ---------------------------------------------------------------------------

void demo_kpi_card() {
    demo_header("kpi_card", "v1.3.0",
        "Card compacta 86px con icono opcional + label muted, valor x1.4, trend con "
        "TI_TRENDING_UP/DOWN y sparkline. Usa tokens: surface bg, border, radius md.");

    if (ImGui::BeginTable("##kpi_grid", 4, ImGuiTableFlags_SizingStretchSame)) {
        float history[] = {10, 12, 11, 15, 18, 17, 20};
        ImGui::TableNextRow();
        ImGui::TableSetColumnIndex(0); kpi_card("Revenue", 20000.0f,  12.5f, history, 7, "$%.0f",  TI_CASH);
        ImGui::TableSetColumnIndex(1); kpi_card("Users",   1250.0f,    3.4f, history, 7, "%.0f",  TI_USERS);
        ImGui::TableSetColumnIndex(2); kpi_card("Churn",   2.1f,      -0.3f, history, 7, "%.1f%%", TI_CHART_BAR);
        ImGui::TableSetColumnIndex(3); kpi_card("Errors",  0.0f,       0.0f, nullptr, 0, "%.0f",  TI_ALERT_CIRCLE);
        ImGui::EndTable();
    }

    code_block(
        "#include \"core/icons_tabler.h\"\n\n"
        "float history[] = {10,12,11,15,18,17,20};\n"
        "kpi_card(\"Revenue\", 20000.0f, 12.5f, history, 7, \"$%.0f\", TI_CASH);\n"
        "kpi_card(\"Users\",   1250.0f,   3.4f, history, 7, \"%.0f\",  TI_USERS);\n"
        "// Sin delta ni history: muestra TI_MINUS como placeholder\n"
        "kpi_card(\"Errors\",  0.0f,      0.0f, nullptr, 0, \"%.0f\",  TI_ALERT_CIRCLE);"
    );
}

// ---------------------------------------------------------------------------
// badge
// ---------------------------------------------------------------------------

void demo_badge() {
    demo_header("badge", "v1.0.0",
        "Etiqueta inline con 6 variantes semanticas. Equivalente a <Badge> de fn_library.");

    section("Variants");
    badge("Default",  BadgeVariant::Default);   ImGui::SameLine();
    badge("Success",  BadgeVariant::Success);   ImGui::SameLine();
    badge("Warning",  BadgeVariant::Warning);   ImGui::SameLine();
    badge("Error",    BadgeVariant::Error);     ImGui::SameLine();
    badge("Info",     BadgeVariant::Info);      ImGui::SameLine();
    badge("Outline",  BadgeVariant::Outline);

    section("In context (table row)");
    ImGui::Text("filter_slice_go_core"); ImGui::SameLine();
    badge("pure",   BadgeVariant::Success); ImGui::SameLine();
    badge("tested", BadgeVariant::Info);

    code_block(
        "badge(\"pure\",   BadgeVariant::Success);\n"
        "badge(\"stale\",  BadgeVariant::Warning);\n"
        "badge(\"broken\", BadgeVariant::Error);"
    );
}

// ---------------------------------------------------------------------------
// empty_state
// ---------------------------------------------------------------------------

void demo_empty_state() {
    demo_header("empty_state", "v1.0.0",
        "Icono grande muted + titulo + descripcion opcional. Para listas/tablas vacias.");

    ImGui::BeginChild("##es", ImVec2(0, 180), ImGuiChildFlags_Borders);
    empty_state("( no data )", "No projects yet",
                "Create one under projects/{name}/ with project.md and reindex");
    ImGui::EndChild();

    code_block(
        "if (apps.empty()) {\n"
        "    empty_state(\"( no data )\", \"No apps yet\",\n"
        "                \"Click + Add to create one\");\n"
        "    return;\n"
        "}"
    );
}

// ---------------------------------------------------------------------------
// page_header
// ---------------------------------------------------------------------------

void demo_page_header() {
    demo_header("page_header", "v1.0.0",
        "Header de pagina con titulo, subtitulo opcional y separador final. "
        "Patron begin/end permite insertar acciones entre titulo y separador.");

    page_header_begin("Dashboard", "13 apps, 3 projects, 2 analyses");
    ImGui::SameLine(ImGui::GetContentRegionAvail().x - 140.0f);
    toolbar_begin();
        button("Reload", V::Subtle);      ImGui::SameLine();
        button("+ Add",  V::Secondary);
    toolbar_end();
    page_header_end();

    code_block(
        "page_header_begin(\"Dashboard\", subtitle);\n"
        "ImGui::SameLine(ImGui::GetContentRegionAvail().x - 140);\n"
        "toolbar_begin();\n"
        "    button(\"Reload\", Subtle);\n"
        "toolbar_end();\n"
        "page_header_end();"
    );
}

// ---------------------------------------------------------------------------
// dashboard_panel
// ---------------------------------------------------------------------------

void demo_dashboard_panel() {
    demo_header("dashboard_panel", "v1.0.0",
        "Contenedor tipo panel con titulo, bordes redondeados, bg surface. "
        "Auto-resize-Y segun contenido. Usa min_width/min_height como piso.");

    if (dashboard_panel_begin("Revenue", 0, 120.0f)) {
        ImGui::Text("Some panel content goes here.");
        ImGui::Text("Anything drawn inside lives in the child window.");
    }
    dashboard_panel_end();

    code_block(
        "if (dashboard_panel_begin(\"Revenue\", 0, 120.0f)) {\n"
        "    ImGui::Text(\"content\");\n"
        "}\n"
        "dashboard_panel_end();"
    );
}

} // namespace gallery
