// =========================
// auth_api.c
// =========================

#include "auth_api.h"
#include "auth.h"
#include "esp_log.h"
#include "cJSON.h"
#include <string.h>

static const char *TAG = "auth_api";

// =================================
// Dummy user storage (static list)
// =================================

static struct {
    char username[128];
} users[10] = { /* {"admin"}, {"user1"} */ };

static int num_users = 2;

// =================================
// Handlers for Auth Methods (RFID)
// =================================

static esp_err_t auth_methods_get_handler(httpd_req_t *req) {
    httpd_resp_set_type(req, "application/json");
    cJSON *json = cJSON_CreateObject();
    cJSON_AddBoolToObject(json, "RFID", auth_is_enabled());
    char *str = cJSON_PrintUnformatted(json);
    httpd_resp_sendstr(req, str);
    free(str);
    cJSON_Delete(json);
    return ESP_OK;
}

static esp_err_t auth_methods_post_handler(httpd_req_t *req) {
    char buf[256];
    int len = httpd_req_recv(req, buf, sizeof(buf) - 1);
    if (len <= 0) {
        httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Erro ao receber dados");
        return ESP_FAIL;
    }

    buf[len] = '\0';
    cJSON *json = cJSON_Parse(buf);
    if (!json) {
        httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "JSON inválido");
        return ESP_FAIL;
    }

    cJSON *rfid = cJSON_GetObjectItem(json, "RFID");
    if (rfid && cJSON_IsBool(rfid)) {
        auth_set_enabled(cJSON_IsTrue(rfid));
    } else {
        cJSON_Delete(json);
        httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Campo 'RFID' inválido ou ausente");
        return ESP_FAIL;
    }

    cJSON_Delete(json);
    httpd_resp_sendstr(req, "Métodos de autenticação atualizados");
    return ESP_OK;
}

// =================================
// User Management Handlers
// =================================

static esp_err_t users_get_handler(httpd_req_t *req) {
    httpd_resp_set_type(req, "application/json");
    cJSON *root = cJSON_CreateObject();
    cJSON *list = cJSON_CreateArray();
    for (int i = 0; i < num_users; ++i) {
        cJSON *u = cJSON_CreateObject();
        cJSON_AddStringToObject(u, "username", users[i].username);
        cJSON_AddItemToArray(list, u);
    }
    cJSON_AddItemToObject(root, "users", list);
    char *str = cJSON_PrintUnformatted(root);
    httpd_resp_sendstr(req, str);
    free(str);
    cJSON_Delete(root);
    return ESP_OK;
}

static esp_err_t users_post_handler(httpd_req_t *req) {
    char buf[128];
    int len = httpd_req_recv(req, buf, sizeof(buf) - 1);
    if (len <= 0) return ESP_FAIL;

    buf[len] = '\0';

    if (num_users < 10) {
        strlcpy(users[num_users].username, buf, sizeof(users[num_users].username));
        num_users++;
        httpd_resp_sendstr(req, "Usuário adicionado com sucesso");
    } else {
        httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Limite de usuários atingido");
    }
    return ESP_OK;
}

static esp_err_t users_delete_handler(httpd_req_t *req) {
    char query[128];
    if (httpd_req_get_url_query_str(req, query, sizeof(query)) == ESP_OK) {
        char username[128];
        if (httpd_query_key_value(query, "username", username, sizeof(username)) == ESP_OK) {
            for (int i = 0; i < num_users; i++) {
                if (strcmp(users[i].username, username) == 0) {
                    for (int j = i; j < num_users - 1; j++) {
                        users[j] = users[j + 1];
                    }
                    num_users--;
                    httpd_resp_sendstr(req, "Usuário removido com sucesso");
                    return ESP_OK;
                }
            }
        }
    }
    httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Usuário não encontrado");
    return ESP_FAIL;
}

// =================================
// Tag Management Handlers
// =================================

static esp_err_t tags_get_handler(httpd_req_t *req) {
    httpd_resp_set_type(req, "application/json");
    cJSON *root = cJSON_CreateObject();
    cJSON *list = cJSON_CreateArray();

    int count = auth_get_tag_count();
    for (int i = 0; i < count; i++) {
        const char *tag = auth_get_tag_by_index(i);
        if (tag) {
            cJSON_AddItemToArray(list, cJSON_CreateString(tag));
        }
    }

    cJSON_AddItemToObject(root, "tags", list);
    char *str = cJSON_PrintUnformatted(root);
    httpd_resp_sendstr(req, str);
    free(str);
    cJSON_Delete(root);
    return ESP_OK;
}

static esp_err_t tags_delete_handler(httpd_req_t *req) {
    char query[128];
    if (httpd_req_get_url_query_str(req, query, sizeof(query)) == ESP_OK) {
        char tag[AUTH_TAG_MAX_LEN];
        if (httpd_query_key_value(query, "tag", tag, sizeof(tag)) == ESP_OK) {
            if (auth_remove_tag(tag)) {
                httpd_resp_sendstr(req, "Tag removida com sucesso");
                return ESP_OK;
            }
        }
    }
    httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Tag não encontrada ou inválida");
    return ESP_FAIL;
}

static esp_err_t tags_register_handler(httpd_req_t *req) {
    auth_wait_for_tag_registration();
    httpd_resp_sendstr(req, "Modo de registro de tag ativado");
    return ESP_OK;
}

// =================================
// Register All REST Endpoints
// =================================

void register_auth_handlers(httpd_handle_t server, void *ctx) {
    // Auth methods
    httpd_register_uri_handler(server, &(httpd_uri_t){
        .uri = "/api/v1/config/auth-methods",
        .method = HTTP_GET,
        .handler = auth_methods_get_handler,
        .user_ctx = ctx
    });
    httpd_register_uri_handler(server, &(httpd_uri_t){
        .uri = "/api/v1/config/auth-methods",
        .method = HTTP_POST,
        .handler = auth_methods_post_handler,
        .user_ctx = ctx
    });

    // Users
    httpd_register_uri_handler(server, &(httpd_uri_t){
        .uri = "/api/v1/config/users",
        .method = HTTP_GET,
        .handler = users_get_handler,
        .user_ctx = ctx
    });
    httpd_register_uri_handler(server, &(httpd_uri_t){
        .uri = "/api/v1/config/users",
        .method = HTTP_POST,
        .handler = users_post_handler,
        .user_ctx = ctx
    });
    httpd_register_uri_handler(server, &(httpd_uri_t){
        .uri = "/api/v1/config/users",
        .method = HTTP_DELETE,
        .handler = users_delete_handler,
        .user_ctx = ctx
    });

    // Tags
    httpd_register_uri_handler(server, &(httpd_uri_t){
        .uri = "/api/v1/config/tags",
        .method = HTTP_GET,
        .handler = tags_get_handler,
        .user_ctx = ctx
    });
    httpd_register_uri_handler(server, &(httpd_uri_t){
        .uri = "/api/v1/config/tags",
        .method = HTTP_DELETE,
        .handler = tags_delete_handler,
        .user_ctx = ctx
    });
    httpd_register_uri_handler(server, &(httpd_uri_t){
        .uri = "/api/v1/config/tags/register",
        .method = HTTP_POST,
        .handler = tags_register_handler,
        .user_ctx = ctx
    });
}
