#include <sys/param.h>
#include <freertos/FreeRTOS.h>
#include "freertos/task.h"
#include "esp_log.h"
#include "ntc_sensor.h"
#include "ntc_driver.h"
#include "adc.h"

static const char *TAG = "temp_sensor";

#define MEASURE_PERIOD 15000 // 15s

static float temp = 0.0f;
static ntc_device_handle_t ntc = NULL;
static portMUX_TYPE temp_mux = portMUX_INITIALIZER_UNLOCKED;

static void ntc_sensor_task_func(void *param)
{
    float t;
    while (true)
    {
        if (ntc_dev_get_temperature(ntc, &t) == ESP_OK)
        {
            portENTER_CRITICAL(&temp_mux);
            temp = t;
            portEXIT_CRITICAL(&temp_mux);
        }
        vTaskDelay(pdMS_TO_TICKS(MEASURE_PERIOD));
    }
}

float ntc_temp_sensor(void)
{
    float t;
    portENTER_CRITICAL(&temp_mux);
    t = temp;
    portEXIT_CRITICAL(&temp_mux);
    return t;
}

void ntc_sensor_init(void)
{
    ESP_LOGI(TAG, "ntc_sensor_init");

    ntc_config_t ntc_config = {
        .b_value = 3950,
        .r25_ohm = 10000,
        .fixed_ohm = 11000,
        .vdd_mv = 3300,
        .circuit_mode = CIRCUIT_MODE_NTC_GND,
        .atten = ADC_ATTEN_DB_12,
        .channel = ADC_CHANNEL_0,
        .unit = ADC_UNIT_1};

    // Criar driver e inicializar ADC
    // adc_oneshot_unit_handle_t adc_handle = NULL;
    ESP_ERROR_CHECK(ntc_dev_create(&ntc_config, &ntc, &adc_handle));
    ESP_ERROR_CHECK(ntc_dev_get_adc_handle(ntc, &adc_handle));

    // Leitura inicial para log
    float t0 = 0.0f;
    esp_err_t err = ntc_dev_get_temperature(ntc, &t0);
    if (err == ESP_OK)
    {
        portENTER_CRITICAL(&temp_mux);
        temp = t0;
        portEXIT_CRITICAL(&temp_mux);
        ESP_LOGI(TAG, "Temperatura inicial: %.2f °C", t0);
    }
    else
    {
        ESP_LOGW(TAG, "Falha na leitura inicial: %s", esp_err_to_name(err));
    }

    // Tarefa periódica
    xTaskCreate(ntc_sensor_task_func, "ntc_sensor_task", 5 * 1024, NULL, 3, NULL);
}
