#include <stdio.h>
#include "STATUS_LED.h"

static const char *TAG = "status_led";

// LED 引脚定义
#define STATUS_LED_1_PIN    (GPIO_NUM_8)
#define STATUS_LED_2_PIN    (GPIO_NUM_18)


// LED 控制结构体
typedef struct {
    gpio_num_t pin;
    led_state_t state;
    int blink_period_ms;
    bool current_level;  // 实际输出电平
    TaskHandle_t task_handle;
    bool task_running;
} status_led_t;

static status_led_t led1 = {.pin = STATUS_LED_1_PIN, .state = LED_OFF, .task_running = false};
static status_led_t led2 = {.pin = STATUS_LED_2_PIN, .state = LED_OFF, .task_running = false};

/**
 * @brief LED控制任务
 * 
 * @param param 指向LED结构体的指针
 */
static void led_control_task(void *param)
{
    status_led_t *led = (status_led_t *)param;
    
    while(led->task_running) {
        switch(led->state) {
            case LED_OFF:
                gpio_set_level(led->pin, 1); // 低电平点亮，所以高电平关闭
                vTaskDelay(100 / portTICK_PERIOD_MS); // 延迟100ms后再次检查状态
                break;
                
            case LED_ON:
                gpio_set_level(led->pin, 0); // 低电平点亮
                vTaskDelay(100 / portTICK_PERIOD_MS); // 延迟100ms后再次检查状态
                break;
                
            case LED_BLINK_SLOW:
                led->current_level = !led->current_level;
                gpio_set_level(led->pin, !led->current_level); // 反转输出以适应低电平点亮
                vTaskDelay(500 / portTICK_PERIOD_MS); // 慢闪周期500ms
                break;
                
            case LED_BLINK_FAST:
                led->current_level = !led->current_level;
                gpio_set_level(led->pin, !led->current_level); // 反转输出以适应低电平点亮
                vTaskDelay(100 / portTICK_PERIOD_MS); // 快闪周期100ms
                break;
                
            case LED_HEARTBEAT:
                // 心跳模式：快速亮两次，然后长灭
                gpio_set_level(led->pin, 0); // 点亮
                vTaskDelay(100 / portTICK_PERIOD_MS);
                gpio_set_level(led->pin, 1); // 熄灭
                vTaskDelay(100 / portTICK_PERIOD_MS);
                gpio_set_level(led->pin, 0); // 点亮
                vTaskDelay(100 / portTICK_PERIOD_MS);
                gpio_set_level(led->pin, 1); // 熄灭
                vTaskDelay(800 / portTICK_PERIOD_MS); // 间隔800ms
                break;
                
            default:
                gpio_set_level(led->pin, 1); // 默认关闭
                vTaskDelay(100 / portTICK_PERIOD_MS);
                break;
        }
    }
    
    // 任务结束前关闭LED（高电平关闭）
    gpio_set_level(led->pin, 1);
    vTaskDelete(NULL);
}

/**
 * @brief 初始化GPIO引脚为输出模式
 * 
 * @param led_pin LED使用的GPIO引脚
 */
static void init_gpio_pin(gpio_num_t led_pin)
{
    gpio_config_t io_conf = {};
    io_conf.intr_type = GPIO_INTR_DISABLE;
    io_conf.mode = GPIO_MODE_OUTPUT;
    io_conf.pin_bit_mask = (1ULL << led_pin);
    io_conf.pull_down_en = 0;
    io_conf.pull_up_en = 0;
    gpio_config(&io_conf);
    
    // 初始状态设为高电平（LED熄灭，适用于低电平点亮的LED）
    gpio_set_level(led_pin, 1);
}

/**
 * @brief 初始化状态LED
 * 
 * 配置两个LED引脚为输出模式并设置初始状态
 */
