/*
 * 自然写智能点阵笔嵌入式固件软件 V1.0
 * power_monitor_task.c - 电源监测与低功耗管理任务
 *
 * 功能说明：
 * 1. 电池电压ADC采样与电量百分比估算
 * 2. 充电检测与充电状态管理
 * 3. 低电量告警与自动关机保护
 * 4. 低功耗状态机（Active → Light Sleep → Deep Sleep）
 * 5. USB充电IC状态监测
 */

#include <stdint.h>
#include <stdbool.h>

#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"
#include "semphr.h"

#include "hal_adc.h"
#include "hal_gpio.h"
#include "power_manager.h"
#include "led_driver.h"

/* ========== 电池参数定义 ========== */

/* 电池满充电压（mV）：锂聚合物3.7V标称 */
#define BATTERY_FULL_MV             4200

/* 电池截止电压（mV）：低于此值必须关机保护 */
#define BATTERY_CUTOFF_MV           3300

/* 低电量告警阈值（百分比） */
#define LOW_BATTERY_THRESHOLD       10

/* 极低电量关机阈值 */
#define CRITICAL_BATTERY_THRESHOLD  3

/* ADC参考电压（mV） */
#define ADC_VREF_MV                 3300

/* ADC分辨率（12位） */
#define ADC_MAX_VALUE               4095

/* 电池电压分压比（电阻分压器：R1=100K, R2=100K → 2:1） */
#define BATTERY_DIVIDER_RATIO       2

/* 电压采样滤波窗口大小 */
#define VOLTAGE_FILTER_WINDOW       8

/* 电源监测周期（毫秒） */
#define POWER_MONITOR_PERIOD_MS     5000

/* 自动休眠超时（毫秒）：笔静止超过此时间自动进入深度睡眠 */
#define AUTO_SLEEP_TIMEOUT_MS       300000   /* 5分钟 */

/* ========== 电源状态枚举 ========== */

typedef enum {
    POWER_STATE_ACTIVE,             /* 活跃状态（正常工作） */
    POWER_STATE_LIGHT_SLEEP,        /* 轻度睡眠（BLE保持连接） */
    POWER_STATE_DEEP_SLEEP,         /* 深度睡眠（仅保留RTC唤醒） */
    POWER_STATE_CHARGING,           /* 充电中 */
    POWER_STATE_SHUTDOWN            /* 关机保护 */
} PowerState;

/* ========== 外部引用 ========== */

extern EventGroupHandle_t g_ble_event_group;
extern SemaphoreHandle_t g_system_mutex;

/* 系统状态结构体（在main.c中定义） */
typedef struct {
    bool pen_is_down;
    bool ble_connected;
    bool is_charging;
    uint8_t battery_percent;
    uint32_t total_strokes;
    uint32_t uptime_seconds;
    uint8_t error_flags;
} SystemState;

extern SystemState g_system_state;

/* ========== 静态变量 ========== */

/* 当前电源状态 */
static PowerState s_power_state = POWER_STATE_ACTIVE;

/* 电压采样滤波缓冲区 */
static uint16_t s_voltage_buffer[VOLTAGE_FILTER_WINDOW];
static uint8_t s_voltage_buffer_index = 0;
static bool s_voltage_buffer_full = false;

/* 最后一次活动时间（用于自动休眠判断） */
static uint32_t s_last_activity_time = 0;

/* ========== 电压采样与滤波 ========== */

/**
 * 读取电池原始ADC值并转换为电压（mV）
 */
static uint16_t read_battery_voltage_mv(void) {
    /* 读取ADC原始值 */
    uint16_t adc_raw = hal_adc_read(ADC_CHANNEL_BATTERY);

    /* ADC值 → 分压后电压 → 实际电池电压 */
    uint32_t voltage_mv = (uint32_t)adc_raw * ADC_VREF_MV / ADC_MAX_VALUE;
    voltage_mv *= BATTERY_DIVIDER_RATIO;

    return (uint16_t)voltage_mv;
}

/**
 * 移动平均滤波
 * 对连续采样的电压值取平均，消除ADC噪声
 *
 * @param new_sample  新采样的电压值（mV）
 * @return 滤波后的电压值
 */
static uint16_t voltage_filter(uint16_t new_sample) {
    s_voltage_buffer[s_voltage_buffer_index] = new_sample;
    s_voltage_buffer_index = (s_voltage_buffer_index + 1) % VOLTAGE_FILTER_WINDOW;

    if (s_voltage_buffer_index == 0) {
        s_voltage_buffer_full = true;
    }

    uint8_t count = s_voltage_buffer_full ? VOLTAGE_FILTER_WINDOW : s_voltage_buffer_index;
    uint32_t sum = 0;
    uint8_t i;
    for (i = 0; i < count; i++) {
        sum += s_voltage_buffer[i];
    }

    return (uint16_t)(sum / count);
}

