//! Verify generated types exist and are constructable.

use bo4e_edifact_types::generated::companions::*;

#[test]
fn test_companion_types_exist() {
    let _m = MarktlokationEdifact::default();
    let _g = GeschaeftspartnerEdifact::default();
    let _p = ProzessdatenEdifact::default();
}

#[test]
fn test_companion_serde_roundtrip() {
    let companion = MarktlokationEdifact {
        haushaltskunde: Some("Z18".to_string()),
        ..Default::default()
    };
    let json = serde_json::to_string(&companion).unwrap();
    let deserialized: MarktlokationEdifact = serde_json::from_str(&json).unwrap();
    assert_eq!(deserialized.haushaltskunde.as_deref(), Some("Z18"));
}

#[cfg(feature = "fv2504")]
mod fv2504_tests {
    use bo4e_edifact_types::generated::fv2504::utilmd_strom::entities::*;
    use bo4e_edifact_types::generated::fv2504::utilmd_strom::pids::*;

    #[test]
    fn test_pid_55001_types_exist() {
    let _m = Pid55001MessageStammdaten::default();
    let _t = Pid55001TransaktionStammdaten::default();
}

#[test]
fn test_pid_55001_interchange_type_alias() {
    let interchange = Pid55001Interchange {
        interchangedaten: bo4e_edifact_types::Interchangedaten::default(),
        nachrichten: vec![],
    };
    assert!(interchange.nachrichten.is_empty());
}

// --- BTreeMap deserialization tests for Marktteilnehmer ---

#[test]
fn test_marktteilnehmer_map_from_engine_array() {
    // Simulate mapping engine output: array format with marktrolle as discriminator string.
    // The deserialize_map_or_vec function should find "MS"/"MR" in string fields
    // and use them as BTreeMap keys.
    let json = serde_json::json!({
        "marktteilnehmer": [
            {
                "marktrolle": "MS",
                "rollencodenummer": "9978842000002",
                "rollencodetyp": "BDEW"
            },
            {
                "marktrolle": "MR",
                "rollencodenummer": "9912345000003",
                "rollencodetyp": "BDEW"
            }
        ]
    });

    let msg: Pid55001MessageStammdaten = serde_json::from_value(json).unwrap();
    let mt = msg.marktteilnehmer.unwrap();
    assert_eq!(mt.len(), 2);
    assert!(mt.contains_key(&MarktteilnehmerKey::Ms));
    assert!(mt.contains_key(&MarktteilnehmerKey::Mr));
}

#[test]
fn test_marktteilnehmer_map_from_typed_json() {
    // Object/map format: keys are "MS"/"MR" directly.
    let json = serde_json::json!({
        "marktteilnehmer": {
            "MS": {
                "rollencodenummer": "9978842000002"
            },
            "MR": {
                "rollencodenummer": "9912345000003"
            }
        }
    });

    let msg: Pid55001MessageStammdaten = serde_json::from_value(json).unwrap();
    let mt = msg.marktteilnehmer.unwrap();
    assert_eq!(mt.len(), 2);
    assert!(mt.contains_key(&MarktteilnehmerKey::Ms));
    assert!(mt.contains_key(&MarktteilnehmerKey::Mr));
}

#[test]
fn test_marktteilnehmer_map_serializes_as_object() {
    use std::collections::BTreeMap;

    let mut mt = BTreeMap::new();
    mt.insert(MarktteilnehmerKey::Ms, MarktteilnehmerWrapped::default());
    mt.insert(MarktteilnehmerKey::Mr, MarktteilnehmerWrapped::default());
    let msg = Pid55001MessageStammdaten {
        marktteilnehmer: Some(mt),
        ..Default::default()
    };
    let json = serde_json::to_value(&msg).unwrap();
    // BTreeMap serializes as a JSON object with "MS"/"MR" keys
    assert!(
        json["marktteilnehmer"].is_object(),
        "expected object, got: {}",
        json["marktteilnehmer"]
    );
    assert!(json["marktteilnehmer"]["MS"].is_object());
    assert!(json["marktteilnehmer"]["MR"].is_object());
}

#[test]
fn test_marktteilnehmer_map_null_and_missing() {
    // null → None
    let json = serde_json::json!({ "marktteilnehmer": null });
    let msg: Pid55001MessageStammdaten = serde_json::from_value(json).unwrap();
    assert!(msg.marktteilnehmer.is_none());

    // missing field → None (via #[serde(default)])
    let json = serde_json::json!({});
    let msg: Pid55001MessageStammdaten = serde_json::from_value(json).unwrap();
    assert!(msg.marktteilnehmer.is_none());
}

#[test]
fn test_marktteilnehmer_map_roundtrip_serde() {
    use std::collections::BTreeMap;

    // Build typed → serialize → deserialize → compare
    let mut mt = BTreeMap::new();
    mt.insert(MarktteilnehmerKey::Ms, MarktteilnehmerWrapped::default());
    let msg = Pid55001MessageStammdaten {
        marktteilnehmer: Some(mt),
        ..Default::default()
    };
    let json = serde_json::to_value(&msg).unwrap();
    let roundtripped: Pid55001MessageStammdaten = serde_json::from_value(json).unwrap();
    let rt_mt = roundtripped.marktteilnehmer.unwrap();
    assert_eq!(rt_mt.len(), 1);
    assert!(rt_mt.contains_key(&MarktteilnehmerKey::Ms));
}
} // mod fv2504_tests
