use super::super::{RuntimeImportContext, SaveSliceProjection, SaveSliceProjectionMode};
use super::{
    PackedEventProjection, ProfileWorldProjection, ProjectionMetadata,
    append_projection_collection_metadata, append_projection_note_metadata,
    build_projection_metadata, project_chairman_projection, project_company_projection,
    project_event_runtime, project_near_city_projection, project_profile_world,
};
use crate::inspect::smp::save_load::SmpLoadedSaveSlice;

pub(super) fn project_save_slice_components(
    save_slice: &SmpLoadedSaveSlice,
    runtime_context: &RuntimeImportContext,
    mode: SaveSliceProjectionMode,
) -> Result<SaveSliceProjection, String> {
    let ProjectionMetadata {
        world_flags,
        mut metadata,
    } = build_projection_metadata(save_slice, mode);
    let ProfileWorldProjection {
        save_profile,
        world_restore,
        candidate_availability,
        named_locomotive_availability,
        locomotive_catalog,
        cargo_catalog,
        named_locomotive_cost,
        all_cargo_price_override,
        named_cargo_price_overrides,
        all_cargo_production_override,
        factory_cargo_production_override,
        farm_mine_cargo_production_override,
        named_cargo_production_overrides,
        cargo_production_overrides,
        world_scalar_overrides,
        special_conditions,
    } = project_profile_world(save_slice, &mut metadata);
    let company_projection = project_company_projection(save_slice, &mut metadata);
    let chairman_projection = project_chairman_projection(save_slice, &mut metadata);
    let near_city_projection =
        project_near_city_projection(save_slice, &company_projection, &mut metadata);

    append_projection_collection_metadata(save_slice, &mut metadata);

    let PackedEventProjection {
        packed_event_collection,
        event_runtime_records,
    } = project_event_runtime(
        save_slice,
        runtime_context,
        &company_projection,
        &chairman_projection,
        locomotive_catalog.as_deref(),
        cargo_catalog.as_deref(),
        &mut metadata,
    )?;

    append_projection_note_metadata(save_slice, &mut metadata);

    Ok(SaveSliceProjection {
        world_flags,
        save_profile,
        world_restore,
        metadata,
        packed_event_collection,
        event_runtime_records,
        companies: company_projection.companies,
        has_company_projection: company_projection.has_company_projection,
        has_company_selection_override: company_projection.has_company_selection_override,
        selected_company_id: company_projection.selected_company_id,
        company_market_state: company_projection.company_market_state,
        company_periodic_side_latch_state: company_projection.company_periodic_side_latch_state,
        has_company_market_projection: company_projection.has_company_market_projection,
        world_issue_opinion_base_terms_raw_i32: company_projection
            .world_issue_opinion_base_terms_raw_i32,
        chairman_profiles: chairman_projection.chairman_profiles,
        has_chairman_projection: chairman_projection.has_chairman_projection,
        has_chairman_selection_override: chairman_projection.has_chairman_selection_override,
        selected_chairman_profile_id: chairman_projection.selected_chairman_profile_id,
        chairman_issue_opinion_terms_raw_i32: chairman_projection
            .chairman_issue_opinion_terms_raw_i32,
        chairman_personality_raw_u8: chairman_projection.chairman_personality_raw_u8,
        near_city_acquisition_regions: near_city_projection.regions,
        near_city_acquisition_sites: near_city_projection.sites,
        has_near_city_projection: near_city_projection.has_projection,
        candidate_availability,
        named_locomotive_availability,
        locomotive_catalog,
        cargo_catalog,
        named_locomotive_cost,
        all_cargo_price_override,
        named_cargo_price_overrides,
        all_cargo_production_override,
        factory_cargo_production_override,
        farm_mine_cargo_production_override,
        named_cargo_production_overrides,
        cargo_production_overrides,
        world_scalar_overrides,
        special_conditions,
    })
}
