use std::io::{Read, Result, BufReader};
use std::fs::File;
use std::convert::TryInto;
use super::structures::{TimeStruct, SpectralData, ImageInfo, OneIRISData};
// use serde::de::value;
use serde_json::Value;
pub fn read_time<R: Read>(reader: &mut R) -> Result<TimeStruct> {
    let mut buffer = [0u8; 10]; // Corrected buffer size to 10 bytes
    reader.read_exact(&mut buffer)?;

    Ok(TimeStruct {
        time_zone: buffer[0] as i8,
        year: u16::from_le_bytes([buffer[1], buffer[2]]),
        month: buffer[3],
        day: buffer[4],
        hour: buffer[5],
        minute: buffer[6],
        second: buffer[7],
        millisecond: u16::from_le_bytes([buffer[8], buffer[9]]), // Indices 8 and 9 are correct for 10-byte buffer
    })
}



pub fn read_image_info<R: Read>(reader: &mut R) -> Result<ImageInfo> {
    let mut info = ImageInfo::new();
    
    // Read data length
    let mut len_buf = [0u8; 8];
    reader.read_exact(&mut len_buf)?;
    info.data_length = u64::from_le_bytes(len_buf);

    // Read name (fixed size 100 bytes)
    let mut name_buf = [0u8; 100];
    reader.read_exact(&mut name_buf)?;
    info.name = String::from_utf8_lossy(&name_buf).trim_end_matches('\0').to_string();
    info.name = remove_after_null_split_once(info.name);

    // Read collection time
    info.collection_time = read_time(reader)?;

    // Read info type
    let mut type_buf = [0u8; 1];
    reader.read_exact(&mut type_buf)?;
    info.info_type = type_buf[0];
    let imagedatlenth= info.data_length as u64- 100-10-1; // Adjusted to account for the size of TimeStruct and info_type
    // Read image data
    info.image_data.resize(imagedatlenth as usize, 0);
    reader.read_exact(&mut info.image_data)?;

    Ok(info)
}

