#include "esp_log.h"
#include "driver/gpio.h"

#include "ac_relay.h"
#include "board_config.h"

static const char* TAG = "ac_relay";

// Memoization do estado atual do relé (salvo em RAM)
static int last_state = -1;

/**
 * @brief Initialize the AC relay GPIO.
 *
 * Configures the specified GPIO pin as an output and sets its initial state to OFF (low).
 */
void ac_relay_init(void)
{
    gpio_config_t conf = {
        .pin_bit_mask = BIT64(board_config.ac_relay_gpio),
        .mode = GPIO_MODE_OUTPUT,
        .pull_down_en = GPIO_PULLDOWN_DISABLE,
        .pull_up_en = GPIO_PULLUP_DISABLE,
        .intr_type = GPIO_INTR_DISABLE
    };

    esp_err_t ret = gpio_config(&conf);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "Failed to configure GPIO (error: %s)", esp_err_to_name(ret));
        return;
    }

    gpio_set_level(board_config.ac_relay_gpio, 0);  ///< Ensure relay starts OFF
    last_state = 0;
    ESP_LOGI(TAG, "AC relay initialized. Pin: %d", board_config.ac_relay_gpio);
}

/**
 * @brief Set the state of the AC relay.
 *
 * @param state True to turn the relay ON, False to turn it OFF.
 */
void ac_relay_set_state(bool state)
{
    if (state == last_state) {
        // Estado não mudou; evita log e escrita desnecessária.
        return;
    }
    last_state = state;

    ESP_LOGI(TAG, "Setting AC relay state: Pin: %d, State: %d", board_config.ac_relay_gpio, state);

    esp_err_t ret = gpio_set_level(board_config.ac_relay_gpio, state ? 1 : 0);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "Failed to set GPIO level (error: %s)", esp_err_to_name(ret));
    }
}

/**
 * @brief Get the current state of the AC relay.
 *
 * @return true if the relay is ON, false if OFF.
 */
bool ac_relay_get_state(void)
{
    int level = gpio_get_level(board_config.ac_relay_gpio);
    ESP_LOGD(TAG, "Current AC relay state: Pin: %d, State: %d", board_config.ac_relay_gpio, level);
    return (level != 0);
}