void status_led_init(void)
{
    init_gpio_pin(STATUS_LED_1_PIN);
    init_gpio_pin(STATUS_LED_2_PIN);
    
    // 启动LED控制任务
    led1.task_running = true;
    xTaskCreate(led_control_task, "led1_control", 2048, &led1, 5, &led1.task_handle);
    
    led2.task_running = true;
    xTaskCreate(led_control_task, "led2_control", 2048, &led2, 5, &led2.task_handle);
    
    ESP_LOGI(TAG, "Status LEDs initialized on pins GPIO%d and GPIO%d", 
             STATUS_LED_1_PIN, STATUS_LED_2_PIN);
}

/**
 * @brief 控制指定LED的状态
 * 
 * @param led_num LED编号 (1 或 2)
 * @param state LED状态 (0=关闭, 1=开启)
 */
void status_led_set(uint8_t led_num, uint8_t state)
{
    status_led_t *led = NULL;
    
    if (led_num == 1) {
        led = &led1;
    } else if (led_num == 2) {
        led = &led2;
    } else {
        ESP_LOGE(TAG, "Invalid LED number: %d", led_num);
        return;
    }
    
    if (state == 1) {
        led->state = LED_ON;
    } else {
        led->state = LED_OFF;
    }
    
    ESP_LOGD(TAG, "LED %d set to %s", led_num, state ? "ON" : "OFF");
}

/**
 * @brief 切换指定LED的状态
 * 
 * @param led_num LED编号 (1 或 2)
 */
void status_led_toggle(uint8_t led_num)
{
    status_led_t *led = NULL;
    
    if (led_num == 1) {
        led = &led1;
    } else if (led_num == 2) {
        led = &led2;
    } else {
        ESP_LOGE(TAG, "Invalid LED number: %d", led_num);
        return;
    }
    
    if (led->state == LED_ON) {
        led->state = LED_OFF;
    } else if (led->state == LED_OFF) {
        led->state = LED_ON;
    }
    
    ESP_LOGD(TAG, "LED %d toggled", led_num);
}

/**
 * @brief 设置LED为闪烁模式
 * 
 * @param led_num LED编号 (1 或 2)
 * @param mode 闪烁模式 (0=慢闪, 1=快闪, 2=心跳)
 */
void status_led_blink_mode(uint8_t led_num, uint8_t mode)
{
    status_led_t *led = NULL;
    
    if (led_num == 1) {
        led = &led1;
    } else if (led_num == 2) {
        led = &led2;
    } else {
        ESP_LOGE(TAG, "Invalid LED number: %d", led_num);
        return;
    }
    
    switch(mode) {
        case 0: // 慢闪
            led->state = LED_BLINK_SLOW;
            break;
        case 1: // 快闪
            led->state = LED_BLINK_FAST;
            break;
        case 2: // 心跳
            led->state = LED_HEARTBEAT;
            break;
        default:
            ESP_LOGE(TAG, "Invalid blink mode: %d", mode);
            return;
    }
    
    ESP_LOGD(TAG, "LED %d set to blink mode %d", led_num, mode);
}

/**
 * @brief 销毁LED控制任务
 * 
 * @param led_num LED编号 (1 或 2)
 */
void status_led_deinit(uint8_t led_num)
{
    status_led_t *led = NULL;
    
    if (led_num == 1) {
        led = &led1;
    } else if (led_num == 2) {
        led = &led2;
    } else {
        ESP_LOGE(TAG, "Invalid LED number: %d", led_num);
        return;
    }
    
    if (led->task_running) {
        led->task_running = false;
        if (led->task_handle) {
            vTaskDelete(led->task_handle);
            led->task_handle = NULL;
        }
        gpio_set_level(led->pin, 1); // 关闭LED（高电平关闭）
    }
}

/**
 * @brief 获取LED当前状态
 * 
 * @param led_num LED编号 (1 或 2)
 * @return 当前LED状态
 */
led_state_t status_led_get_state(uint8_t led_num)
{
    if (led_num == 1) {
        return led1.state;
    } else if (led_num == 2) {
        return led2.state;
    } else {
        ESP_LOGE(TAG, "Invalid LED number: %d", led_num);
        return LED_OFF;
    }
}
