#ifndef __KV_FLASH_H
#define __KV_FLASH_H

#include "stm32l4xx_hal.h"
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

// ------------------- 基本参数配置 -------------------
#define DB_FLASH_SIZE        2048  // 每个数据库大小
#define DB_FLASH_PAGE_SIZE   2048  // 单页大小
#define KV_MAX_KEY_LEN       32
#define KV_MAX_VAL_LEN       64
#define KV_ITEM_MAX_LEN      (KV_MAX_KEY_LEN + KV_MAX_VAL_LEN + 2)

// ------------------- 数据库 ID 枚举 -------------------
typedef enum {
    DB_ID_SYSTEM = 0,
    DB_ID_CALIB,
    DB_ID_SNAPSHOT,
    DB_ID_MAX
} KV_DB_ID;

// ------------------- 键值映射表结构 -------------------
typedef struct {
    const char* key;
    KV_DB_ID db_id;
} KV_KeyMap;

typedef struct {
    uint8_t db_id;
    const char *kv_str; // 直接存成 "key=value"
} InitEntry;



// ------------------- key字段宏定义 -------------------
// SystemConfig 相关字段
#define KV_KEY_MAC           "mac"
#define KV_KEY_ROLE          "role"
#define KV_KEY_CONSOLE       "console"
#define KV_KEY_ADDR          "addr"
#define KV_KEY_BAUDRATE      "baudrate"
#define KV_KEY_VERSION       "version"

// CalibrationParams 相关字段
#define KV_KEY_ROD_VOL0     "rod_vol0"
#define KV_KEY_ROD_VOL1     "rod_vol1"
#define KV_KEY_ROD_VOL2     "rod_vol2"
#define KV_KEY_ROD_VOL3     "rod_vol3"
#define KV_KEY_ROD_VOL4     "rod_vol4"
#define KV_KEY_ROD_VOL5     "rod_vol5"
#define KV_KEY_ROD_VOL6     "rod_vol6"

#define KV_KEY_OIL_CAP0     "oil_cap0"
#define KV_KEY_OIL_CAP1     "oil_cap1"
#define KV_KEY_OIL_CAP2     "oil_cap2"
#define KV_KEY_OIL_CAP3     "oil_cap3"
#define KV_KEY_OIL_CAP4     "oil_cap4"
#define KV_KEY_OIL_CAP5     "oil_cap5"
#define KV_KEY_OIL_CAP6     "oil_cap6"
#define KV_KEY_OIL_CAP7     "oil_cap7"
#define KV_KEY_OIL_CAP8     "oil_cap8"
#define KV_KEY_OIL_CAP9     "oil_cap9"
#define KV_KEY_OIL_CAP10    "oil_cap10"

#define KV_KEY_RES_VOL0    	"res_vol0"
#define KV_KEY_RES_VOL1    	"res_vol1"
#define KV_KEY_RES_VOL2    	"res_vol2"
#define KV_KEY_RES_VOL3    	"res_vol3"
#define KV_KEY_RES_VOL4    	"res_vol4"
#define KV_KEY_RES_VOL5    	"res_vol5"

#define KV_KEY_RES_CAP0    	"res_cap0"
#define KV_KEY_RES_CAP1    	"res_cap1"
#define KV_KEY_RES_CAP2    	"res_cap2"
#define KV_KEY_RES_CAP3    	"res_cap3"
#define KV_KEY_RES_CAP4    	"res_cap4"
#define KV_KEY_RES_CAP5    	"res_cap5"

#define KV_KEY_ROD_VOL_OFFSET  "rod_vol_offset"
#define KV_KEY_ROD_DIALOG    	 "rod_dialog"
#define KV_KEY_ROD_COL_TIME    "rod_coltime" 

#define KV_KEY_OIL_PARA_INDU   "oil_para_indu"
#define KV_KEY_OIL_PARA_CAP    "oil_para_cap"
#define KV_KEY_OIL_CAP_OFFSET  "oil_cap_offset"
#define KV_KEY_OIL_DIALOG   	 "oil_dialog"
#define KV_KEY_OIL_COL_TIME    "rod_oil_coltime" 

#define KV_KEY_RES_PARA_INDU   "res_para_indu"
#define KV_KEY_RES_PARA_CAP  	 "res_para_cap"
#define KV_KEY_RES_CAP_OFFSET  "res_cap_offset"
#define KV_KEY_RES_VOL_OFFSET  "res_vol_offset"
#define KV_KEY_RES_CAP_DIALOG  "res_cap_dialog"
#define KV_KEY_RES_VOL_DIALOG  "res_vol_dialog"
#define KV_KEY_RES_CAP_COL_TIME    "res_oil_cap_coltime" 
#define KV_KEY_RES_VOL_COL_TIME    "res_oil_vol_coltime" 

#define KV_KEY_TEMP_VOL_OFFSET "temp_vol_offset"
#define KV_KEY_TEMP_DIALOG  	 "temp_dialog"
#define KV_KEY_TEMP_COL_TIME   "temp_coltime"

