#!/usr/bin/env bash
# init_cpp_app — Scaffolder estandar de apps C++ del registry.
#
# Genera la estructura canonica (main.cpp, CMakeLists.txt, app.md), registra
# la app en cpp/CMakeLists.txt, inicializa git + repo Gitea dataforge/<name>,
# y ejecuta fn index. La plantilla cumple cpp/PATTERNS.md y .claude/rules/cpp_apps.md.
#
# Uso:
#   init_cpp_app <name> [--project <p>] [--domain <d>] [--desc "..."] [--tags "a,b"]
#
# Por defecto domain=tools, sin proyecto (apps/<name>/, issue 0096).

set -euo pipefail

# Carga helpers del registry
FN_ROOT="${FN_REGISTRY_ROOT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"
# shellcheck source=/dev/null
source "$FN_ROOT/bash/functions/infra/ensure_repo_synced.sh"

init_cpp_app() {
    local name=""
    local project=""
    local domain="tools"
    local desc=""
    local tags=""

    while [[ $# -gt 0 ]]; do
        case "$1" in
            --project) project="$2"; shift 2 ;;
            --domain)  domain="$2";  shift 2 ;;
            --desc)    desc="$2";    shift 2 ;;
            --tags)    tags="$2";    shift 2 ;;
            -*) echo "init_cpp_app: flag desconocido: $1" >&2; return 2 ;;
            *)  if [[ -z "$name" ]]; then name="$1"; else
                    echo "init_cpp_app: argumento extra: $1" >&2; return 2
                fi
                shift ;;
        esac
    done

    if [[ -z "$name" ]]; then
        echo "init_cpp_app: se requiere <name>" >&2
        echo "Uso: init_cpp_app <name> [--project <p>] [--domain <d>] [--desc \"...\"] [--tags \"a,b\"]" >&2
        return 2
    fi

    [[ -z "$desc" ]] && desc="App C++ del registry"

    # Resolver dir destino
    local rel_dir abs_dir
    if [[ -n "$project" ]]; then
        if [[ ! -f "$FN_ROOT/projects/$project/project.md" ]]; then
            echo "init_cpp_app: proyecto '$project' no existe (falta projects/$project/project.md)" >&2
            return 1
        fi
        rel_dir="projects/$project/apps/$name"
    else
        rel_dir="apps/$name"
    fi
    abs_dir="$FN_ROOT/$rel_dir"

    if [[ -e "$abs_dir" ]]; then
        echo "init_cpp_app: $rel_dir ya existe" >&2
        return 1
    fi

    mkdir -p "$abs_dir"

    # ---------- main.cpp ----------
    cat > "$abs_dir/main.cpp" <<EOF
#include <imgui.h>
#include "app_base.h"
#include "core/panel_menu.h"
#include "core/icons_tabler.h"
#include "core/logger.h"
// #include "viz/data_table.h"  // uncomment to enable data_table::render() panel

// Toggles de paneles (visibles desde el menu View del menubar canonico)
static bool g_show_main = true;

static void draw_main() {
    if (!ImGui::Begin(TI_HOME " Main", &g_show_main)) {
        ImGui::End();
        return;
    }
    ImGui::TextUnformatted("Hello from $name");
    ImGui::End();
}

static void render() {
    // El framework dibuja menubar (View/Layouts/Settings/About) y un
    // DockSpaceOverViewport central (auto_dockspace=true por defecto).
    // Aqui solo se dibujan los paneles propios de la app.
    if (g_show_main) draw_main();

    // === Data panel (uncomment to enable) ===
    // static data_table::State data_state;
    // static std::vector<data_table::TableInput> data_tables; // populate from your source
    // data_table::render("main_data", data_tables, data_state);
}

int main(int /*argc*/, char** /*argv*/) {
    static fn_ui::PanelToggle panels[] = {
        { "Main", nullptr, &g_show_main },
    };

    fn::AppConfig cfg;
    cfg.title       = "$name — $desc";
    cfg.about       = { "$name", "0.1.0", "$desc" };
    cfg.log         = { "$name.log", 1 };
    cfg.panels      = panels;
    cfg.panel_count = sizeof(panels) / sizeof(panels[0]);

    return fn::run_app(cfg, render);
}
EOF

    # ---------- CMakeLists.txt ----------
    cat > "$abs_dir/CMakeLists.txt" <<EOF
add_imgui_app($name
    main.cpp
)
target_include_directories($name PRIVATE \${CMAKE_CURRENT_SOURCE_DIR})

