use crate::inspect::smp::save_load::*;

pub(in crate::inspect::smp) fn build_save_load_summary(
    file_extension_hint: Option<&str>,
    container_profile: Option<&SmpContainerProfile>,
    runtime_trailer_block: Option<&SmpRuntimeTrailerBlock>,
    rt3_105_post_span_bridge_probe: Option<&SmpRt3105PostSpanBridgeProbe>,
    classic_rehydrate_profile_probe: Option<&SmpClassicRehydrateProfileProbe>,
    rt3_105_packed_profile_probe: Option<&SmpRt3105PackedProfileProbe>,
    rt3_105_save_name_table_probe: Option<&SmpRt3105SaveNameTableProbe>,
) -> Option<SmpSaveLoadSummary> {
    let file_extension_hint = file_extension_hint.map(str::to_string);
    let container_profile_family = container_profile.map(|profile| profile.profile_family.clone());
    let trailer_family = runtime_trailer_block.map(|trailer| trailer.trailer_family.clone());
    let bridge_family = rt3_105_post_span_bridge_probe.map(|bridge| bridge.bridge_family.clone());
    let candidate_table =
        rt3_105_save_name_table_probe.map(|probe| SmpSaveLoadCandidateTableSummary {
            source_kind: probe.source_kind.clone(),
            semantic_family: probe.semantic_family.clone(),
            observed_entry_count: probe.observed_entry_count,
            zero_availability_count: probe.zero_trailer_entry_count,
            zero_availability_names: probe.zero_trailer_entry_names.clone(),
            footer_progress_hex_words: vec![
                probe.footer_progress_word_0_hex.clone(),
                probe.footer_progress_word_1_hex.clone(),
            ],
        });

    if let Some(probe) = classic_rehydrate_profile_probe {
        let block = &probe.packed_profile_block;
        let mut notes = vec![
            "Classic save load reaches the grounded late rehydrate band 0x32dc -> 0x3714 -> 0x3715."
                .to_string(),
            "The file exposes one exact 0x108 packed-profile block between progress ids 0x3714 and 0x3715."
                .to_string(),
        ];
        if let Some(map_path) = &block.map_path {
            notes.push(format!("Packed profile map path: {map_path}"));
        }
        if let Some(display_name) = &block.display_name {
            notes.push(format!("Packed profile display name: {display_name}"));
        }

        return Some(SmpSaveLoadSummary {
            file_extension_hint,
            container_profile_family,
            mechanism_family: "classic-save-rehydrate-v1".to_string(),
            mechanism_confidence: "grounded".to_string(),
            packed_profile_kind: Some("classic-rehydrate-profile".to_string()),
            packed_profile_family: Some(probe.profile_family.clone()),
            packed_profile_offset: Some(probe.packed_profile_offset),
            packed_profile_len: Some(probe.packed_profile_len),
            map_path: block.map_path.clone(),
            display_name: block.display_name.clone(),
            profile_byte_0x77: Some(block.profile_byte_0x77),
            profile_byte_0x77_hex: Some(block.profile_byte_0x77_hex.clone()),
            profile_byte_0x82: Some(block.profile_byte_0x82),
            profile_byte_0x82_hex: Some(block.profile_byte_0x82_hex.clone()),
            profile_byte_0x97: Some(block.profile_byte_0x97),
            profile_byte_0x97_hex: Some(block.profile_byte_0x97_hex.clone()),
            profile_byte_0xc5: Some(block.profile_byte_0xc5),
            profile_byte_0xc5_hex: Some(block.profile_byte_0xc5_hex.clone()),
            trailer_family,
            bridge_family: None,
            candidate_table,
            notes,
        });
    }

    if let Some(probe) = rt3_105_packed_profile_probe {
        let block = &probe.packed_profile_block;
        let mechanism_family = rt3_105_post_span_bridge_probe
            .map(|bridge| bridge.bridge_family.clone())
            .unwrap_or_else(|| match probe.profile_family.as_str() {
                "rt3-105-scenario-save-container-v1" => {
                    "rt3-105-scenario-save-profile-analog-v1".to_string()
                }
                "rt3-105-alt-save-container-v1" => "rt3-105-alt-save-profile-analog-v1".to_string(),
                _ => "rt3-105-save-profile-analog-v1".to_string(),
            });
        let mechanism_confidence = if rt3_105_post_span_bridge_probe.is_some() {
            "mixed"
        } else {
            "inferred"
        }
        .to_string();
        let mut notes = Vec::new();
        if let Some(bridge) = rt3_105_post_span_bridge_probe {
            notes.push(format!(
                "RT3 1.05 save branch uses {} with selector/descriptor {} -> {}.",
                bridge.bridge_family, bridge.selector_high_hex, bridge.descriptor_high_hex
            ));
        } else {
            notes.push(
                "RT3 1.05 save exposes a packed-profile analogue, but the upstream load bridge is not resolved for this branch."
                    .to_string(),
            );
        }
        if let Some(map_path) = &block.map_path {
            notes.push(format!("Packed profile map path: {map_path}"));
        }
        if let Some(display_name) = &block.display_name {
            notes.push(format!("Packed profile display name: {display_name}"));
        }
        if let Some(table) = &candidate_table {
            notes.push(format!(
                "Candidate table source {} carries {} entries with {} zero-availability overrides.",
                table.source_kind, table.observed_entry_count, table.zero_availability_count
            ));
        }

        return Some(SmpSaveLoadSummary {
            file_extension_hint,
            container_profile_family,
            mechanism_family,
            mechanism_confidence,
            packed_profile_kind: Some("rt3-105-packed-profile".to_string()),
            packed_profile_family: Some(probe.profile_family.clone()),
            packed_profile_offset: Some(probe.packed_profile_offset),
            packed_profile_len: Some(probe.packed_profile_len),
            map_path: block.map_path.clone(),
            display_name: block.display_name.clone(),
            profile_byte_0x77: Some(block.profile_byte_0x77),
            profile_byte_0x77_hex: Some(block.profile_byte_0x77_hex.clone()),
            profile_byte_0x82: Some(block.profile_byte_0x82),
            profile_byte_0x82_hex: Some(block.profile_byte_0x82_hex.clone()),
            profile_byte_0x97: Some(block.profile_byte_0x97),
            profile_byte_0x97_hex: Some(block.profile_byte_0x97_hex.clone()),
            profile_byte_0xc5: Some(block.profile_byte_0xc5),
            profile_byte_0xc5_hex: Some(block.profile_byte_0xc5_hex.clone()),
            trailer_family,
            bridge_family,
            candidate_table,
            notes,
        });
    }

    if let Some(table) = candidate_table {
        return Some(SmpSaveLoadSummary {
            file_extension_hint,
            container_profile_family,
            mechanism_family: "rt3-105-candidate-catalog-source-v1".to_string(),
            mechanism_confidence: "mixed".to_string(),
            packed_profile_kind: None,
            packed_profile_family: None,
            packed_profile_offset: None,
            packed_profile_len: None,
            map_path: None,
            display_name: None,
            profile_byte_0x77: None,
            profile_byte_0x77_hex: None,
            profile_byte_0x82: None,
            profile_byte_0x82_hex: None,
            profile_byte_0x97: None,
            profile_byte_0x97_hex: None,
            profile_byte_0xc5: None,
            profile_byte_0xc5_hex: None,
            trailer_family,
            bridge_family,
            notes: vec![
                format!(
                    "The file carries the shared 1.05 candidate table source block through {}.",
                    table.source_kind
                ),
                format!(
                    "The table exposes {} named entries with {} zero-availability overrides.",
                    table.observed_entry_count, table.zero_availability_count
                ),
            ],
            candidate_table: Some(table),
        });
    }

    None
}