// SnapshotInfo 相关字段
#define KV_KEY_IAP_LOAD        "iapLoadStatus"
#define KV_KEY_IAP_SIZE        "iapsize"
#define KV_KEY_IAP_MD5         "iapmd5"
#define KV_KEY_IAP_SUBCODE     "subcode"
#define KV_KEY_UPDATE_OK       "update_ok"
#define KV_KEY_UPDATE_ERR      "update_err"
#define KV_KEY_UBOOTBACK       "ubootback" 

/*
**iapLoadStatus定义如下：
	值0：APP1区运行；
	值300：下载完成，即已完成IAP缓存区的新装载（下一步在bootloader中需将其拷贝至APP2区）；
	值2：APP2区运行
*/
/*
**ubootback定义如下：
	值400：检测到APP2区内程序无效，置上此值，并将IAP装载状态值置0（自动恢复到APP1区）；
	值401：检测到APP2区文件完整性校验错误，置上此值，并将IAP装载状态值置0（自动恢复到APP1区）；
	值1：因接收到命令，需要恢复到APP1区运行；
	值0：IAP装载状态设置为2时，会将此状态值置0；
*/
// ------------------- 接口函数 -------------------

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 读取整个数据库内容（原始字符串）
 * @param id 数据库ID
 * @param buf 存储缓冲区
 * @param buf_len 缓冲区大小（建议2048）
 * @return 实际读取字节数，失败返回0
 */
uint16_t DB_Dump(uint8_t id, char *buf, uint16_t buf_len);

/**
 * @brief 保存整个数据库内容（字符串）
 * @param id 数据库ID
 * @param buf 要保存的内容（##key1=val1##key2=val2##）
 * @param len 内容长度（不超过2048）
 * @return 1成功，0失败
 */
uint8_t DB_Save(uint8_t id, const char *buf, uint16_t len);

/**
 * @brief 写入或删除某个键值对（增删改）
 * @param id 数据库ID
 * @param kv_str 形如"key=val"，val为空表示删除该key
 * @return 1成功，0失败
 */
uint8_t SaveKvCache(uint8_t id, const char *kv_str);


size_t get_db_used_len(uint8_t db_id);

void DB_InitAllConfigs(void);


void handle_mac_set_cmd(const char *buf); // 处理 ###::{"mac":"112233445566"} 设置设备SN号也就是MAC号
void handle_cfg_set_cmd(const char *buf); // 入口函数_cfg_set
void handle_cfg_setx_cmd(const char *buf); // 入口函数_cfg_setx
void handle_cfg_get_cmd(const char *buf); // 入口函数_cfg_get
void handle_fileid_cmd(const char *buf); // 入口函数 --fileid=X,0 读取库存信息
void handle_clear_fileid_cmd(const char *buf); // 入口函数 --clear_fileid=X 清除内部配置库
	
int parse_cfg_set_cmd(const char *buf, uint8_t *db_id, char *key, size_t key_sz, char *val, size_t val_sz); // 解析
int parse_cfg_setx_cmd(const char *buf, uint8_t *db_id, char *key, size_t key_sz, char *val, size_t val_sz); // 解析

void handle_cfg_set_common(uint8_t db_id, const char *key, const char *value); // 通用处理函数
void sync_JsRoot_field(const char *key, const char *value); // 更新缓存结构体

void KV_HandleQuery(uint8_t db_id, const char* key);
void KV_HandleUpdate(uint8_t db_id, const char* key, const char* value);
void KV_HandleDelete(uint8_t db_id, const char* key);
void KV_HandleInsert(uint8_t db_id, const char* key, const char* value);

void DB_SaveUInt(uint8_t dbId, const char *key, uint32_t value); // 存入 uint32_t 型到数据库
void DB_SaveChar(uint8_t db_id, const char *key, const char *value); // 存入 char 型到数据库
void DB_SaveInt(uint8_t dbId, const char *key, int32_t value); // 存入 int32_t 型到数据库
void DB_SaveFloat(uint8_t dbId, const char *key, float value); // 存入 float 型到数据库

uint8_t pickup_string_from_key(uint8_t id, const char *key, char *val_out, uint8_t max_len); // 读取某个键的字符串值
uint8_t pickup_int_from_key(uint8_t id, const char *key, int *val_out); // 读取某个键的整数值
uint8_t pickup_uint32_from_key(uint8_t id, const char *key, uint32_t *val_out); // 从数据库提取 uint32_t 类型
uint8_t pickup_long_from_key(uint8_t id, const char *key, long *val_out); // 从数据库提取 long 类型

void DB_Load_All(void);

uint8_t pickup_string_from_cache(uint8_t id, const char *key, char *val_out, uint8_t max_len);
uint8_t pickup_int_from_cache(uint8_t id, const char *key, int *val_out);
uint8_t pickup_uint32_from_cache(uint8_t id, const char *key, uint32_t *val_out);
uint8_t pickup_long_from_cache(uint8_t id, const char *key, long *val_out);
void DB_Dump_to_JsRoot(void);
void DB_SyncAllToJsRoot(void);
void DB_Debug_Print_All(void);
void DB__Dump_IAP_LOAD(void);
#ifdef __cplusplus
}
#endif

#endif // __KV_FLASH_H

