#ifndef __EQ_FLASH_STORAGE_H__
#define __EQ_FLASH_STORAGE_H__

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

// EQ Flash存储相关常量定义
#define EQ_FLASH_MAGIC           0x45515041  // "EQPA" - EQ参数文件魔数
#define EQ_FLASH_MAGIC_PARAMS    0x45515041  // "EQPA" - EQ参数文件魔数
#define EQ_FLASH_VERSION         0x00020000  // 版本2.0.0 - 优化存储格式
#define EQ_FLASH_MAX_SAMPLE_RATES 6          // 支持的采样率数量
#define EQ_FLASH_MAX_MODES       10          // 最大模式数量
#define EQ_FLASH_MAX_CHANNELS    2           // 最大通道数量

// 支持的采样率列表
#define EQ_SAMPLE_RATES {44100, 48000, 88200, 96000, 176400, 192000}

// EQ参数文件头结构 (简化版本，去除采样率字段)
typedef struct {
    uint32_t magic;          // 魔数: 0x45515041 ("EQPA")
    uint32_t version;        // 版本号
    uint8_t mode;            // 模式号
    uint8_t channel;         // 通道号
    uint16_t reserved;       // 保留字段
    uint32_t data_size;      // 数据大小
    uint32_t crc32;          // CRC32校验
} __attribute__((packed)) eq_file_header_t;

// 元数据结构已移除，简化存储系统

// EQ存储状态结构
typedef struct {
    int is_initialized;      // 是否已初始化 (0: 否, 1: 是)
    int has_flash_data;      // Flash中是否有数据 (0: 否, 1: 是)
    uint32_t last_sync_time; // 最后同步时间
    uint32_t sync_count;     // 同步次数
    uint32_t error_count;    // 错误次数
} eq_storage_status_t;

// 增益存储结构（只存储用户模式）
typedef struct {
    uint32_t magic;          // 魔数: 0x4551474E ("EQGN" - EQ Gain)
    uint32_t version;        // 版本号
    uint32_t data_size;      // 数据大小
    uint32_t crc32;          // CRC32校验
} __attribute__((packed)) eq_gain_header_t;

// 模式增益数据（只存储用户模式6-8）
typedef struct {
    int32_t mode_gains[3];   // 用户模式增益数组：mode 6, 7, 8，每个4字节
} __attribute__((packed)) eq_gain_data_t;

// 单个模式名称存储结构
typedef struct {
    uint32_t magic;          // 魔数: 0x45514E4D ("EQNM" - EQ Name)
    uint32_t version;        // 版本号
    uint8_t mode;            // 模式号
    uint8_t reserved[3];     // 保留字段
    uint32_t data_size;      // 数据大小（16字节）
    uint32_t crc32;          // CRC32校验
} __attribute__((packed)) eq_name_header_t;

// 单个模式名称数据
typedef struct {
    char mode_name[16];      // 模式名称，16字节
} __attribute__((packed)) eq_name_data_t;

// 兼容旧格式的结构（保留用于向后兼容）
typedef struct {
    uint32_t magic;          // 魔数: 0x45514E47 ("EQNG" - EQ Name Gain)
    uint32_t version;        // 版本号
    uint32_t data_size;      // 数据大小
    uint32_t crc32;          // CRC32校验
} __attribute__((packed)) eq_gain_name_header_t;

// 模式增益和名称数据
typedef struct {
    int32_t mode_gains[NUM_EQ_MODES];   // 模式增益数组，每个4字节
    char mode_names[NUM_EQ_MODES][16];  // 模式名称数组，每个16字节
} __attribute__((packed)) eq_gain_name_data_t;

// 函数声明

/**
 * @brief 初始化EQ Flash存储系统
 * @return 0: 成功, -1: 失败
 */
int eq_flash_init(void);

/**
 * @brief 反初始化EQ Flash存储系统
 */
void eq_flash_deinit(void);

// 注意：save all 和 load all 函数已移除，使用动态单参数存储系统

/**
 * @brief 从Flash加载指定模式的EQ参数
 * @param mode 模式号
 * @return 0: 成功, -1: 失败
 */
int eq_flash_load_mode(uint8_t mode);

/**
 * @brief 保存指定模式的EQ参数到Flash
 * @param mode 模式号
 * @return 0: 成功, -1: 失败
 */
int eq_flash_save_mode(uint8_t mode);

/**
 * @brief 同步指定模式参数到Flash(延迟写入)
 * @param mode 模式号
 * @return 0: 成功, -1: 失败
 */
int eq_flash_sync_mode(uint8_t mode);

/**
 * @brief 同步所有待更新的参数到Flash
 * @return 0: 成功, -1: 失败
 */
int eq_flash_sync_all(void);

/**
 * @brief 检查Flash中是否存在EQ参数数据
 * @return 1: 存在, 0: 不存在
 */
int eq_flash_has_data(void);

