// data_table_ai_panel — modal "Ask AI" de la tabla TQL.
// Sub-funcion extraida de modules/data_table/data_table.cpp (issue 0107c).
//
// Rangos de lineas del fuente original (antes de la extraccion):
//   - Stub llm_anthropic (no-op)   : lineas 82-112
//   - Modal "Ask AI" completo      : lineas 4209-4328
//   - Boton trigger en viz selector: linea 1588
//
// NOTA DEUDA TECNICA: llm_anthropic no esta en el registry todavia (Wave 4 TODO).
// Pendiente promover a cpp/functions/infra/llm_anthropic (.h + .cpp + .md).

#include "viz/data_table_ai_panel.h"
#include "core/data_table_types.h"
#include "core/tql_apply.h"
#include "imgui.h"

// llm_anthropic: usar header real si disponible, stub si no.
#ifdef FN_LLM_ANTHROPIC
#  include "core/llm_anthropic.h"
#else
// Stub no-op (inline en este TU hasta que llm_anthropic se promueva al registry).
// TODO: Wave 4 — promover a cpp/functions/infra/llm_anthropic.cpp + .h + .md
namespace llm_anthropic {
    enum class OutputMode { TQL, SQL };
    struct AskInput {
        std::string question;
        std::string tql_current;
        std::vector<std::string> col_names;
        std::vector<data_table::ColumnType> col_types;
        std::vector<std::string> joinable_names;
        OutputMode mode = OutputMode::TQL;
        std::string model;
        int max_tokens = 8192;
    };
    struct AskResult {
        std::string code;
        std::string raw;
        std::string error;
        int tokens_in  = 0;
        int tokens_out = 0;
    };
    inline AskResult ask(const AskInput&, const std::string& = "") {
        AskResult r;
        r.error = "llm_anthropic not available (stub). Build with FN_LLM_ANTHROPIC=1.";
        return r;
    }
} // namespace llm_anthropic
#endif

#include <string>
#include <vector>
#include <cstdio>

