#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/pwm.h"
#include "esp_log.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_bt.h"
#include "esp_gap_ble_api.h"
#include "esp_gattc_api.h"
#include "esp_gatts_api.h"
#include "esp_gatt_common_api.h"

#define BUTTON_A_GPIO GPIO_NUM_5
#define BUTTON_B_GPIO GPIO_NUM_6
#define BUTTON_C_GPIO GPIO_NUM_7
#define LED_GPIO GPIO_NUM_16

#define PWM_CHANNEL PWM_CHANNEL_0
#define PWM_FREQ 1000
#define PWM_RES 100

#define GATTS_TAG "GATTS_DEMO"
#define GATTS_SERVICE_UUID 0x00FF
#define GATTS_CHAR_UUID_LED_ON_OFF 0xFF01
#define GATTS_CHAR_UUID_LED_BRIGHTNESS 0xFF02
#define GATTS_CHAR_UUID_LED_CONTROL 0xFF03

static bool led_on = false;
static int led_brightness = 0;

// 定义蓝牙服务和特征值UUID
static uint16_t gatts_service_uuid = GATTS_SERVICE_UUID;
static uint16_t gatts_char_uuid_led_on_off = GATTS_CHAR_UUID_LED_ON_OFF;
static uint16_t gatts_char_uuid_led_brightness = GATTS_CHAR_UUID_LED_BRIGHTNESS;
static uint16_t gatts_char_uuid_led_control = GATTS_CHAR_UUID_LED_CONTROL;

// 定义蓝牙特征值句柄
static uint16_t gatts_handle_table[3];

// 定义解析BLE指令的函数
static void parse_ble_command(uint8_t *value, size_t len) {
    switch (value[0]) {
        case 0x01:  // LED开关
            if (len == 2) {
                if (value[1] == 0x01) {
                    led_on = true;
                    pwm_set_duty(PWM_CHANNEL, led_brightness);
                    pwm_start();
                }
                else if (value[1] == 0x00) {
                    led_on = false;
                    pwm_stop();
                }
            }
            break;
        case 0x02:  // 逐级增减LED亮度
            if (len == 2) {
                int delta = (value[1] == 0x01 ? 1 : -1);
                led_brightness += delta;
                if (led_brightness < 0) {
                    led_brightness = 0;
                }
                else if (led_brightness > PWM_RES) {
                    led_brightness = PWM_RES;
                }
                if (led_on) {
                    pwm_set_duty(PWM_CHANNEL, led_brightness);
                    pwm_start();
                }
            }
            break;
        case 0x03:  // 直接指定LED亮度
            if (len == 2) {
                led_brightness = value[1];
                if (led_brightness < 0) {
                    led_brightness = 0;
                }
                else if (led_brightness > PWM_RES) {
                    led_brightness = PWM_RES;
                }
                if (
                led_on) {
                pwm_set_duty(PWM_CHANNEL, led_brightness);
                pwm_start();
            }
        }
        break;
    default:
        break;
}
}

// 定义BLE GATT Server回调函数
static esp_gatts_cb_event_t gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) {
switch (event) {
case ESP_GATTS_REG_EVT:
// 注册GATT服务
esp_err_t create_attr_ret = esp_ble_gatts_create_attr_tab((esp_gatts_attr_db_t *)param->reg.create.handles, gatts_if, 3, 0);
if (create_attr_ret != ESP_OK) {
ESP_LOGE(GATTS_TAG, "create attr table failed, error code = %x", create_attr_ret);
}
else {
// 保存特征值句柄
memcpy(gatts_handle_table, param->reg.create.handles, sizeof(gatts_handle_table));
}
break;
case ESP_GATTS_READ_EVT:
break;
case ESP_GATTS_WRITE_EVT:
if (param->write.is_prep) {
break;
}
if (param->write.need_rsp) {
esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL);
}
parse_ble_command(param->write.value, param->write.len);
break;
default:
break;
}
return ESP_GATT_OK;
}

