use crate::inspect::smp::events::*;
use crate::inspect::smp::*;

fn runtime_variable_index(descriptor_id: u32) -> Option<u32> {
    match descriptor_id {
        39..=42 => Some(descriptor_id - 38),
        43..=46 => Some(descriptor_id - 42),
        47..=50 => Some(descriptor_id - 46),
        51..=54 => Some(descriptor_id - 50),
        _ => None,
    }
}

pub(super) fn decode_runtime_variable_effect(
    row: &SmpLoadedPackedEventGroupedEffectRowSummary,
    compact_control: &SmpLoadedPackedEventCompactControlSummary,
    descriptor_metadata: RealGroupedEffectDescriptorMetadata,
    target_subject: Option<RealGroupedTargetSubject>,
    target_scope_ordinal: u8,
) -> Option<RuntimeEffect> {
    if !(descriptor_metadata.executable_in_runtime
        && descriptor_metadata.parameter_family == "runtime_variable_scalar"
        && row.row_shape == "scalar_assignment")
    {
        return None;
    }

    let index = runtime_variable_index(descriptor_metadata.descriptor_id)?;
    match target_subject {
        Some(RealGroupedTargetSubject::WholeGame) => Some(RuntimeEffect::SetWorldVariable {
            index,
            value: i64::from(row.raw_scalar_value),
        }),
        Some(RealGroupedTargetSubject::Company) => Some(RuntimeEffect::SetCompanyVariable {
            target: real_grouped_company_target(target_scope_ordinal)?,
            index,
            value: i64::from(row.raw_scalar_value),
        }),
        Some(RealGroupedTargetSubject::Player) => Some(RuntimeEffect::SetPlayerVariable {
            target: real_grouped_player_target(target_scope_ordinal)?,
            index,
            value: i64::from(row.raw_scalar_value),
        }),
        Some(RealGroupedTargetSubject::Territory) => compact_control
            .grouped_territory_selectors_0x80f
            .get(row.group_index)
            .copied()
            .filter(|selector| *selector >= 0)
            .map(|selector| RuntimeEffect::SetTerritoryVariable {
                target: RuntimeTerritoryTarget::Ids {
                    ids: vec![selector as u32],
                },
                index,
                value: i64::from(row.raw_scalar_value),
            }),
        _ => None,
    }
}