/* ========== 电量百分比估算 ========== */

/**
 * 根据电池电压估算电量百分比
 * 使用分段线性插值模拟锂电池放电曲线
 *
 * 锂聚合物电池典型放电曲线（近似分段线性）：
 *   4200mV → 100%
 *   4060mV →  90%
 *   3920mV →  80%
 *   3830mV →  70%
 *   3750mV →  60%
 *   3680mV →  50%
 *   3620mV →  40%
 *   3570mV →  30%
 *   3500mV →  20%
 *   3400mV →  10%
 *   3300mV →   0%
 */
static uint8_t estimate_battery_percent(uint16_t voltage_mv) {
    /* 放电曲线查找表（电压mV → 百分比） */
    static const struct {
        uint16_t voltage;
        uint8_t percent;
    } discharge_curve[] = {
        {4200, 100},
        {4060,  90},
        {3920,  80},
        {3830,  70},
        {3750,  60},
        {3680,  50},
        {3620,  40},
        {3570,  30},
        {3500,  20},
        {3400,  10},
        {3300,   0}
    };

    const uint8_t table_size = sizeof(discharge_curve) / sizeof(discharge_curve[0]);

    /* 边界检查 */
    if (voltage_mv >= discharge_curve[0].voltage) {
        return 100;
    }
    if (voltage_mv <= discharge_curve[table_size - 1].voltage) {
        return 0;
    }

    /* 分段线性插值 */
    uint8_t i;
    for (i = 0; i < table_size - 1; i++) {
        if (voltage_mv >= discharge_curve[i + 1].voltage) {
            uint16_t v_high = discharge_curve[i].voltage;
            uint16_t v_low  = discharge_curve[i + 1].voltage;
            uint8_t  p_high = discharge_curve[i].percent;
            uint8_t  p_low  = discharge_curve[i + 1].percent;

            /* 线性插值 */
            uint16_t v_range = v_high - v_low;
            uint16_t v_offset = voltage_mv - v_low;

            return p_low + (uint8_t)((uint32_t)v_offset * (p_high - p_low) / v_range);
        }
    }

    return 0;
}

/* ========== 充电检测 ========== */

/**
 * 检测USB充电状态
 * 通过GPIO读取充电IC的状态引脚
 *
 * @return 0=未充电, 1=充电中, 2=充满
 */
static uint8_t detect_charging_state(void) {
    /* STAT1引脚：低电平=充电中，高电平=充满或未充电 */
    bool stat1 = hal_gpio_read(GPIO_CHARGE_STAT1);

    /* STAT2引脚：低电平=充满 */
    bool stat2 = hal_gpio_read(GPIO_CHARGE_STAT2);

    /* USB电源检测引脚 */
    bool usb_power = hal_gpio_read(GPIO_USB_DETECT);

    if (!usb_power) {
        return 0;   /* USB未连接，未充电 */
    }

    if (!stat1) {
        return 1;   /* 充电中 */
    }

    if (!stat2) {
        return 2;   /* 充满 */
    }

    return 0;
}

/* ========== LED状态指示 ========== */

/**
 * 根据电源状态和电量更新LED指示
 */
static void update_led_indication(uint8_t battery_percent, uint8_t charge_state) {
    if (charge_state == 1) {
        /* 充电中：绿色呼吸灯 */
        led_set_mode(LED_MODE_BREATH_GREEN);
    } else if (charge_state == 2) {
        /* 充满：绿色常亮 */
        led_set_mode(LED_MODE_SOLID_GREEN);
    } else if (battery_percent <= LOW_BATTERY_THRESHOLD) {
        /* 低电量：红色慢闪 */
        led_set_mode(LED_MODE_BLINK_RED);
    } else if (battery_percent <= CRITICAL_BATTERY_THRESHOLD) {
        /* 极低电量：红色快闪 */
        led_set_mode(LED_MODE_FAST_BLINK_RED);
    } else if (g_system_state.ble_connected) {
        /* 已连接：蓝色常亮 */
        led_set_mode(LED_MODE_SOLID_BLUE);
    } else {
        /* 未连接：蓝色慢闪 */
        led_set_mode(LED_MODE_BLINK_BLUE);
    }
}

/* ========== 低功耗管理 ========== */

/**
 * 进入轻度睡眠模式
 * 关闭不必要的外设，降低CPU频率
 * BLE连接保持，可被笔尖触摸或BLE命令唤醒
 */
static void enter_light_sleep(void) {
    if (s_power_state == POWER_STATE_LIGHT_SLEEP) {
        return;
    }

    /* 关闭摄像头 */
    camera_power_off();

    /* 关闭SPI（传感器通信） */
    hal_spi_disable(SPI_PORT_1);

    /* 降低CPU频率到16MHz */
    SystemClock_SetLow();

    /* LED关闭 */
    led_set_mode(LED_MODE_OFF);

    s_power_state = POWER_STATE_LIGHT_SLEEP;
}

