use super::types::{BuildingTypeBcaSelectorProbe, BuildingTypeBtyHeaderProbe};

pub(super) fn probe_bca_selector_bytes(bytes: &[u8]) -> BuildingTypeBcaSelectorProbe {
    let byte_0xb8 = bytes.get(0xb8).copied().unwrap_or(0);
    let byte_0xb9 = bytes.get(0xb9).copied().unwrap_or(0);
    let byte_0xba = bytes.get(0xba).copied().unwrap_or(0);
    let byte_0xbb = bytes.get(0xbb).copied().unwrap_or(0);
    BuildingTypeBcaSelectorProbe {
        byte_0xb8,
        byte_0xb8_hex: format!("0x{byte_0xb8:02x}"),
        byte_0xb9,
        byte_0xb9_hex: format!("0x{byte_0xb9:02x}"),
        byte_0xba,
        byte_0xba_hex: format!("0x{byte_0xba:02x}"),
        byte_0xbb,
        byte_0xbb_hex: format!("0x{byte_0xbb:02x}"),
    }
}

pub(super) fn probe_bty_header(bytes: &[u8]) -> BuildingTypeBtyHeaderProbe {
    let type_id = read_u32_le(bytes, 0x00);
    let byte_0xb8 = bytes.get(0xb8).copied().unwrap_or(0);
    let byte_0xb9 = bytes.get(0xb9).copied().unwrap_or(0);
    let byte_0xba = bytes.get(0xba).copied().unwrap_or(0);
    let dword_0xbb = read_u32_le(bytes, 0xbb);
    BuildingTypeBtyHeaderProbe {
        type_id,
        type_id_hex: format!("0x{type_id:08x}"),
        name_0x04: read_c_string(bytes, 0x04, 0x1e),
        name_0x22: read_c_string(bytes, 0x22, 0x1e),
        name_0x40: read_c_string(bytes, 0x40, 0x1e),
        name_0x5e: read_c_string(bytes, 0x5e, 0x1e),
        name_0x7c: read_c_string(bytes, 0x7c, 0x1e),
        name_0x9a: read_c_string(bytes, 0x9a, 0x1e),
        byte_0xb8,
        byte_0xb8_hex: format!("0x{byte_0xb8:02x}"),
        byte_0xb9,
        byte_0xb9_hex: format!("0x{byte_0xb9:02x}"),
        byte_0xba,
        byte_0xba_hex: format!("0x{byte_0xba:02x}"),
        dword_0xbb,
        dword_0xbb_hex: format!("0x{dword_0xbb:08x}"),
    }
}

fn read_u32_le(bytes: &[u8], offset: usize) -> u32 {
    bytes
        .get(offset..offset + 4)
        .and_then(|slice| <[u8; 4]>::try_from(slice).ok())
        .map(u32::from_le_bytes)
        .unwrap_or(0)
}

fn read_c_string(bytes: &[u8], offset: usize, max_len: usize) -> String {
    let Some(slice) = bytes.get(offset..offset.saturating_add(max_len)) else {
        return String::new();
    };
    let end = slice
        .iter()
        .position(|byte| *byte == 0)
        .unwrap_or(slice.len());
    String::from_utf8_lossy(&slice[..end]).into_owned()
}
