use crate::inspect::smp::bundle::SmpContainerProfile;
use crate::inspect::smp::catalog::offsets::world::{
    RT3_SAVE_WORLD_BLOCK_CAMPAIGN_OVERRIDE_FLAG_RELATIVE_OFFSET,
    RT3_SAVE_WORLD_BLOCK_CHAIRMAN_ROLE_GATE_RELATIVE_OFFSET,
    RT3_SAVE_WORLD_BLOCK_CHAIRMAN_ROLE_GATE_STRIDE, RT3_SAVE_WORLD_BLOCK_CHAIRMAN_SLOT_COUNT,
    RT3_SAVE_WORLD_BLOCK_CHAIRMAN_SLOT_SELECTOR_RELATIVE_OFFSET, RT3_SAVE_WORLD_BLOCK_CHUNK_TAG,
    RT3_SAVE_WORLD_BLOCK_LEN, RT3_SAVE_WORLD_BLOCK_NEXT_CHUNK_TAG,
    RT3_SAVE_WORLD_BLOCK_SELECTED_CHAIRMAN_PROFILE_ID_RELATIVE_OFFSET,
    RT3_SAVE_WORLD_BLOCK_SELECTED_COMPANY_ID_RELATIVE_OFFSET,
};
use crate::inspect::smp::common::{find_u32_le_offsets, read_u32_at};
use crate::inspect::smp::world::SmpSaveWorldSelectionContextProbe;

pub(in crate::inspect::smp) fn parse_save_world_selection_context_probe(
    bytes: &[u8],
    file_extension_hint: Option<&str>,
    container_profile: Option<&SmpContainerProfile>,
) -> Option<SmpSaveWorldSelectionContextProbe> {
    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 selected_company_id_offset =
            payload_offset + RT3_SAVE_WORLD_BLOCK_SELECTED_COMPANY_ID_RELATIVE_OFFSET;
        let selected_chairman_profile_id_offset =
            payload_offset + RT3_SAVE_WORLD_BLOCK_SELECTED_CHAIRMAN_PROFILE_ID_RELATIVE_OFFSET;
        let chairman_slot_selector_offset =
            payload_offset + RT3_SAVE_WORLD_BLOCK_CHAIRMAN_SLOT_SELECTOR_RELATIVE_OFFSET;
        let campaign_override_flag_offset =
            payload_offset + RT3_SAVE_WORLD_BLOCK_CAMPAIGN_OVERRIDE_FLAG_RELATIVE_OFFSET;
        let chairman_role_gate_offset =
            payload_offset + RT3_SAVE_WORLD_BLOCK_CHAIRMAN_ROLE_GATE_RELATIVE_OFFSET;
        let selected_company_id = read_u32_at(bytes, selected_company_id_offset)?;
        let selected_chairman_profile_id = read_u32_at(bytes, selected_chairman_profile_id_offset)?;
        let chairman_slot_selectors = bytes
            .get(
                chairman_slot_selector_offset
                    ..chairman_slot_selector_offset + RT3_SAVE_WORLD_BLOCK_CHAIRMAN_SLOT_COUNT,
            )?
            .to_vec();
        let campaign_override_flag = *bytes.get(campaign_override_flag_offset)?;
        let chairman_role_gate_bytes = (0..RT3_SAVE_WORLD_BLOCK_CHAIRMAN_SLOT_COUNT)
            .map(|slot_index| {
                bytes
                    .get(
                        chairman_role_gate_offset
                            + slot_index * RT3_SAVE_WORLD_BLOCK_CHAIRMAN_ROLE_GATE_STRIDE,
                    )
                    .copied()
            })
            .collect::<Option<Vec<_>>>()?;
        return Some(SmpSaveWorldSelectionContextProbe {
            profile_family: profile.profile_family.clone(),
            source_kind: "save-direct-world-block".to_string(),
            semantic_family: "scenario-selected-company-and-chairman-context".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),
            selected_company_id_offset,
            selected_company_id,
            selected_company_id_hex: format!("0x{selected_company_id:08x}"),
            selected_chairman_profile_id_offset,
            selected_chairman_profile_id,
            selected_chairman_profile_id_hex: format!("0x{selected_chairman_profile_id:08x}"),
            chairman_slot_selector_offset,
            chairman_slot_selectors,
            campaign_override_flag_offset,
            campaign_override_flag,
            campaign_override_flag_hex: format!("0x{campaign_override_flag:02x}"),
            chairman_role_gate_offset,
            chairman_role_gate_bytes,
            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!(
                    "selected company id comes from payload +0x{:x} ([world+0x21])",
                    RT3_SAVE_WORLD_BLOCK_SELECTED_COMPANY_ID_RELATIVE_OFFSET
                ),
                format!(
                    "selected chairman profile id comes from payload +0x{:x} ([world+0x25])",
                    RT3_SAVE_WORLD_BLOCK_SELECTED_CHAIRMAN_PROFILE_ID_RELATIVE_OFFSET
                ),
                format!(
                    "16 chairman slot selector bytes come from payload +0x{:x} ([world+0x87])",
                    RT3_SAVE_WORLD_BLOCK_CHAIRMAN_SLOT_SELECTOR_RELATIVE_OFFSET
                ),
                format!(
                    "campaign override flag comes from payload +0x{:x} ([world+0xc5])",
                    RT3_SAVE_WORLD_BLOCK_CAMPAIGN_OVERRIDE_FLAG_RELATIVE_OFFSET
                ),
                format!(
                    "chairman role-gate bytes come from payload +0x{:x} + slot*0x{:x} ([world+0x0bc3+slot*9])",
                    RT3_SAVE_WORLD_BLOCK_CHAIRMAN_ROLE_GATE_RELATIVE_OFFSET,
                    RT3_SAVE_WORLD_BLOCK_CHAIRMAN_ROLE_GATE_STRIDE
                ),
            ],
        });
    }

    None
}