/**
 * 进入深度睡眠模式
 * 关闭所有外设和BLE，仅保留RTC和GPIO唤醒
 * 适用于长时间不使用的场景
 */
static void enter_deep_sleep(void) {
    /* 断开BLE连接 */
    ble_gatt_disconnect();
    ble_gatt_stop_advertising();

    /* 关闭所有外设 */
    camera_power_off();
    hal_spi_disable(SPI_PORT_1);
    hal_i2c_disable(I2C_PORT_1);
    hal_adc_disable(ADC_CHANNEL_BATTERY);

    /* 保存系统状态到Flash */
    offline_storage_flush();

    /* 配置唤醒源（笔尖GPIO中断唤醒） */
    hal_gpio_set_wakeup(GPIO_PEN_TIP_PIN, GPIO_WAKEUP_RISING);

    /* 进入MCU深度睡眠模式（不应返回） */
    hal_enter_deep_sleep();
}

/**
 * 从轻度睡眠唤醒，恢复正常工作状态
 */
static void wake_from_light_sleep(void) {
    /* 恢复CPU频率 */
    SystemClock_Config();

    /* 重新使能SPI */
    hal_spi_enable(SPI_PORT_1);

    s_power_state = POWER_STATE_ACTIVE;
    s_last_activity_time = xTaskGetTickCount();
}

/* ========== 电源监测主任务 ========== */

/**
 * 电源监测任务（FreeRTOS任务函数）
 *
 * 运行流程：
 * 1. 定期读取电池电压并估算电量
 * 2. 检测充电状态
 * 3. 低电量告警和自动关机保护
 * 4. 更新LED状态指示
 * 5. 自动休眠判断
 */
void power_monitor_task(void *pvParameters) {
    (void)pvParameters;

    TickType_t last_wake_time = xTaskGetTickCount();
    s_last_activity_time = last_wake_time;

    while (1) {
        /* 读取并滤波电池电压 */
        uint16_t raw_mv = read_battery_voltage_mv();
        uint16_t filtered_mv = voltage_filter(raw_mv);

        /* 估算电量百分比 */
        uint8_t battery_percent = estimate_battery_percent(filtered_mv);

        /* 检测充电状态 */
        uint8_t charge_state = detect_charging_state();

        /* 更新全局系统状态 */
        if (xSemaphoreTake(g_system_mutex, pdMS_TO_TICKS(100)) == pdTRUE) {
            g_system_state.battery_percent = battery_percent;
            g_system_state.is_charging = (charge_state == 1);
            xSemaphoreGive(g_system_mutex);
        }

        /* 更新LED指示 */
        update_led_indication(battery_percent, charge_state);

        /* 低电量告警处理 */
        if (battery_percent <= LOW_BATTERY_THRESHOLD && charge_state == 0) {
            /* 通知上位机低电量 */
            xEventGroupSetBits(g_ble_event_group, EVT_LOW_BATTERY);
        }

        /* 极低电量自动关机保护 */
        if (battery_percent <= CRITICAL_BATTERY_THRESHOLD && charge_state == 0) {
            enter_deep_sleep();
        }

        /* 充电状态变化通知 */
        if (charge_state > 0) {
            xEventGroupSetBits(g_ble_event_group, EVT_CHARGING);
            s_power_state = POWER_STATE_CHARGING;
            s_last_activity_time = xTaskGetTickCount();
        }

        /* 自动休眠检查：笔没有书写且BLE空闲超时 */
        if (!g_system_state.pen_is_down && charge_state == 0) {
            uint32_t idle_time = (xTaskGetTickCount() - s_last_activity_time)
                                 * portTICK_PERIOD_MS;

            if (idle_time > AUTO_SLEEP_TIMEOUT_MS) {
                if (s_power_state == POWER_STATE_ACTIVE) {
                    enter_light_sleep();
                } else if (idle_time > AUTO_SLEEP_TIMEOUT_MS * 2) {
                    /* 静止超过10分钟，进入深度睡眠 */
                    enter_deep_sleep();
                }
            }
        } else {
            /* 有活动，重置计时器 */
            s_last_activity_time = xTaskGetTickCount();
            if (s_power_state == POWER_STATE_LIGHT_SLEEP) {
                wake_from_light_sleep();
            }
        }

        /* 休眠到下一个监测周期 */
        vTaskDelayUntil(&last_wake_time, pdMS_TO_TICKS(POWER_MONITOR_PERIOD_MS));
    }
}

/* ========== 外部查询接口 ========== */

/** 获取当前电量百分比（供其他模块调用） */
uint8_t power_get_battery_percent(void) {
    return g_system_state.battery_percent;
}

/** 获取当前电源状态 */
uint8_t power_get_state(void) {
    return (uint8_t)s_power_state;
}
