#ifndef VEML7700_H
#define VEML7700_H

#include "i2c_device.h"
#include "esp_log.h"
#include <cstdint>

// VEML7700 I2C地址（7-bit）
#define VEML7700_I2C_ADDR       0x10

// VEML7700 寄存器地址（命令码）
#define VEML7700_REG_ALS_CONF   0x00    // ALS配置寄存器
#define VEML7700_REG_ALS_WH     0x01    // 高阈值窗口设置
#define VEML7700_REG_ALS_WL     0x02    // 低阈值窗口设置
#define VEML7700_REG_PSM        0x03    // 省电模式配置
#define VEML7700_REG_ALS        0x04    // ALS数据输出寄存器
#define VEML7700_REG_WHITE      0x05    // 白光通道数据输出寄存器
#define VEML7700_REG_ALS_INT    0x06    // 中断状态寄存器

// 增益设置（ALS_CONF[12:11]）
typedef enum {
    VEML7700_GAIN_1   = 0x00,   // 增益 x1
    VEML7700_GAIN_2   = 0x01,   // 增益 x2
    VEML7700_GAIN_D8  = 0x02,   // 增益 x(1/8)
    VEML7700_GAIN_D4  = 0x03,   // 增益 x(1/4)
} veml7700_gain_t;

// 积分时间设置（ALS_CONF[9:6]）
typedef enum {
    VEML7700_IT_25MS  = 0x0C,   // 25ms
    VEML7700_IT_50MS  = 0x08,   // 50ms
    VEML7700_IT_100MS = 0x00,   // 100ms（默认）
    VEML7700_IT_200MS = 0x01,   // 200ms
    VEML7700_IT_400MS = 0x02,   // 400ms
    VEML7700_IT_800MS = 0x03,   // 800ms
} veml7700_it_t;

// 持续保护次数设置（ALS_CONF[5:4]）
typedef enum {
    VEML7700_PERS_1 = 0x00,     // 1次
    VEML7700_PERS_2 = 0x01,     // 2次
    VEML7700_PERS_4 = 0x02,     // 4次
    VEML7700_PERS_8 = 0x03,     // 8次
} veml7700_pers_t;

// 省电模式设置（PSM[2:1]）
typedef enum {
    VEML7700_PSM_1 = 0x00,      // 模式1（刷新700ms @ IT=100ms）
    VEML7700_PSM_2 = 0x01,      // 模式2（刷新1100ms @ IT=100ms）
    VEML7700_PSM_3 = 0x02,      // 模式3（刷新1800ms @ IT=100ms）
    VEML7700_PSM_4 = 0x03,      // 模式4（刷新3400ms @ IT=100ms）
} veml7700_psm_t;

// VEML7700 读取数据结构
typedef struct {
    uint16_t als_raw;           // ALS原始计数值
    uint16_t white_raw;         // 白光通道原始计数值
    float als_lux;              // ALS计算后的Lux值
    float white_lux;            // 白光通道计算后的Lux值
} veml7700_data_t;

// 自动量程测量结果（包含最终使用的增益和积分时间）
typedef struct {
    float lux;                  // 校正后的Lux值
    uint16_t raw;               // 最终原始计数值
    veml7700_gain_t gain;       // 自动选择的增益
    veml7700_it_t it;           // 自动选择的积分时间
} veml7700_auto_data_t;

class VEML7700 : public I2cDevice {
public:
    VEML7700(i2c_master_bus_handle_t i2c_bus, uint8_t addr = VEML7700_I2C_ADDR);
    ~VEML7700() = default;

    // 初始化传感器，配置默认参数
    esp_err_t Init();

    // 配置增益
    esp_err_t SetGain(veml7700_gain_t gain);
    veml7700_gain_t GetGain() const { return gain_; }

    // 配置积分时间
    esp_err_t SetIntegrationTime(veml7700_it_t it);
    veml7700_it_t GetIntegrationTime() const { return it_; }

    // 配置持续保护次数
    esp_err_t SetPersistence(veml7700_pers_t pers);

    // 省电模式
    esp_err_t SetPowerSaving(veml7700_psm_t mode, bool enable);

    // 中断使能/禁用
    esp_err_t SetInterruptEnable(bool enable);

    // 设置中断阈值
    esp_err_t SetThresholdHigh(uint16_t threshold);
    esp_err_t SetThresholdLow(uint16_t threshold);

    // 关机/唤醒
    esp_err_t Shutdown(bool sd);

    // 读取原始数据
    esp_err_t ReadALSRaw(uint16_t* raw);
    esp_err_t ReadWhiteRaw(uint16_t* raw);

    // 读取Lux值（带非线性校正）
    esp_err_t ReadALSLux(float* lux);
    esp_err_t ReadWhiteLux(float* lux);

    // 一次性读取所有数据
    esp_err_t ReadAll(veml7700_data_t* data);

    // 读取中断状态
    esp_err_t ReadInterruptStatus(bool* high_triggered, bool* low_triggered);

    // 获取当前配置下的采样等待时间（ms）
    uint32_t GetSampleDelayMs() const;

    // ---- 自动量程接口 ----
    // 自动调节增益和积分时间，在任意光照条件下获取最优测量结果
    // 强光下自动降低灵敏度避免溢出，弱光下自动提高灵敏度获得精度
    // 注意：此函数会修改当前增益和积分时间设置，且耗时较长（最长约5秒）
    esp_err_t ReadAutoALSLux(veml7700_auto_data_t* result);
    esp_err_t ReadAutoWhiteLux(veml7700_auto_data_t* result);

    // 自动量程一次性读取ALS和White双通道
    esp_err_t ReadAutoAll(veml7700_auto_data_t* als_result, veml7700_auto_data_t* white_result);

private:
    veml7700_gain_t gain_;
    veml7700_it_t it_;
    veml7700_pers_t pers_;
    bool int_enable_;
    bool shutdown_;
    uint16_t als_conf_;         // 缓存的ALS配置寄存器值

    // 16-bit 寄存器读写（VEML7700使用16-bit寄存器）
    esp_err_t WriteReg16(uint8_t cmd, uint16_t value);
    esp_err_t ReadReg16(uint8_t cmd, uint16_t* value);

    // 更新ALS配置寄存器
    esp_err_t UpdateALSConf();

    // 根据当前增益和积分时间计算分辨率
    float GetResolution() const;

    // 非线性校正（高Lux值时的多项式补偿）
    float CorrectLux(float lux) const;

    // 自动量程内部实现（通道类型由读取函数指针区分）
    typedef esp_err_t (VEML7700::*ReadRawFunc)(uint16_t* raw);
    esp_err_t AutoRangeMeasure(ReadRawFunc read_func, veml7700_auto_data_t* result);

    // 应用增益和积分时间并等待采样完成
    esp_err_t ApplyConfigAndWait(veml7700_gain_t gain, veml7700_it_t it);
};

#endif // VEML7700_H
