#pragma once

#include <string>
#include <vector>

// Sistema de proyectos: cada proyecto es una subcarpeta junto al exe que
// contiene sus propios `operations.db`, `types.yaml` y `graph_explorer.db`
// (layouts). El usuario crea proyectos, los nombra y conmuta entre ellos.
//
// Layout en disco (issue: convencion local_files):
//
//   <exe_dir>/
//     graph_explorer.exe
//     enrichers/, runtime/, *.ttf, ...    (read-only, distribuibles)
//     local_files/                        (escribibles, per-PC)
//       imgui.ini, app_settings.ini       (gestionados por fn_framework)
//       graph_explorer.ini                # last_active + recent
//       projects/
//         default/
//           operations.db
//           types.yaml
//           graph_explorer.db             # layouts del proyecto
//         caso_X/
//           ...

namespace ge {

// Helpers que resuelven a <exe_dir>/local_files/... via fn::local_path.
// Las constantes solo guardan el basename relativo a local_files/.
constexpr const char* k_projects_subdir = "projects";
constexpr const char* k_default_project = "default";
constexpr const char* k_settings_basename = "graph_explorer.ini";

// Devuelven paths absolutos resueltos contra local_files/ (creando la
// carpeta si no existe). Sustituyen el uso directo de los constexpr.
const char* projects_root();   // <exe>/local_files/projects
const char* settings_path();   // <exe>/local_files/graph_explorer.ini

struct ProjectPaths {
    std::string root_dir;        // <exe>/projects/<slug>/
    std::string operations_db;   // <root>/operations.db
    std::string types_yaml;      // <root>/types.yaml
    std::string layout_db;       // <root>/graph_explorer.db
};

// Valida slug (a-z, 0-9, _ y -). Devuelve true si es valido. error_msg
// describe el motivo del fallo.
bool project_validate_slug(const char* name, std::string* error_msg);

// Devuelve los paths del proyecto `slug`. NO comprueba existencia en disco.
ProjectPaths project_paths(const char* slug);

// Asegura que `<exe>/projects/` existe. Idempotente.
bool projects_root_ensure();

// Lista proyectos detectados (subdirs de `<exe>/projects/`). Ordenado alfa.
// Cada string es el slug (basename de la subcarpeta).
bool project_list(std::vector<std::string>* out);

// Devuelve true si la carpeta del proyecto existe y contiene operations.db.
bool project_exists(const char* slug);

// Crea el proyecto `slug`:
//   - mkdir <exe>/projects/<slug>/
//   - bootstrap operations.db con el DDL completo (entities, relations, fts, ...)
//   - escribe types.yaml semilla (basado en examples/types.yaml o embed)
// Devuelve false y rellena `error_msg` si falla.
bool project_create(const char* slug, std::string* error_msg);

// Migracion: si `<exe>/projects/` no existe pero hay operations.db en el cwd,
// crea projects/default/ y mueve operations.db + graph_explorer.db ahi.
// Idempotente: no-op si projects/ ya existe.
bool projects_migrate_legacy_layout();

// Migracion idempotente del schema de una operations.db existente.
// Detecta columnas/tablas ausentes via PRAGMA y aplica los ALTER TABLE
// minimos. Llamar al abrir un proyecto antes de cargar el grafo.
//
// Migraciones aplicadas:
//   - 0035a: ALTER TABLE entities ADD COLUMN group_id TEXT (si falta)
//
// Devuelve true si la BD esta al dia (o ya lo estaba). Si falla, rellena
// `error_msg` y devuelve false.
bool project_migrate_schema(const std::string& path, std::string* error_msg);

// Lee/escribe `graph_explorer.ini` (junto al exe). Formato:
//   last_active = <slug>
//   recent      = slug1,slug2,slug3
struct ProjectSettings {
    std::string         last_active;     // slug del ultimo proyecto abierto
    std::vector<std::string> recent;     // mas reciente primero, max 5
};

bool project_settings_load(ProjectSettings* out);
bool project_settings_save(const ProjectSettings& s);

// Marca `slug` como activo y lo empuja al frente de `recent`. Persiste en
// disco. No-op si slug es vacio.
void project_settings_touch(const char* slug);

// Abre la carpeta del proyecto en el explorador del sistema.
// (Windows: explorer.exe; Linux: xdg-open).
void project_reveal_in_explorer(const char* slug);

} // namespace ge
