use crate::inspect::smp::bundle::SmpContainerProfile;
use crate::inspect::smp::catalog::offsets::world::{
    RT3_SAVE_WORLD_BLOCK_CHUNK_TAG, RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_MULTIPLIER_RELATIVE_OFFSET,
    RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_VALUE_RELATIVE_OFFSET,
    RT3_SAVE_WORLD_BLOCK_ISSUE_OPINION_BASE_TERMS_OFFSET,
    RT3_SAVE_WORLD_BLOCK_ISSUE_OPINION_TERM_COUNT, RT3_SAVE_WORLD_BLOCK_LEN,
    RT3_SAVE_WORLD_BLOCK_NEXT_CHUNK_TAG,
};
use crate::inspect::smp::common::{find_u32_le_offsets, read_u8_at, read_u32_at};
use crate::inspect::smp::world::{
    SmpSaveWorldIssue37Probe, build_save_dword_candidate, build_save_i32_term_strip,
};

pub(in crate::inspect::smp) fn parse_save_world_issue_37_probe(
    bytes: &[u8],
    file_extension_hint: Option<&str>,
    container_profile: Option<&SmpContainerProfile>,
) -> Option<SmpSaveWorldIssue37Probe> {
    if file_extension_hint != Some("gms") {
        return None;
    }
    let profile = container_profile?;
    let supported = matches!(
        profile.profile_family.as_str(),
        "rt3-classic-save-container-v1"
            | "rt3-105-save-container-v1"
            | "rt3-105-scenario-save-container-v1"
            | "rt3-105-alt-save-container-v1"
    );
    if !supported {
        return None;
    }

    for chunk_tag_offset in find_u32_le_offsets(bytes, RT3_SAVE_WORLD_BLOCK_CHUNK_TAG) {
        let payload_offset = chunk_tag_offset + 4;
        let next_chunk_tag_offset = payload_offset.checked_add(RT3_SAVE_WORLD_BLOCK_LEN)?;
        if read_u32_at(bytes, next_chunk_tag_offset) != Some(RT3_SAVE_WORLD_BLOCK_NEXT_CHUNK_TAG) {
            continue;
        }
        let issue_value_lane = build_save_dword_candidate(
            bytes,
            payload_offset,
            "issue_0x37_value",
            RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_VALUE_RELATIVE_OFFSET,
        )?;
        let issue_37_raw_u8 = read_u8_at(
            bytes,
            payload_offset + RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_VALUE_RELATIVE_OFFSET,
        )?;
        let issue_38_raw_u8 = read_u8_at(
            bytes,
            payload_offset + RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_VALUE_RELATIVE_OFFSET + 1,
        )?;
        let issue_39_raw_u8 = read_u8_at(
            bytes,
            payload_offset + RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_VALUE_RELATIVE_OFFSET + 2,
        )?;
        let issue_3a_raw_u8 = read_u8_at(
            bytes,
            payload_offset + RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_VALUE_RELATIVE_OFFSET + 3,
        )?;
        let multiplier_lane = build_save_dword_candidate(
            bytes,
            payload_offset,
            "issue_0x37_multiplier",
            RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_MULTIPLIER_RELATIVE_OFFSET,
        )?;
        let issue_opinion_base_terms_raw_i32 = build_save_i32_term_strip(
            bytes,
            payload_offset,
            RT3_SAVE_WORLD_BLOCK_ISSUE_OPINION_BASE_TERMS_OFFSET,
            RT3_SAVE_WORLD_BLOCK_ISSUE_OPINION_TERM_COUNT,
        )?;
        return Some(SmpSaveWorldIssue37Probe {
            profile_family: profile.profile_family.clone(),
            source_kind: "save-direct-world-block".to_string(),
            semantic_family: "scenario-save-world-issue-0x37".to_string(),
            chunk_tag_offset,
            payload_offset,
            payload_len: RT3_SAVE_WORLD_BLOCK_LEN,
            payload_len_hex: format!("0x{:x}", RT3_SAVE_WORLD_BLOCK_LEN),
            issue_37_raw_u8,
            issue_37_raw_hex: format!("0x{issue_37_raw_u8:02x}"),
            issue_38_raw_u8,
            issue_38_raw_hex: format!("0x{issue_38_raw_u8:02x}"),
            issue_39_raw_u8,
            issue_39_raw_hex: format!("0x{issue_39_raw_u8:02x}"),
            issue_3a_raw_u8,
            issue_3a_raw_hex: format!("0x{issue_3a_raw_u8:02x}"),
            issue_value_lane,
            multiplier_lane,
            issue_opinion_base_terms_raw_i32,
            evidence: vec![
                format!(
                    "chunk tag 0x32c8 at 0x{chunk_tag_offset:x} matches the fixed [world+0x04] save block"
                ),
                format!(
                    "next chunk tag 0x32c9 appears at 0x{next_chunk_tag_offset:x}, matching the documented 0x4f2c payload span"
                ),
                format!(
                    "issue value lane uses payload +0x{:x} ([world+0x2d]); atlas notes tie 0x004339b0 to the clamped 0..4 issue-0x37 setter there",
                    RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_VALUE_RELATIVE_OFFSET
                ),
                format!(
                    "multiplier lane uses payload +0x{:x} ([world+0x29]); atlas notes tie 0x004339b0 to one companion scalar at that lane before company share-price refresh",
                    RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_MULTIPLIER_RELATIVE_OFFSET
                ),
                format!(
                    "the adjacent byte strip at payload +0x{:x}..+0x{:x} carries raw issue slots 0x37..0x3a as {:02x} {:02x} {:02x} {:02x}",
                    RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_VALUE_RELATIVE_OFFSET,
                    RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_VALUE_RELATIVE_OFFSET + 3,
                    issue_37_raw_u8,
                    issue_38_raw_u8,
                    issue_39_raw_u8,
                    issue_3a_raw_u8
                ),
            ],
        });
    }

    None
}
