#pragma once

#include "esp_http_server.h"
#include "cJSON.h"

class WebServer {
public:
    static WebServer& instance();

    void start();
    void stop();
    bool isRunning() const { return server_ != nullptr; }

private:
    WebServer() = default;
    ~WebServer();
    WebServer(const WebServer&) = delete;
    WebServer& operator=(const WebServer&) = delete;

    httpd_handle_t server_ = nullptr;

    // Static file handlers (StaticFileHandlers.cpp)
    static esp_err_t rootHandler(httpd_req_t* req);
    static esp_err_t staticFileHandler(httpd_req_t* req);
    static esp_err_t imagesHandler(httpd_req_t* req);

    // Config handlers (ConfigHandlers.cpp)
    static esp_err_t getConfigHandler(httpd_req_t* req);
    static esp_err_t postConfigHandler(httpd_req_t* req);
    static esp_err_t postSaveHandler(httpd_req_t* req);
    static esp_err_t postResetHandler(httpd_req_t* req);

    // KNX handlers (KnxHandlers.cpp)
    static esp_err_t getKnxAddressesHandler(httpd_req_t* req);
    static esp_err_t getKnxProgHandler(httpd_req_t* req);
    static esp_err_t postKnxProgHandler(httpd_req_t* req);
    static esp_err_t postKnxResetHandler(httpd_req_t* req);

    // Status handlers (StatusHandlers.cpp)
    static esp_err_t getStatusHandler(httpd_req_t* req);

    // File manager handlers (FileManagerHandlers.cpp)
    static esp_err_t fileManagerHandler(httpd_req_t* req);
    static esp_err_t filesListHandler(httpd_req_t* req);
    static esp_err_t filesUploadHandler(httpd_req_t* req);
    static esp_err_t filesDownloadHandler(httpd_req_t* req);
    static esp_err_t filesDeleteHandler(httpd_req_t* req);
    static esp_err_t filesMkdirHandler(httpd_req_t* req);
    static esp_err_t filesReadHandler(httpd_req_t* req);
    static esp_err_t filesWriteHandler(httpd_req_t* req);

public:
    // Shared utility functions (used by handlers)
    static const char* getContentType(const char* filepath);
    static esp_err_t sendFile(httpd_req_t* req, const char* filepath);
    static bool getQueryParam(httpd_req_t* req, const char* key, char* value, size_t maxLen);

    // JSON response helpers
    static esp_err_t sendJsonObject(httpd_req_t* req, cJSON* json);
    static esp_err_t sendJsonError(httpd_req_t* req, const char* error);
    static esp_err_t sendJsonSuccess(httpd_req_t* req);
};

// Case-insensitive path resolution for FAT filesystem
bool resolveCaseInsensitivePath(const char* requestedPath, char* resolvedPath, size_t maxLen);

// URL decode helper
void urlDecode(char* str);