# fn_table_viz: provides data_table::render(), viz_render, TQL engine, Lua, LLM.
# Guard keeps the app compilable in builds where vendor/lua is absent.
if(TARGET fn_table_viz)
    target_link_libraries($name PRIVATE fn_table_viz)
endif()

if(WIN32)
    set_target_properties($name PROPERTIES WIN32_EXECUTABLE TRUE)
endif()
EOF

    # ---------- app.md ----------
    local repo_url="https://gitea.organic-machine.com/dataforge/$name"
    local tags_yaml="[imgui]"
    if [[ -n "$tags" ]]; then
        # Convierte "a,b,c" -> "[a, b, c]"
        tags_yaml="[$(echo "$tags" | sed 's/,/, /g'), imgui]"
    fi

    cat > "$abs_dir/app.md" <<EOF
---
name: $name
lang: cpp
domain: $domain
description: "$desc"
tags: $tags_yaml
uses_functions:
  # Uncomment when using data_table::render() — provided via fn_table_viz:
  # - data_table_cpp_viz
  # - viz_render_cpp_viz
  # - compute_stage_cpp_core
  # - compute_pipeline_cpp_core
  # - compute_column_stats_cpp_core
  # - auto_detect_type_cpp_core
  # - tql_emit_cpp_core
  # - tql_apply_cpp_core
  # - lua_engine_cpp_core
  # - join_tables_cpp_core
  # - tql_to_sql_cpp_core
  # - llm_anthropic_cpp_core
uses_types: []
framework: "imgui"
entry_point: "main.cpp"
dir_path: "$rel_dir"
repo_url: "$repo_url"
---

# $name

$desc

## Build

\`\`\`bash
cd cpp && cmake --build build --target $name -j
\`\`\`

## Run

\`\`\`bash
./cpp/build/$name
\`\`\`
EOF

    # ---------- Registrar en cpp/CMakeLists.txt ----------
    local cpp_cmake="$FN_ROOT/cpp/CMakeLists.txt"
    if ! grep -q "# --- $name ---" "$cpp_cmake"; then
        if [[ -n "$project" ]]; then
            local upper
            upper="$(echo "$name" | tr '[:lower:]' '[:upper:]')"
            cat >> "$cpp_cmake" <<EOF

# --- $name (lives in projects/$project/apps/) ---
set(_${upper}_DIR \${CMAKE_SOURCE_DIR}/../projects/$project/apps/$name)
if(EXISTS \${_${upper}_DIR}/CMakeLists.txt)
    add_subdirectory(\${_${upper}_DIR} \${CMAKE_BINARY_DIR}/apps/$name)
endif()
EOF
        else
            local upper
            upper="$(echo "$name" | tr '[:lower:]' '[:upper:]')"
            cat >> "$cpp_cmake" <<EOF

# --- $name (lives in apps/, issue 0096) ---
set(_${upper}_DIR \${CMAKE_SOURCE_DIR}/../apps/$name)
if(EXISTS \${_${upper}_DIR}/CMakeLists.txt)
    add_subdirectory(\${_${upper}_DIR} \${CMAKE_BINARY_DIR}/apps/$name)
endif()
EOF
        fi
    fi

    # ---------- Git + Gitea ----------
    if [[ -n "${GITEA_URL:-}" && -n "${GITEA_TOKEN:-}" ]]; then
        ensure_repo_synced "$abs_dir" "dataforge" "$name" "master" "feat: scaffold $name via init_cpp_app" || \
            echo "init_cpp_app: warning — ensure_repo_synced fallo, repo no creado" >&2
    else
        echo "init_cpp_app: GITEA_URL/GITEA_TOKEN no seteados, omitiendo creacion de repo Gitea" >&2
        (cd "$abs_dir" && git init -b master >/dev/null 2>&1 || git init >/dev/null 2>&1)
    fi

    # ---------- fn index ----------
    if [[ -x "$FN_ROOT/fn" ]]; then
        (cd "$FN_ROOT" && ./fn index >/dev/null 2>&1) || \
            echo "init_cpp_app: warning — fn index fallo" >&2
    fi

    echo "init_cpp_app: $rel_dir creada"
    echo "  - Build: cd $FN_ROOT/cpp && cmake --build build --target $name -j"
    echo "  - app.md: $rel_dir/app.md (rellena uses_functions cuando uses funciones del registry)"
}

# Permitir invocacion directa via 'fn run init_cpp_app ...'
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    init_cpp_app "$@"
fi
