use super::context::ValidationContext;
use crate::state::RuntimeState;

pub(super) fn validate_runtime_variables(
    state: &RuntimeState,
    context: &ValidationContext,
) -> Result<(), String> {
    for key in state.candidate_availability.keys() {
        if key.trim().is_empty() {
            return Err("candidate_availability contains an empty key".to_string());
        }
    }
    for key in state.named_locomotive_availability.keys() {
        if key.trim().is_empty() {
            return Err("named_locomotive_availability contains an empty key".to_string());
        }
    }
    for key in state.named_locomotive_cost.keys() {
        if key.trim().is_empty() {
            return Err("named_locomotive_cost contains an empty key".to_string());
        }
    }
    for key in state.named_cargo_price_overrides.keys() {
        if key.trim().is_empty() {
            return Err("named_cargo_price_overrides contains an empty key".to_string());
        }
    }
    for key in state.named_cargo_production_overrides.keys() {
        if key.trim().is_empty() {
            return Err("named_cargo_production_overrides contains an empty key".to_string());
        }
    }
    for slot in state.cargo_production_overrides.keys() {
        if !(1..=11).contains(slot) {
            return Err(format!(
                "cargo_production_overrides contains out-of-range slot {}",
                slot
            ));
        }
    }
    for index in state.world_runtime_variables.keys() {
        if !(1..=4).contains(index) {
            return Err(format!(
                "world_runtime_variables contains out-of-range index {}",
                index
            ));
        }
    }
    for (company_id, vars) in &state.company_runtime_variables {
        if !context.seen_company_ids.contains(company_id) {
            return Err(format!(
                "company_runtime_variables references unknown company_id {}",
                company_id
            ));
        }
        for index in vars.keys() {
            if !(1..=4).contains(index) {
                return Err(format!(
                    "company_runtime_variables[{company_id}] contains out-of-range index {}",
                    index
                ));
            }
        }
    }
    for (player_id, vars) in &state.player_runtime_variables {
        if !context.seen_player_ids.contains(player_id) {
            return Err(format!(
                "player_runtime_variables references unknown player_id {}",
                player_id
            ));
        }
        for index in vars.keys() {
            if !(1..=4).contains(index) {
                return Err(format!(
                    "player_runtime_variables[{player_id}] contains out-of-range index {}",
                    index
                ));
            }
        }
    }
    for (territory_id, vars) in &state.territory_runtime_variables {
        if !context.seen_territory_ids.contains(territory_id) {
            return Err(format!(
                "territory_runtime_variables references unknown territory_id {}",
                territory_id
            ));
        }
        for index in vars.keys() {
            if !(1..=4).contains(index) {
                return Err(format!(
                    "territory_runtime_variables[{territory_id}] contains out-of-range index {}",
                    index
                ));
            }
        }
    }
    for key in state.world_scalar_overrides.keys() {
        if key.trim().is_empty() {
            return Err("world_scalar_overrides contains an empty key".to_string());
        }
    }
    for key in state.special_conditions.keys() {
        if key.trim().is_empty() {
            return Err("special_conditions contains an empty key".to_string());
        }
    }

    Ok(())
}
