#include "app_leakage.h"

#include <string.h>
#include "bsp_w25q.h"
#include "bsp_buzzer.h"
#include "bsp_relay.h"

static void history_clear_all(void);
static u8 history_read_record(u32 record_index, app_leakage_history_alarm_t *record);
static void history_init(void);
static void history_save_metadata(void);

app_hitory_t history =
{
    .read_history = history_read_record,
    .clean_history = history_clear_all,
    .init_history = history_init
};

/*控制 声 光 继电器 报警*/
static void app_leakage_alarm_contorl(void)
{
    if(0 != leakage.alarm_state)
    {
        buzzer.set.on();
        relay.set(BSP_RELAY_CH_ERROR_STATE,USR_ON);
    }
    else
    {
        buzzer.set.off();
        relay.set(BSP_RELAY_CH_ERROR_STATE,USR_OFF);
    }
    
    /*漏液状态*/
    if(leakage.alarm_state & APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE)
    {
        relay.set(BSP_RELAY_CH_LEAKAGE,USR_ON);
    }
    else
    {
        relay.set(BSP_RELAY_CH_LEAKAGE,USR_OFF); 
    }
    /*断带状态*/
    if(leakage.alarm_state & APP_LEAKAGE_SUB_DEVICE_STATE_OPEN)
    {
        relay.set(BSP_RELAY_CH_OPEN,USR_ON);
    }
    else
    {
        relay.set(BSP_RELAY_CH_OPEN,USR_OFF);
    }
    /*通讯超时*/
    if(leakage.alarm_state & APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT)
    {
        relay.set(BSP_RELAY_CH_COMMINCAION,USR_ON);
    }  
    else
    {
        relay.set(BSP_RELAY_CH_COMMINCAION,USR_OFF);
    }
}


/*异常状态设备数量统计*/
void app_leakage_task(void)
{
    static u16 prev_ch_state[APP_LEAKAGE_SUB_DEVICE_NUM][APP_LEAKAGE_SUB_DEVICE_CH_NUM] = {0};
    u16 i, j, k, sub_device_index;

    /* 检测状态变化并统计异常数量 */
    for(i = 0; i < leakage.region_num; i++)
    {
        for(j = 0; j < leakage.region_data[i].sub_device_num; j++)
        {
            sub_device_index = leakage.region_data[i].sub_device_index[j];
            
            /* 检查设备是否启用 */
            if(leakage.sub_device_data[sub_device_index].flash_data.state != ENABLE)
            {
                continue;
            }
            
            /*历史报警存储*/
            for(k = 0; k < APP_LEAKAGE_SUB_DEVICE_CH_NUM; k++)
            {
                u16 current_state = leakage.sub_device_data[sub_device_index].ch_data[k].state;
                u16 prev_state = prev_ch_state[sub_device_index][k];
                u16 leak_distance = leakage.sub_device_data[sub_device_index].ch_data[k].distance;
                
                /* 检测状态变化并记录历史报警 */
                if((current_state & APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE) && 
                   !(prev_state & APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE))
                {
                    /* 漏液报警开始 - 记录历史报警 */
                    history_add_alarm_record(i, sub_device_index, k, APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE, leak_distance);
                }
                
                if((current_state & APP_LEAKAGE_SUB_DEVICE_STATE_OPEN) && 
                   !(prev_state & APP_LEAKAGE_SUB_DEVICE_STATE_OPEN))
                {
                    /* 断带报警开始 - 记录历史报警 */
                    history_add_alarm_record(i, sub_device_index, k, APP_LEAKAGE_SUB_DEVICE_STATE_OPEN, 0);
                }
                
                if((current_state & APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT) && 
                   !(prev_state & APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT))
                {
                    /* 通讯超时报警开始 - 记录历史报警 */
                    history_add_alarm_record(i, sub_device_index, k, APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT, 0);
                }
                
                /* 更新历史状态 */
                prev_ch_state[sub_device_index][k] = current_state;
            }

        }
    }
    /*报警控制 声光报警*/
    app_leakage_alarm_contorl();
}

/* 获取当前时间 */
static void get_current_time(u8 *time_buffer)
{
//    RTC_TimeTypeDef sTime;
//    RTC_DateTypeDef sDate;
//    
//    /* 获取RTC时间 */
//    HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
//    HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
//    
//    /* 年: 2字节 (例如: 2024 -> 0x07 0xE8) */
//    uint16_t year = 2000 + sDate.Year;  /* RTC年份通常从2000开始 */
//    time_buffer[0] = (year >> 8) & 0xFF;  /* 高字节 */
//    time_buffer[1] = year & 0xFF;         /* 低字节 */
//    time_buffer[2] = sDate.Month;         /* 月 */
//    time_buffer[3] = sDate.Date;          /* 日 */
//    time_buffer[4] = sTime.Hours;         /* 时 */
//    time_buffer[5] = sTime.Minutes;       /* 分 */
}

/* 从Flash读取历史报警元数据 */
static void history_read_metadata(void)
{
    app_leakage_history_metadata_t temp_metadata;
    
    w25q32.read(W25Q32_HISTORY_ALARM_METADATA_ADDR, 
                (uint8_t*)&temp_metadata, 
                sizeof(app_leakage_history_metadata_t));
    
    
    if(temp_metadata.total_records <= temp_metadata.max_records &&
       temp_metadata.write_index < temp_metadata.max_records)
    {
        /* 数据有效，复制到全局变量 */
        memcpy(&leakage.history_metadata, &temp_metadata, sizeof(app_leakage_history_metadata_t));
    }
    else
    {
        /* 数据无效，初始化 */
        memset(&leakage.history_metadata, 0, sizeof(app_leakage_history_metadata_t));
        leakage.history_metadata.max_records = MAX_HISTORY_ALARM_RECORDS;
        
        /* 保存到Flash */
        history_save_metadata(); 
    }
}

