#include <stdio.h>
#include <string.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/queue.h>
#include <esp_log.h>
#include <wiegand.h>
#include "auth.h"

#define CONFIG_EXAMPLE_BUF_SIZE 50

static const char *TAG = "WiegandReader";

static wiegand_reader_t reader;
static QueueHandle_t queue = NULL;

typedef struct {
    uint8_t data[CONFIG_EXAMPLE_BUF_SIZE];
    size_t bits;
} data_packet_t;

static void reader_callback(wiegand_reader_t *r) {
    data_packet_t p;
    p.bits = r->bits;
    memcpy(p.data, r->buf, CONFIG_EXAMPLE_BUF_SIZE);
    xQueueSendToBack(queue, &p, 0);
}

static void wiegand_task(void *arg) {
    queue = xQueueCreate(5, sizeof(data_packet_t));
    if (!queue) {
        ESP_LOGE(TAG, "Failed to create queue");
        vTaskDelete(NULL);
        return;
    }

    ESP_ERROR_CHECK(wiegand_reader_init(&reader, 21, 22,
        true, CONFIG_EXAMPLE_BUF_SIZE, reader_callback, WIEGAND_MSB_FIRST, WIEGAND_LSB_FIRST));

    data_packet_t p;
    while (1) {
        ESP_LOGI(TAG, "Waiting for Wiegand data...");
        if (xQueueReceive(queue, &p, portMAX_DELAY) == pdPASS) {
            ESP_LOGI(TAG, "Bits received: %d", p.bits);

            char tag[20] = {0};

            if (p.bits == 26) {
                snprintf(tag, sizeof(tag), "%03d%03d%03d", p.data[0], p.data[1], p.data[2]);
            } else if (p.bits == 34) {
                snprintf(tag, sizeof(tag), "%03d%03d%03d%03d", p.data[0], p.data[1], p.data[2], p.data[3]);
            } else {
                ESP_LOGW(TAG, "Unsupported bit length: %d", (int)p.bits);
                continue;
            }

            ESP_LOGI(TAG, "Tag read: %s", tag);
            auth_process_tag(tag);  // agora delega toda a lógica à auth.c
        }
    }
}

void initWiegand(void) {
    ESP_LOGI(TAG, "Initializing Wiegand reader");
    xTaskCreate(wiegand_task, TAG, configMINIMAL_STACK_SIZE * 4, NULL, 4, NULL);
}