/**
 * @brief 获取EQ存储状态
 * @param status 状态结构指针
 * @return 0: 成功, -1: 失败
 */
int eq_flash_get_status(eq_storage_status_t *status);

/**
 * @brief 清除Flash中的所有EQ参数数据
 * @return 0: 成功, -1: 失败
 */
int eq_flash_clear_all(void);

/**
 * @brief 验证EQ参数文件完整性
 * @param mode 模式号
 * @return 1: 完整, 0: 损坏
 */
int eq_flash_verify_mode(uint8_t mode);

/**
 * @brief 获取文件路径
 * @param mode 模式号
 * @param channel 通道号
 * @param path 输出路径缓冲区
 * @param max_len 缓冲区最大长度
 * @return 0: 成功, -1: 失败
 */
int eq_flash_get_file_path(uint8_t mode, uint8_t channel, 
                          char *path, size_t max_len);

/**
 * @brief 计算CRC32校验值
 * @param data 数据指针
 * @param len 数据长度
 * @return CRC32值
 */
uint32_t eq_flash_calculate_crc32(const uint8_t *data, size_t len);

/**
 * @brief 检查是否需要同步参数到Flash
 * @return 1: 需要同步, 0: 不需要
 */
int eq_flash_needs_sync(void);

/**
 * @brief 标记参数已修改，需要同步
 * @param mode 模式号
 */
void eq_flash_mark_dirty(uint8_t mode);

/**
 * @brief 检查滤波器是否为默认值（bypass）
 * @param band 滤波器参数
 * @return 1: 是默认值, 0: 不是默认值
 */
int is_filter_bypass(const filter_params_t *band);

/**
 * @brief 从EQ数据中提取非默认滤波器到Flash存储格式
 * @param eq_data 源EQ数据
 * @param flash_data 目标Flash存储数据
 * @return 0: 成功, -1: 失败
 */
int extract_active_filters(const eq_mode_data_t *eq_data, eq_flash_data_t *flash_data);

/**
 * @brief 从Flash存储格式恢复EQ数据
 * @param flash_data 源Flash存储数据
 * @param eq_data 目标EQ数据
 * @return 0: 成功, -1: 失败
 */
int restore_eq_from_flash(const eq_flash_data_t *flash_data, eq_mode_data_t *eq_data);

/**
 * @brief 实时计算滤波器系数
 * @param eq_data EQ数据
 * @param sample_rate 采样率
 * @return 0: 成功, -1: 失败
 */
int calculate_filter_coefficients(eq_mode_data_t *eq_data, uint32_t sample_rate);

// ==================== 单参数动态存储系统 ====================

/**
 * @brief 初始化单参数存储数据库
 * @return 0: 成功, -1: 失败
 */
int eq_single_param_database_init(void);

/**
 * @brief 处理0x8c/0x8d命令的单参数变化
 * @param data 接收到的数据
 * @param len 数据长度
 * @return 0: 成功, -1: 失败
 */
int eq_process_single_param_change(uint32_t sample_rate, uint8_t mode, uint8_t channel, uint8_t band_index, filter_params_t *band);

/**
 * @brief 比较单个参数是否不同
 * @param old_params 旧参数
 * @param new_params 新参数
 * @return 1: 不同, 0: 相同
 */
int eq_single_params_different(const filter_params_t *old_params, const filter_params_t *new_params);

/**
 * @brief 添加单个参数变化到数据库
 * @param sample_rate 采样率
 * @param mode 模式
 * @param channel 通道
 * @param band_index 滤波器索引
 * @param new_params 新参数
 * @return 0: 成功, -1: 失败
 */
int eq_add_single_param(uint32_t sample_rate, uint8_t mode, uint8_t channel, 
                       uint8_t band_index, const filter_params_t *new_params);

/**
 * @brief 保存单个参数到Flash
 * @param sample_rate 采样率
 * @param mode 模式
 * @param channel 通道
 * @param band_index 滤波器索引
 * @return 0: 成功, -1: 失败
 */
int eq_save_single_param(uint32_t sample_rate, uint8_t mode, uint8_t channel, uint8_t band_index);

/**
 * @brief 从Flash加载单个参数
 * @param sample_rate 采样率
 * @param mode 模式
 * @param channel 通道
 * @param band_index 滤波器索引
 * @return 0: 成功, -1: 失败
 */
int eq_load_single_param(uint32_t sample_rate, uint8_t mode, uint8_t channel, uint8_t band_index);

/**
 * @brief 保存所有脏参数到Flash（只保存EQ参数，不包括增益和名称）
 * @return 0: 成功, -1: 失败
 */
int eq_save_dirty_params(void);

/**
 * @brief 保存脏的增益到Flash
 * @return 0: 成功, -1: 失败
 */
int eq_save_dirty_gain(void);