/* 保存历史报警元数据到Flash */
static void history_save_metadata(void)
{
    /* 擦除元数据扇区 */
    w25q32_sector_erase(W25Q32_HISTORY_ALARM_METADATA_ADDR);
    
    /* 写入元数据 */
    w25q32.write(W25Q32_HISTORY_ALARM_METADATA_ADDR, 
                (uint8_t*)&leakage.history_metadata, 
                sizeof(app_leakage_history_metadata_t));
}

/* 计算记录在Flash中的地址 */
static uint32_t history_calc_record_addr(u32 record_index)
{
    return W25Q32_HISTORY_ALARM_DATA_ADDR + 
           (record_index * HISTORY_ALARM_RECORD_SIZE);
}

/* 获取记录所在的扇区地址 */
static uint32_t history_calc_sector_addr(u32 record_index)
{
    uint32_t record_addr = history_calc_record_addr(record_index);
    return record_addr & ~(W25Q32_SECTOR_SIZE - 1);  /* 4K对齐 */
}

/* 添加历史报警记录 */
void history_add_alarm_record(u8 region_idx, u8 device_idx, u8 channel, u16 alarm_type, u16 leak_distance)
{
    app_leakage_history_alarm_t new_alarm;
    uint32_t write_addr;
    
    /* 填充报警记录 */
    memset(&new_alarm, 0, sizeof(app_leakage_history_alarm_t));
    
    /* 区域名 */
    if(region_idx < leakage.region_num)
    {
        memcpy(new_alarm.region_name, leakage.region_data[region_idx].name, 
               APP_LEAKAGE_STRING_NANE_LEN);
    }
    
    /* 设备ID和名称 */
    if(device_idx < APP_LEAKAGE_SUB_DEVICE_NUM)
    {
        new_alarm.device_id = leakage.sub_device_data[device_idx].flash_data.modbus_id;
        memcpy(new_alarm.device_name, leakage.sub_device_data[device_idx].flash_data.device_name,
               APP_LEAKAGE_STRING_NANE_LEN);
    }
    
    /* 报警类型、通道和漏液距离 */
    new_alarm.alarm_type = alarm_type; 
    new_alarm.channel = channel;
    new_alarm.leak_distance = leak_distance;
    
    /* 开始时间 */
    get_current_time(new_alarm.start_time);
    
    /* 计算写入地址 */
    write_addr = history_calc_record_addr(leakage.history_metadata.write_index);
    
    /* 检查是否需要擦除新扇区 */
    uint32_t current_sector = history_calc_sector_addr(leakage.history_metadata.write_index);
    uint32_t prev_sector = history_calc_sector_addr(
        (leakage.history_metadata.write_index == 0) ? 
        leakage.history_metadata.max_records - 1 : 
        leakage.history_metadata.write_index - 1);
    
    /* 如果切换到新扇区，需要擦除 */
    if(current_sector != prev_sector)
    {
        w25q32_sector_erase(current_sector);
    }
    
    /* 写入记录 */
    w25q32.write(write_addr, (uint8_t*)&new_alarm, HISTORY_ALARM_RECORD_SIZE);
    
    /* 更新元数据 */
    leakage.history_metadata.write_index++;
    if(leakage.history_metadata.write_index >= leakage.history_metadata.max_records)
    {
        leakage.history_metadata.write_index = 0;
    }
    
    if(leakage.history_metadata.total_records < leakage.history_metadata.max_records)
    {
        leakage.history_metadata.total_records++;
    }
    
    /* 保存元数据 */
    history_save_metadata();
}

/* 读取历史报警记录 */
static u8 history_read_record(u32 record_index, app_leakage_history_alarm_t *record)
{
    if(record_index >= leakage.history_metadata.total_records)
    {
        return 0;  /* 记录索引无效 */
    }
    
    /* 计算实际存储索引（考虑循环队列） */
    uint32_t actual_index;
    if(leakage.history_metadata.total_records == leakage.history_metadata.max_records)
    {
        /* 缓冲区已满，计算相对索引 */
        actual_index = (leakage.history_metadata.write_index + record_index) % 
                       leakage.history_metadata.max_records;
    }
    else
    {
        /* 缓冲区未满，直接读取 */
        actual_index = record_index;
    }
    
    uint32_t read_addr = history_calc_record_addr(actual_index);
    w25q32.read(read_addr, (uint8_t*)record, HISTORY_ALARM_RECORD_SIZE);
    
    return 1;
}

/* 清空所有历史报警记录 */
static void history_clear_all(void)
{
    /* 重置元数据 */
    memset(&leakage.history_metadata, 0, sizeof(app_leakage_history_metadata_t));
    leakage.history_metadata.max_records = MAX_HISTORY_ALARM_RECORDS;
    
    /* 保存元数据 */
    history_save_metadata();
    
    /* 擦除所有数据扇区（可选） */
    for(uint32_t i = 0; i < HISTORY_ALARM_SECTORS_NEEDED; i++)
    {
        uint32_t sector_addr = W25Q32_HISTORY_ALARM_DATA_ADDR + i * W25Q32_SECTOR_SIZE;
        w25q32_sector_erase(sector_addr);
    }
}


/* 初始化历史报警模块 */
static void history_init(void)
{
    /* 读取元数据 */
    history_read_metadata();
}
