use crate::inspect::smp::events::actions::world::decode_world_effect;
use crate::inspect::smp::events::actions::{actors, catalogs, runtime_variables, trains};
use crate::inspect::smp::events::*;
use crate::inspect::smp::*;

pub(in crate::inspect::smp) fn decode_real_grouped_effect_actions(
    grouped_effect_rows: &[SmpLoadedPackedEventGroupedEffectRowSummary],
    compact_control: &SmpLoadedPackedEventCompactControlSummary,
) -> Vec<RuntimeEffect> {
    grouped_effect_rows
        .iter()
        .filter_map(|row| decode_real_grouped_effect_action(row, compact_control))
        .collect()
}

pub(in crate::inspect::smp) fn decode_real_grouped_effect_action(
    row: &SmpLoadedPackedEventGroupedEffectRowSummary,
    compact_control: &SmpLoadedPackedEventCompactControlSummary,
) -> Option<RuntimeEffect> {
    let descriptor_metadata = real_grouped_effect_descriptor_metadata(row.descriptor_id)?;
    let target_scope_ordinal = compact_control
        .grouped_target_scope_ordinals_0x7fb
        .get(row.group_index)
        .copied()?;
    let target_subject = derive_real_grouped_target_subject(row, compact_control);

    runtime_variables::decode_runtime_variable_effect(
        row,
        compact_control,
        descriptor_metadata,
        target_subject,
        target_scope_ordinal,
    )
    .or_else(|| {
        actors::decode_actor_effect(
            row,
            compact_control,
            descriptor_metadata,
            target_subject,
            target_scope_ordinal,
        )
    })
    .or_else(|| decode_world_effect(row, descriptor_metadata))
    .or_else(|| catalogs::decode_catalog_effect(row, descriptor_metadata))
    .or_else(|| {
        trains::decode_train_effect(
            row,
            compact_control,
            descriptor_metadata,
            target_scope_ordinal,
        )
    })
}