// 定义按钮A的中断处理函数
static void IRAM_ATTR button_a_isr_handler(void *arg) {
static uint64_t button_a_pressed_time = 0;
uint64_t button_a_current_time = esp_timer_get_time();
if (gpio_get_level(BUTTON_A_GPIO) == 0) {
button_a_pressed_time = button_a_current_time;
}
else {
if (button_a_current_time - button_a_pressed_time > 500000) { // 长按
led_brightness--;
if (led_brightness < 0) {
led_brightness = 0;
}
pwm_set_duty(PWM_CHANNEL, led_brightness);
pwm_start();
}
else { // 短按
led_brightness++;
if (led_brightness > PWM_RES) {
led_brightness = PWM_RES;
}
pwm_set_duty(PWM_CHANNEL, led_brightness);
pwm_start();
}
}
}

// 定义按钮B的中断处理函数
static void IRAM_ATTR button_b_isr_handler(void *arg) {
static uint64_t button_b_pressed_time = 0;
uint64_t button_b_current_time = esp_timer_get_time();
if (gpio_get_level(BUTTON_B_GPIO) == 0) {
button_b_pressed_time = button_b_current_time;
}
else {
if (button_b_current_time - button_b_pressed_time > 500000) { // 长按
led_brightness++;
if (led_brightness > PWM_RES) {
led_brightness = PWM_RES;
}
pwm_set_duty(PWM_CHANNEL, led_brightness);
pwm_start();
}
else { // 短按
led_brightness--;
if (led_brightness < 0) {
led_brightness = 0;
}
pwm_set_duty(PWM_CHANNEL, led_brightness);
pwm_start();
}
}
}

// 定义按钮C的中断处理函数
static void IRAM_ATTR button_c_isr_handler(void *arg) {
           bool led_on = false;
           if (gpio_get_level(LED_GPIO) == 0) {
           led_on = true;
           }
           led_on = !led_on;
           gpio_set_level(LED_GPIO, led_on ? 1 : 0);
           }

           void app_main() {
           // 初始化GPIO
           gpio_pad_select_gpio(BUTTON_A_GPIO);
           gpio_pad_select_gpio(BUTTON_B_GPIO);
           gpio_pad_select_gpio(BUTTON_C_GPIO);
           gpio_pad_select_gpio(LED_GPIO);
           gpio_set_direction(BUTTON_A_GPIO, GPIO_MODE_INPUT);
           gpio_set_direction(BUTTON_B_GPIO, GPIO_MODE_INPUT);
           gpio_set_direction(BUTTON_C_GPIO, GPIO_MODE_INPUT);
           gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT);
           gpio_set_level(LED_GPIO, 0);

           // 初始化PWM
           pwm_init(PWM_CHANNEL, NULL);
           pwm_set_freq(PWM_CHANNEL, PWM_FREQ);
           pwm_set_duty(PWM_CHANNEL, 0);
           pwm_start();

           // 设置按钮A的中断
           gpio_set_intr_type(BUTTON_A_GPIO, GPIO_INTR_ANYEDGE);
           gpio_install_isr_service(0);
           gpio_isr_handler_add(BUTTON_A_GPIO, button_a_isr_handler, NULL);

           // 设置按钮B的中断
           gpio_set_intr_type(BUTTON_B_GPIO, GPIO_INTR_ANYEDGE);
           gpio_isr_handler_add(BUTTON_B_GPIO, button_b_isr_handler, NULL);

           // 设置按钮C的中断
           gpio_set_intr_type(BUTTON_C_GPIO, GPIO_INTR_ANYEDGE);
           gpio_isr_handler_add(BUTTON_C_GPIO, button_c_isr_handler, NULL);

           // 初始化BLE
           esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
           esp_bt_controller_init(&bt_cfg);
           esp_bt_controller_enable(ESP_BT_MODE_BTDM);

           esp_bluedroid_init();
           esp_bluedroid_enable();

           esp_ble_gatts_register_callback(gatts_event_handler);
           esp_ble_gatts_app_register(APP_ID);
}