pub fn read_iris_file(path: &str) -> Result<OneIRISData> {
    let file = File::open(path)?;
    let mut reader = BufReader::new(file);
    
    // Read and verify magic number
    // let mut magic = [0u8; 4];
    // reader.read_exact(&mut magic)?;
    // if magic != [0x49, 0x52, 0x49, 0x53] { // "IRIS" in ASCII
    //     return Err(std::io::Error::new(
    //         std::io::ErrorKind::InvalidData,
    //         "Not a valid IRIS file"
    //     ));
    // }

    let mut iris_data = OneIRISData::new();

    // // Read file version
    // let mut version = [0u8; 2];
    // reader.read_exact(&mut version)?;

    // Read sections until EOF
    loop {
        let mut section_header = [0u8; 12]; // type (4) + length (8)
        if reader.read_exact(&mut section_header).is_err() {
            break; // EOF reached
        }

        let section_type = u32::from_le_bytes(section_header[0..4].try_into().unwrap());
        let section_length = u64::from_le_bytes(section_header[4..12].try_into().unwrap());

        match section_type {
            0x00FF00FF => { // Spectral data section
                let count = read_section_count(&mut reader)?;
                let mut data = Vec::with_capacity(count);
                for _ in 0..count {
                    data.push(read_spectral_data(&mut reader)?);
                }
                iris_data.spectral_data_section = data;
            },
            0xFF00FF00 => { // Spectral info section
                let count = read_section_count(&mut reader)?;
                let mut data = Vec::with_capacity(count);
                for _ in 0..count {
                    let mut tempbuffer = [0u8; 3]; // Adjust size as needed
                    reader.read_exact(&mut tempbuffer)?;
                    let lenth = u16::from_le_bytes([tempbuffer[0],tempbuffer[1]]) as usize;
                    let datatype= u8::from_le_bytes([tempbuffer[2]]);
                     let mut tempvector = vec![0u8; lenth];
                    reader.read_exact(&mut tempvector)?;
                    // Convert to String
                    let json_string = String::from_utf8(tempvector).unwrap_or_default();
                    let json_string = json_string.trim_end_matches('\0').to_string();
                    //print!("JSON String: {}", json_string);
                    let json:Value =  match serde_json::from_str(&json_string){
                        Ok(json) => json,
                        Err(e) => {
                            eprintln!("Error parsing JSON: {}", e);
                            continue; // Skip this entry if parsing fails
                        }
                    }; // Handle parsing error gracefully

                    //判断json["info_type"]是否存在
                    if !json.get("info_type").is_some() {
                        eprintln!("JSON does not contain 'info_type': {}", json_string);
                        continue; // Skip this entry if "info_type" is missing
                    }
                    /* {
           "info_type": "infolist", // 0 for device info
           "info_number":3,
           "info_list": [
                {
                    "info_type": "devinfo", // 0 for device info
                    "sensor_id": "is30002",
                    "bandnum": 2048,
                    "wave_coeff": { 
                        "a1": 0.0,
                        "a2": 0.0,
                        "a3":  400,
                        "a4": 1.0
                    }
                },
                {
                    "info_type": "environment", // 1 for gain info
                    "date": "2000-01-00 00:00:00",
                    //下面可选
                    "humidity":90.0,
                    "temperature":35.0 ,
                    "gps":{
                        "latitude":115.01,
                        "longitude": 39.01,
                        "altitude": 100.0
                    },
                },
                {
                    "info_type": "devinfo", // 0 for device info
                    "sensor_id": "is20001",
                    "bandnum": 512,
                    "wave_coeff": { 
                        "a1": 0,
                        "a2": 0.0,
                        "a3":390,
                        "a4": 4
                    }
                }
            ]

        } */
                    //如果info_type是infolist 则需要逐个解析
                    if json.get("info_type").and_then(Value::as_str) == Some("infolist") {
                        let info_number = json.get("info_number").and_then(Value::as_u64).unwrap_or(0) as usize;
                        for i  in 0 ..info_number{
                            //将对应的info加入到data中
                            if let Some(info) = json.get("info_list").and_then(|list| list.get(i)) {
                               data.push(info.clone());
                            } 


                        }

                        continue; // Skip the rest of the loop for this entry
                    }



                    data.push(json);
                    //println!("Parsed JSON: {:?}", json);
                    // let mut data_entry = SpectralInfo::new();
                    // data_entry.sensor_id = json.get("SensorId").and_then(Value::as_str).unwrap_or_default().to_string();
                    // data_entry.wave_coeff[0]=json["WaveCoeff"]["a1"].as_f64().unwrap_or(0.0);
                    // data_entry.wave_coeff[1]=json["WaveCoeff"]["a2"].as_f64().unwrap_or(0.0);
                    // data_entry.wave_coeff[2]=json["WaveCoeff"]["a3"].as_f64().unwrap_or(0.0);
                    // data_entry.wave_coeff[3]=json["WaveCoeff"]["a4"].as_f64().unwrap_or(0.0);
                    // data.push(data_entry);
                    // Parse JSON string
                    
   

                    
                }
                iris_data.spectral_info_section = data;
            },
            0xF0F0F0F0 => { // Other info section
                if section_length == 0 {
                    iris_data.other_info_section = Vec::new(); // Handle empty section
                    continue; // Skip empty section
                }
                let count = read_section_count(&mut reader)?;
                let mut data = Vec::with_capacity(count);
                for _ in 0..count {
                    let mut tempbuffer = [0u8; 3]; // Adjust size as needed
                    reader.read_exact(&mut tempbuffer)?;
                    let lenth = u16::from_le_bytes([tempbuffer[0], tempbuffer[1]]) as usize;
                    let info_type = u8::from_le_bytes([tempbuffer[2]]); 
                    let mut tempvector = vec![0u8; lenth];
                    reader.read_exact(&mut tempvector)?;
                    // Convert to String
                    let json_string = String::from_utf8(tempvector).unwrap_or_default();    
                    let json_string = json_string.trim_end_matches('\0').to_string();
                    //print!("JSON String: {}", json_string);
                    let json: Value = match serde_json::from_str(&json_string) {
                        Ok(json) => json,
                        Err(e) => {
                            eprintln!("Error parsing JSON: {}", e);
                            continue; // Skip this entry if parsing fails
                        }
                    }; // Handle parsing error gracefully
                    data.push(json);
                   
                }
                iris_data.other_info_section = data;
            },
            0x0F0F0F0F => { // Image info section
                if section_length== 0 {
                    iris_data.image_info_section= Vec::new(); // Handle empty section
                    continue; // Skip empty section
                    
                }
                let count = read_section_count(&mut reader)?;
                let mut data = Vec::with_capacity(count);
                for _ in 0..count {
                    data.push(read_image_info(&mut reader)?);
                }
                iris_data.image_info_section = data;
            },
            _ => {
                // Skip unknown sections
                let mut buf = vec![0u8; section_length as usize];
                reader.read_exact(&mut buf)?;
            }
        }
    }

    Ok(iris_data)
}

