#pragma once

// Ejecuta una tarea en un thread en background y expone su estado para que
// la UI pueda mostrar spinner + resultado. La tarea recibe un out-string
// por referencia y devuelve true si termino con exito.
//
// Uso:
//   static fn_ui::ProcessRunner reindex_runner;
//
//   if (button("Reindex", Primary) && !reindex_runner.is_busy()) {
//       fn_ui::runner_trigger(reindex_runner, [](std::string& out) -> bool {
//           return http_post("http://127.0.0.1:8484/api/reindex", "", &out);
//       });
//   }
//   fn_ui::runner_status(reindex_runner, "Reindexing...");

#include <atomic>
#include <functional>
#include <mutex>
#include <string>
#include <thread>

namespace fn_ui {

enum class RunnerState : int {
    Idle    = 0,
    Running = 1,
    Success = 2,
    Error   = 3,
};

class ProcessRunner {
public:
    ProcessRunner();
    ~ProcessRunner();
    ProcessRunner(const ProcessRunner&)            = delete;
    ProcessRunner& operator=(const ProcessRunner&) = delete;

    bool         is_busy()  const;
    RunnerState  state()    const;
    std::string  message()  const;   // thread-safe snapshot del ultimo message
    void         reset();            // vuelve a Idle (solo si no esta Running)

private:
    friend void runner_trigger(ProcessRunner&, std::function<bool(std::string&)>);
    friend void runner_status(const ProcessRunner&, const char*);

    std::atomic<int>       state_{0};
    mutable std::mutex     mu_;
    std::string            message_;
    std::thread            th_;
};

// Lanza `task` en background; al terminar, guarda el out-string y marca
// Success/Error. Si el runner ya esta corriendo, la llamada se ignora.
void runner_trigger(ProcessRunner& r,
                    std::function<bool(std::string&)> task);

// Renderiza inline un spinner ImGui + texto de estado segun runner.state.
// `running_label` es el texto mostrado mientras corre (e.g. "Reindexing...").
// En Success muestra el message completo en color success; en Error idem en
// error.
void runner_status(const ProcessRunner& r, const char* running_label);

} // namespace fn_ui
