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

pub(in crate::inspect::smp) fn real_ordinary_condition_metric_label(
    metadata: RealOrdinaryConditionMetadata,
    candidate_name: Option<&str>,
) -> String {
    match metadata.kind {
        RealOrdinaryConditionKind::Numeric(_) => metadata.label.to_string(),
        RealOrdinaryConditionKind::WorldState(RealWorldConditionKind::SpecialCondition {
            label,
        }) => format!("Special Condition: {label}"),
        RealOrdinaryConditionKind::WorldState(RealWorldConditionKind::CandidateAvailability) => {
            match candidate_name {
                Some(name) => format!("Candidate Availability: {name}"),
                None => "Candidate Availability".to_string(),
            }
        }
        RealOrdinaryConditionKind::WorldState(
            RealWorldConditionKind::NamedLocomotiveAvailability,
        ) => match candidate_name {
            Some(name) => format!("Named Locomotive Availability: {name}"),
            None => "Named Locomotive Availability".to_string(),
        },
        RealOrdinaryConditionKind::WorldState(RealWorldConditionKind::NamedLocomotiveCost) => {
            match candidate_name {
                Some(name) => format!("Named Locomotive Cost: {name}"),
                None => "Named Locomotive Cost".to_string(),
            }
        }
        RealOrdinaryConditionKind::WorldState(RealWorldConditionKind::CargoProductionSlot) => {
            match candidate_name {
                Some(name) => format!("Cargo Production: {name}"),
                None => "Cargo Production".to_string(),
            }
        }
        RealOrdinaryConditionKind::WorldState(RealWorldConditionKind::CargoProductionTotal) => {
            "Cargo Production Total".to_string()
        }
        RealOrdinaryConditionKind::WorldState(RealWorldConditionKind::FactoryProductionTotal) => {
            "Factory Production Total".to_string()
        }
        RealOrdinaryConditionKind::WorldState(RealWorldConditionKind::FarmMineProductionTotal) => {
            "Farm/Mine Production Total".to_string()
        }
        RealOrdinaryConditionKind::WorldState(
            RealWorldConditionKind::OtherCargoProductionTotal,
        ) => "Other Cargo Production Total".to_string(),
        RealOrdinaryConditionKind::WorldState(
            RealWorldConditionKind::LimitedTrackBuildingAmount,
        ) => "Limited Track Building Amount".to_string(),
        RealOrdinaryConditionKind::WorldState(RealWorldConditionKind::TerritoryAccessCost) => {
            "Territory Access Cost".to_string()
        }
        RealOrdinaryConditionKind::WorldState(RealWorldConditionKind::EconomicStatus) => {
            "Economic Status".to_string()
        }
        RealOrdinaryConditionKind::WorldState(RealWorldConditionKind::WorldFlag { .. }) => {
            format!("World Flag: {}", metadata.label)
        }
    }
}

pub(in crate::inspect::smp) fn real_ordinary_condition_semantic_family(
    metadata: RealOrdinaryConditionMetadata,
) -> &'static str {
    match metadata.kind {
        RealOrdinaryConditionKind::Numeric(_) => "numeric_threshold",
        RealOrdinaryConditionKind::WorldState(RealWorldConditionKind::WorldFlag { .. }) => {
            "world_flag_equals"
        }
        RealOrdinaryConditionKind::WorldState(
            RealWorldConditionKind::NamedLocomotiveAvailability
            | RealWorldConditionKind::NamedLocomotiveCost
            | RealWorldConditionKind::CargoProductionSlot
            | RealWorldConditionKind::CargoProductionTotal
            | RealWorldConditionKind::FactoryProductionTotal
            | RealWorldConditionKind::FarmMineProductionTotal
            | RealWorldConditionKind::OtherCargoProductionTotal
            | RealWorldConditionKind::LimitedTrackBuildingAmount
            | RealWorldConditionKind::TerritoryAccessCost,
        ) => "world_scalar_threshold",
        RealOrdinaryConditionKind::WorldState(_) => "world_state_threshold",
    }
}

pub(in crate::inspect::smp) fn decode_real_condition_comparator(
    subtype: u8,
) -> Option<RuntimeConditionComparator> {
    match subtype {
        0 => Some(RuntimeConditionComparator::Ge),
        1 => Some(RuntimeConditionComparator::Le),
        2 => Some(RuntimeConditionComparator::Gt),
        3 => Some(RuntimeConditionComparator::Lt),
        4 => Some(RuntimeConditionComparator::Eq),
        5 => Some(RuntimeConditionComparator::Ne),
        _ => None,
    }
}

pub(in crate::inspect::smp) fn decode_real_condition_threshold(flag_bytes: &[u8]) -> Option<i64> {
    let raw = flag_bytes.get(0..4)?;
    let mut bytes = [0u8; 4];
    bytes.copy_from_slice(raw);
    Some(i32::from_le_bytes(bytes).into())
}

pub(in crate::inspect::smp) fn condition_comparator_label(
    comparator: RuntimeConditionComparator,
) -> String {
    match comparator {
        RuntimeConditionComparator::Ge => "ge".to_string(),
        RuntimeConditionComparator::Le => "le".to_string(),
        RuntimeConditionComparator::Gt => "gt".to_string(),
        RuntimeConditionComparator::Lt => "lt".to_string(),
        RuntimeConditionComparator::Eq => "eq".to_string(),
        RuntimeConditionComparator::Ne => "ne".to_string(),
    }
}

pub(in crate::inspect::smp) fn condition_comparator_symbol(
    comparator: RuntimeConditionComparator,
) -> &'static str {
    match comparator {
        RuntimeConditionComparator::Ge => ">=",
        RuntimeConditionComparator::Le => "<=",
        RuntimeConditionComparator::Gt => ">",
        RuntimeConditionComparator::Lt => "<",
        RuntimeConditionComparator::Eq => "==",
        RuntimeConditionComparator::Ne => "!=",
    }
}