fn read_section_count<R: Read>(reader: &mut R) -> Result<usize> {
    let mut count_buf = [0u8; 2];
    reader.read_exact(&mut count_buf)?;
    Ok(u16::from_le_bytes(count_buf) as usize)
}

// pub fn read_other_info<R: Read>(reader: &mut R) -> Result<OtherInfo> {
//     let mut info = OtherInfo::new();

//     // Read info type
//     let mut type_buf = [0u8; 1];
//     reader.read_exact(&mut type_buf)?;
//     info.info_type = type_buf[0];

//     // Read data length
//     let mut len_buf = [0u8; 8];
//     reader.read_exact(&mut len_buf)?;
//     let data_len = u64::from_le_bytes(len_buf) as usize;

//     // Read data
//     info.data.resize(data_len, 0);
//     reader.read_exact(&mut info.data)?;

//     Ok(info)
// }
fn remove_after_null_split_once(s: String) -> String {
    if let Some((before_null, _after_null)) = s.split_once('\0') {
        // 返回 \0 之前的部分
        before_null.to_string()
    } else {
        // 如果没有找到 \0，就返回原始 String
        s
    }
}
pub fn read_spectral_data<R: Read>(reader: &mut R) -> Result<SpectralData> {
    let mut data = SpectralData::new();
    
    // Read fixed-size fields
    let mut name_buf = [0u8; 100];

    reader.read_exact(&mut name_buf)?;
    name_buf[99] = 0; // Ensure null termination
    let temp= String::from_utf8_lossy(&name_buf);
    data.name = temp.trim_end_matches('\0').to_string();
    data.name = remove_after_null_split_once(data.name);

    let mut sensor_buf = [0u8; 50];
    reader.read_exact(&mut sensor_buf)?;
    data.sensor_id = String::from_utf8_lossy(&sensor_buf).trim_end_matches('\0').to_string();
    data.sensor_id = remove_after_null_split_once(data.sensor_id);
    let mut uint8_buf = [0u8; 1];

    reader.read_exact(&mut uint8_buf)?;
    data.fiber_id = uint8_buf[0];

    
    data.collection_time = read_time(reader)?;

    
    let mut float_buf = [0u8; 8];
    reader.read_exact(&mut float_buf)?;
    data.exposure = f64::from_le_bytes(float_buf);
    
    let mut float_buf = [0u8; 4];
    reader.read_exact(&mut float_buf)?;
    data.gain = f32::from_le_bytes(float_buf);
    
    let mut byte_buf = [0u8; 1];
    reader.read_exact(&mut byte_buf)?;
    data.data_type = byte_buf[0];
    
    reader.read_exact(&mut byte_buf)?;
    data.pixel_size = byte_buf[0];
    
    reader.read_exact(&mut byte_buf)?;
    data.ground_type = byte_buf[0];
    
    let mut short_buf = [0u8; 2];
    reader.read_exact(&mut short_buf)?;
    data.bands = u16::from_le_bytes(short_buf);
    
    reader.read_exact(&mut byte_buf)?;
    data.valid_flag = byte_buf[0];
    let data_len=data.pixel_size as usize * data.bands as usize;
    // Read the length of the spectral_data vector
    // let mut len_buf = [0u8; 8];
    // reader.read_exact(&mut len_buf)?;
    // let data_len = u64::from_le_bytes(len_buf) as usize;

    // Read the spectral_data vector
    data.spectral_data.resize(data_len, 0);
    reader.read_exact(&mut data.spectral_data)?;

    Ok(data)
}