use super::super::{RuntimeImportContext, RuntimeStateInput, SaveSliceProjectionMode};
use super::{
    build_overlay_runtime_state, build_standalone_runtime_state, project_save_slice_components,
};
use crate::inspect::smp::save_load::SmpLoadedSaveSlice;
use crate::state::RuntimeState;

pub fn build_runtime_state_input_from_save_slice(
    save_slice: &SmpLoadedSaveSlice,
    input_id: &str,
    description: Option<String>,
) -> Result<RuntimeStateInput, String> {
    if input_id.trim().is_empty() {
        return Err("input_id must not be empty".to_string());
    }
    let projection = project_save_slice_components(
        save_slice,
        &RuntimeImportContext::standalone(),
        SaveSliceProjectionMode::Standalone,
    )?;

    let mut state = build_standalone_runtime_state(projection);
    state.refresh_derived_world_state();
    state.refresh_derived_market_state();
    state.validate()?;

    Ok(RuntimeStateInput {
        input_id: input_id.to_string(),
        description,
        state,
    })
}

pub fn build_runtime_state_input_from_overlay(
    base_state: &RuntimeState,
    save_slice: &SmpLoadedSaveSlice,
    input_id: &str,
    description: Option<String>,
) -> Result<RuntimeStateInput, String> {
    if input_id.trim().is_empty() {
        return Err("input_id must not be empty".to_string());
    }
    base_state.validate()?;

    let runtime_context = RuntimeImportContext::from_runtime_state(base_state);
    let projection = project_save_slice_components(
        save_slice,
        &runtime_context,
        SaveSliceProjectionMode::Overlay,
    )?;

    let mut state = build_overlay_runtime_state(base_state, projection);
    state.refresh_derived_world_state();
    state.refresh_derived_market_state();
    state.validate()?;

    Ok(RuntimeStateInput {
        input_id: input_id.to_string(),
        description,
        state,
    })
}