/**
 * @brief 保存脏的模式名称到Flash
 * @return 0: 成功, -1: 失败
 */
int eq_save_dirty_names(void);

/**
 * @brief 保存脏的增益和模式名称到Flash（兼容旧接口）
 * @return 0: 成功, -1: 失败
 */
int eq_save_dirty_gain_and_names(void);

/**
 * @brief 保存用户模式的增益到Flash（只保存用户模式6-8）
 * @return 0: 成功, -1: 失败
 */
int eq_save_gain(void);

/**
 * @brief 保存单个用户模式的名称到Flash（只有与初始值不同且非空才保存）
 * @param mode 模式号（必须是用户模式6-8）
 * @return 0: 成功, -1: 失败, 1: 跳过（与初始值相同或为空）
 */
int eq_save_name(uint8_t mode);

/**
 * @brief 从Flash加载用户模式的增益
 * @return 0: 成功, -1: 失败
 */
int eq_load_gain(void);

/**
 * @brief 从Flash加载单个用户模式的名称
 * @param mode 模式号（必须是用户模式6-8）
 * @return 0: 成功, -1: 失败（文件不存在或错误）
 */
int eq_load_name(uint8_t mode);

/**
 * @brief 保存增益和模式名称到Flash（兼容旧接口，内部调用新函数）
 * @return 0: 成功, -1: 失败
 */
int eq_save_gain_and_names(void);

/**
 * @brief 从Flash加载增益和模式名称（兼容旧接口，内部调用新函数）
 * @return 0: 成功, -1: 失败
 */
int eq_load_gain_and_names(void);

/**
 * @brief 标记增益为脏（需要保存）
 */
void eq_mark_gain_dirty(void);

/**
 * @brief 标记模式名称为脏（需要保存）
 */
void eq_mark_name_dirty(void);

/**
 * @brief 标记增益和模式名称为脏（需要保存）（兼容旧接口）
 */
void eq_mark_gain_name_dirty(void);

/**
 * @brief 删除Flash中的EQ参数文件
 * @param mode 模式号 (0-9, 0xFF表示所有模式)
 * @return 0: 成功, -1: 失败
 */
int delete_flash_eq_params(uint8_t mode);

/**
 * @brief 删除Flash中的增益和模式名称文件
 * @param mode 模式号 (0-9, 0xFF表示所有模式)
 * @return 0: 成功, -1: 失败
 */
int delete_flash_gain_and_names(uint8_t mode);

/**
 * @brief 恢复默认EQ参数
 * @param mode 模式号 (0-9, 0xFF表示所有模式)
 * @return 0: 成功, -1: 失败
 */
int restore_default_eq_params(uint8_t mode);

/**
 * @brief 系统开机时加载所有参数并计算系数
 * @param sample_rate 采样率
 * @param mode 模式
 * @return 0: 成功, -1: 失败
 */
int eq_load_all_params_and_calculate_coefficients(uint32_t sample_rate, uint8_t mode);

/**
 * @brief 获取单参数存储统计
 * @param stats 输出统计信息
 * @return 0: 成功, -1: 失败
 */
int eq_get_single_param_stats(eq_single_param_database_t *stats);

/**
 * @brief 清空单参数存储数据库
 * @return 0: 成功, -1: 失败
 */
int eq_clear_single_param_database(void);

/**
 * @brief 保存EQ使能状态到Flash（独立文件存储，与模式存储完全分离）
 * @param enable EQ使能状态 (0=禁用, 1=启用)
 * @return 0: 成功, -1: 失败
 * 
 * 改动原因：将eq_enable存储独立为单独文件（eq_enable），与模式存储完全分离，互不影响
 */
int eq_flash_save_eq_enable(uint8_t enable);

/**
 * @brief 从Flash加载EQ使能状态（独立文件加载，与模式加载完全分离）
 * @return 使能状态值: 成功(0或1), -1: 失败
 * 
 * 改动原因：从独立文件（eq_enable）加载eq_enable，与模式加载完全分离，互不影响
 */
int eq_flash_load_eq_enable(void);

/**
 * @brief 保存当前EQ模式到Flash（独立文件存储，与使能状态存储完全分离）
 * @param mode 模式值 (0-9)
 * @return 0: 成功, -1: 失败
 * 
 * 改动原因：将模式存储独立为单独文件（cur_mode），与eq_enable存储完全分离，互不影响
 */
int eq_flash_save_current_mode(uint8_t mode);

/**
 * @brief 从Flash加载当前EQ模式（独立文件加载，与使能状态加载完全分离）
 * @return 模式值: 成功(0-9), -1: 失败
 * 
 * 改动原因：从独立文件（cur_mode）加载模式，与eq_enable加载完全分离，互不影响
 * 注意：此函数同时加载模式和使能状态（从两个独立文件），用于初始化
 */
int eq_flash_load_current_mode(void);

#endif // __EQ_FLASH_STORAGE_H__