namespace data_table {

// ---------------------------------------------------------------------------
// draw_ask_ai_modal
// Dibuja el modal "Ask AI". Debe llamarse cada frame (patron ImGui).
// Abre el popup si ask_ai.open == true.
// ---------------------------------------------------------------------------
void draw_ask_ai_modal(AskAiState& ask_ai,
                       State& st,
                       const std::vector<std::string>& active_headers,
                       const std::vector<ColumnType>&  active_types,
                       int orig_cols)
{
    if (ask_ai.open) ImGui::OpenPopup("Ask AI");
    ImGui::SetNextWindowSize(ImVec2(820, 560), ImGuiCond_Appearing);
    if (ImGui::BeginPopupModal("Ask AI", &ask_ai.open,
                                ImGuiWindowFlags_NoSavedSettings)) {
        ImGui::TextDisabled("Ask en lenguaje natural. Default TQL. SQL solo si DuckDB linkado.");
        const char* modes[] = {"TQL", "SQL (DuckDB)"};
#ifndef FN_TQL_DUCKDB
        // SQL mode disabled visually pero el toggle existe (informativo)
        if (ask_ai.mode == 1) ask_ai.mode = 0;
#endif
        ImGui::Combo("Output##askmode", &ask_ai.mode, modes, IM_ARRAYSIZE(modes));
#ifndef FN_TQL_DUCKDB
        if (ask_ai.mode == 1) {
            ImGui::TextColored(ImVec4(1, 0.5f, 0.3f, 1),
                "SQL mode requires FN_TQL_DUCKDB=1 build flag.");
        }
#endif
        ImGui::InputTextMultiline("##ask_q", ask_ai.question, sizeof(ask_ai.question),
                                   ImVec2(-1, 80));
        ImGui::BeginDisabled(ask_ai.busy);
        if (ImGui::Button("Send")) {
            ask_ai.busy = true;
            ask_ai.status = "Sending...";
            ask_ai.error.clear();
            ask_ai.response_code.clear();
            ask_ai.response_raw.clear();

            // Build AskInput desde el state actual.
            llm_anthropic::AskInput in;
            in.question = ask_ai.question;
            in.tql_current = ask_ai.current_tql;
            in.col_names = active_headers;
            in.col_types = active_types;
            in.mode = (ask_ai.mode == 1)
                ? llm_anthropic::OutputMode::SQL
                : llm_anthropic::OutputMode::TQL;

            // Llamada blocking (UI freeze breve durante red).
            auto r = llm_anthropic::ask(in);
            ask_ai.busy = false;
            if (!r.error.empty()) {
                ask_ai.error = r.error;
                ask_ai.status = "Error";
            } else {
                ask_ai.response_raw = r.raw;
                ask_ai.response_code = r.code;
                ask_ai.status = "Got response.";
                // Llenar edit buffer
                std::snprintf(ask_ai.edit_buf, sizeof(ask_ai.edit_buf),
                              "%s", r.code.c_str());
            }
        }
        ImGui::EndDisabled();
        ImGui::SameLine();
        if (!ask_ai.status.empty()) {
            ImGui::TextDisabled("%s", ask_ai.status.c_str());
        }
        if (!ask_ai.error.empty()) {
            ImGui::TextColored(ImVec4(1, 0.4f, 0.4f, 1), "%s", ask_ai.error.c_str());
        }
        ImGui::Separator();
        ImGui::Columns(2, "ask_cols", true);
        ImGui::TextUnformatted("Current");
        ImGui::InputTextMultiline("##ask_cur",
            const_cast<char*>(ask_ai.current_tql.c_str()),
            ask_ai.current_tql.size() + 1,
            ImVec2(-1, 240),
            ImGuiInputTextFlags_ReadOnly);
        ImGui::NextColumn();
        ImGui::TextUnformatted("Proposed (editable before apply)");
        ImGui::InputTextMultiline("##ask_new", ask_ai.edit_buf, sizeof(ask_ai.edit_buf),
                                   ImVec2(-1, 240));
        ImGui::Columns(1);

        bool can_apply = !ask_ai.busy && ask_ai.edit_buf[0] != '\0';
        ImGui::BeginDisabled(!can_apply);
        if (ImGui::Button("Apply")) {
            std::string err;
            if (ask_ai.mode == 0) {
                // TQL apply
                bool ok = tql::apply(ask_ai.edit_buf, st,
                                      active_headers,
                                      active_types,
                                      nullptr, 0,
                                      orig_cols,
                                      &err);
                if (ok) {
                    ask_ai.status = "Applied OK.";
                    ask_ai.open = false;
                } else {
                    ask_ai.error = "tql::apply error: " + err;
                    ask_ai.status = "Apply failed.";
                }
            } else {
#ifdef FN_TQL_DUCKDB
                // SQL apply: ejecutar via tql_duckdb sobre TableInputs activas.
                // Para tablas en memoria construimos un TableInput basico desde
                // active_headers/types. v1 no recupera cells originales aqui;
                // reportamos solo error si fallo. Caller real deberia pasar
                // tables() del render scope. Sin esto, marcamos status info.
                ask_ai.status = "SQL execute disponible (FN_TQL_DUCKDB ON). "
                               "Integracion full pendiente: usar tql_duckdb::execute desde caller.";
#else
                ask_ai.status = "SQL execute requires FN_TQL_DUCKDB build flag.";
#endif
            }
        }
        ImGui::EndDisabled();
        ImGui::SameLine();
        if (ImGui::Button("Reject")) {
            ask_ai.response_code.clear();
            ask_ai.edit_buf[0] = '\0';
        }
        ImGui::SameLine();
        if (ImGui::Button("Close")) {
            ask_ai.open = false;
        }
        ImGui::EndPopup();
    }
}

} // namespace data_table
