#include "button.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "esp_timer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"

static const char *TAG = "BTN";

// 去抖间隔（微秒）
#define DEBOUNCE_US 200000

// 按键事件队列
static QueueHandle_t btn_evt_queue = NULL;

// 回调存储
typedef struct {
    btn_event_cb_t cb;
    void *usr_data;
} btn_cb_t;

static btn_cb_t boot_cb = {0};
static btn_cb_t key2_cb = {0};

// 去抖时间戳
static int64_t last_boot_us = 0;
static int64_t last_key2_us = 0;

// GPIO中断服务函数（ISR中不做耗时操作，仅发送事件到队列）
static void IRAM_ATTR gpio_isr_handler(void *arg)
{
    int gpio_num = (int)arg;
    xQueueSendFromISR(btn_evt_queue, &gpio_num, NULL);
}

// 按键事件处理任务
static void btn_task(void *pvParameters)
{
    int gpio_num;
    while (1) {
        if (xQueueReceive(btn_evt_queue, &gpio_num, portMAX_DELAY)) {
            int64_t now = esp_timer_get_time();

            if (gpio_num == PIN_BTN_BOOT) {
                if (now - last_boot_us > DEBOUNCE_US) {
                    last_boot_us = now;
                    ESP_LOGI(TAG, "BOOT按键按下 (GPIO%d)", gpio_num);
                    if (boot_cb.cb) {
                        boot_cb.cb(gpio_num, boot_cb.usr_data);
                    }
                }
            } else if (gpio_num == PIN_BTN_KEY2) {
                if (now - last_key2_us > DEBOUNCE_US) {
                    last_key2_us = now;
                    ESP_LOGI(TAG, "KEY2按键按下 (GPIO%d)", gpio_num);
                    if (key2_cb.cb) {
                        key2_cb.cb(gpio_num, key2_cb.usr_data);
                    }
                }
            }
        }
    }
}

esp_err_t button_init(void)
{
    btn_evt_queue = xQueueCreate(10, sizeof(int));

    // 配置GPIO为输入模式，内部上拉，下降沿触发中断
    gpio_config_t io_conf = {
        .pin_bit_mask = (1ULL << PIN_BTN_BOOT) | (1ULL << PIN_BTN_KEY2),
        .mode = GPIO_MODE_INPUT,
        .pull_up_en = GPIO_PULLUP_ENABLE,
        .pull_down_en = GPIO_PULLDOWN_DISABLE,
        .intr_type = GPIO_INTR_NEGEDGE,
    };
    gpio_config(&io_conf);

    // 安装GPIO中断服务（如果已安装则跳过）
    esp_err_t ret = gpio_install_isr_service(0);
    if (ret != ESP_OK && ret != ESP_ERR_INVALID_STATE) {
        ESP_LOGE(TAG, "GPIO ISR服务安装失败");
        return ret;
    }

    gpio_isr_handler_add(PIN_BTN_BOOT, gpio_isr_handler, (void *)PIN_BTN_BOOT);
    gpio_isr_handler_add(PIN_BTN_KEY2, gpio_isr_handler, (void *)PIN_BTN_KEY2);

    // 按键处理任务
    xTaskCreate(btn_task, "btn_task", 3072, NULL, 5, NULL);

    ESP_LOGI(TAG, "按键初始化完成 (BOOT=GPIO%d, KEY2=GPIO%d)", PIN_BTN_BOOT, PIN_BTN_KEY2);
    return ESP_OK;
}

void button_on_boot_press(btn_event_cb_t cb, void *usr_data)
{
    boot_cb.cb = cb;
    boot_cb.usr_data = usr_data;
}

void button_on_key2_press(btn_event_cb_t cb, void *usr_data)
{
    key2_cb.cb = cb;
    key2_cb.usr_data = usr_data;
}
