use crate::inspect::smp::save_load::SmpLoadedSaveSlice;
use crate::state::{RuntimeWorldFinanceNeighborhoodCandidate, RuntimeWorldRestoreState};

fn special_condition_enabled(save_slice: &SmpLoadedSaveSlice, slot_index: u8) -> Option<bool> {
    save_slice.special_conditions_table.as_ref().map(|table| {
        table
            .entries
            .iter()
            .find(|entry| entry.slot_index == slot_index)
            .map(|entry| entry.value != 0)
            .unwrap_or(false)
    })
}

pub(super) fn project_world_restore(save_slice: &SmpLoadedSaveSlice) -> RuntimeWorldRestoreState {
    let Some(profile) = &save_slice.profile else {
        return RuntimeWorldRestoreState::default();
    };
    let disable_cargo_economy_special_condition_enabled = special_condition_enabled(save_slice, 30);

    RuntimeWorldRestoreState {
        selected_year_profile_lane: Some(profile.profile_byte_0x77),
        campaign_scenario_enabled: Some(profile.profile_byte_0xc5 != 0),
        sandbox_enabled: Some(profile.profile_byte_0x82 != 0),
        seed_tuple_written_from_raw_lane: Some(true),
        absolute_counter_requires_shell_context: Some(
            save_slice.world_finance_neighborhood_state.is_none(),
        ),
        absolute_counter_reconstructible_from_save: Some(
            save_slice.world_finance_neighborhood_state.is_some(),
        ),
        packed_year_word_raw_u16: save_slice
            .world_finance_neighborhood_state
            .as_ref()
            .map(|state| state.packed_year_word_raw_u16),
        partial_year_progress_raw_u8: save_slice
            .world_finance_neighborhood_state
            .as_ref()
            .map(|state| state.partial_year_progress_raw_u8),
        current_calendar_tuple_word_raw_u32: save_slice
            .world_finance_neighborhood_state
            .as_ref()
            .map(|state| state.current_calendar_tuple_word_raw_u32),
        current_calendar_tuple_word_2_raw_u32: save_slice
            .world_finance_neighborhood_state
            .as_ref()
            .map(|state| state.current_calendar_tuple_word_2_raw_u32),
        absolute_counter_raw_u32: save_slice
            .world_finance_neighborhood_state
            .as_ref()
            .map(|state| state.absolute_counter_raw_u32),
        absolute_counter_mirror_raw_u32: save_slice
            .world_finance_neighborhood_state
            .as_ref()
            .map(|state| state.absolute_counter_mirror_raw_u32),
        disable_cargo_economy_special_condition_slot: Some(30),
        disable_cargo_economy_special_condition_reconstructible_from_save: Some(true),
        disable_cargo_economy_special_condition_write_side_grounded: Some(true),
        disable_cargo_economy_special_condition_enabled,
        use_bio_accelerator_cars_enabled: special_condition_enabled(save_slice, 29),
        use_wartime_cargos_enabled: special_condition_enabled(save_slice, 31),
        disable_train_crashes_enabled: special_condition_enabled(save_slice, 32),
        disable_train_crashes_and_breakdowns_enabled: special_condition_enabled(save_slice, 33),
        ai_ignore_territories_at_startup_enabled: special_condition_enabled(save_slice, 34),
        limited_track_building_amount: None,
        economic_status_code: None,
        territory_access_cost: None,
        linked_site_removal_follow_on_gate_raw_u8: save_slice
            .world_locomotive_policy_state
            .as_ref()
            .and_then(|state| state.linked_site_removal_follow_on_gate_raw_u8),
        linked_site_removal_follow_on_gate_enabled: save_slice
            .world_locomotive_policy_state
            .as_ref()
            .and_then(|state| state.linked_site_removal_follow_on_gate_raw_u8)
            .map(|raw| raw != 0),
        auto_show_grade_during_track_lay_raw_u8: save_slice
            .world_locomotive_policy_state
            .as_ref()
            .and_then(|state| state.auto_show_grade_during_track_lay_raw_u8),
        starting_building_density_level_raw_u8: save_slice
            .world_locomotive_policy_state
            .as_ref()
            .and_then(|state| state.starting_building_density_level_raw_u8),
        post_text_building_density_growth_raw_u8: save_slice
            .world_locomotive_policy_state
            .as_ref()
            .and_then(|state| state.building_density_growth_raw_u8),
        leftover_simulation_time_accumulator_raw_u32: save_slice
            .world_locomotive_policy_state
            .as_ref()
            .and_then(|state| state.leftover_simulation_time_accumulator_raw_u32),
        leftover_simulation_time_accumulator_value_f32_text: save_slice
            .world_locomotive_policy_state
            .as_ref()
            .and_then(|state| {
                state
                    .leftover_simulation_time_accumulator_value_f32_text
                    .clone()
            }),
        selected_year_lane_snapshot_raw_u8: save_slice
            .world_locomotive_policy_state
            .as_ref()
            .and_then(|state| state.selected_year_lane_snapshot_raw_u8),
        all_steam_locomotives_available_raw_u8: save_slice
            .world_locomotive_policy_state
            .as_ref()
            .and_then(|state| state.all_steam_locomotives_available_raw_u8),
        all_steam_locomotives_available_enabled: save_slice
            .world_locomotive_policy_state
            .as_ref()
            .and_then(|state| state.all_steam_locomotives_available_raw_u8)
            .map(|raw| raw != 0),
        all_diesel_locomotives_available_raw_u8: save_slice
            .world_locomotive_policy_state
            .as_ref()
            .and_then(|state| state.all_diesel_locomotives_available_raw_u8),
        all_diesel_locomotives_available_enabled: save_slice
            .world_locomotive_policy_state
            .as_ref()
            .and_then(|state| state.all_diesel_locomotives_available_raw_u8)
            .map(|raw| raw != 0),
        all_electric_locomotives_available_raw_u8: save_slice
            .world_locomotive_policy_state
            .as_ref()
            .and_then(|state| state.all_electric_locomotives_available_raw_u8),
        all_electric_locomotives_available_enabled: save_slice
            .world_locomotive_policy_state
            .as_ref()
            .and_then(|state| state.all_electric_locomotives_available_raw_u8)
            .map(|raw| raw != 0),
        issue_37_value: save_slice
            .world_issue_37_state
            .as_ref()
            .map(|state| state.issue_value),
        issue_38_value: save_slice
            .world_issue_37_state
            .as_ref()
            .map(|state| state.issue_38_value),
        issue_39_value: save_slice
            .world_issue_37_state
            .as_ref()
            .map(|state| state.issue_39_value),
        issue_3a_value: save_slice
            .world_issue_37_state
            .as_ref()
            .map(|state| state.issue_3a_value),
        issue_37_multiplier_raw_u32: save_slice
            .world_issue_37_state
            .as_ref()
            .map(|state| state.multiplier_raw_u32),
        issue_37_multiplier_value_f32_text: save_slice
            .world_issue_37_state
            .as_ref()
            .map(|state| state.multiplier_value_f32_text.clone()),
        stock_issue_and_buyback_policy_raw_u8: save_slice
            .world_finance_neighborhood_state
            .as_ref()
            .map(|state| state.stock_policy_raw_u8),
        bond_issue_and_repayment_policy_raw_u8: save_slice
            .world_finance_neighborhood_state
            .as_ref()
            .map(|state| state.bond_policy_raw_u8),
        bankruptcy_policy_raw_u8: save_slice
            .world_finance_neighborhood_state
            .as_ref()
            .map(|state| state.bankruptcy_policy_raw_u8),
        dividend_policy_raw_u8: save_slice
            .world_finance_neighborhood_state
            .as_ref()
            .map(|state| state.dividend_policy_raw_u8),
        building_density_growth_setting_raw_u32: save_slice
            .world_finance_neighborhood_state
            .as_ref()
            .map(|state| state.building_density_growth_setting_raw_u32),
        stock_issue_and_buyback_allowed: save_slice
            .world_finance_neighborhood_state
            .as_ref()
            .map(|state| state.stock_policy_raw_u8 == 0),
        bond_issue_and_repayment_allowed: save_slice
            .world_finance_neighborhood_state
            .as_ref()
            .map(|state| state.bond_policy_raw_u8 == 0),
        bankruptcy_allowed: save_slice
            .world_finance_neighborhood_state
            .as_ref()
            .map(|state| state.bankruptcy_policy_raw_u8 == 0),
        dividend_adjustment_allowed: save_slice
            .world_finance_neighborhood_state
            .as_ref()
            .map(|state| state.dividend_policy_raw_u8 == 0),
        finance_neighborhood_candidates: save_slice
            .world_finance_neighborhood_state
            .as_ref()
            .map(|state| {
                state
                    .labels
                    .iter()
                    .enumerate()
                    .map(|(index, label)| RuntimeWorldFinanceNeighborhoodCandidate {
                        label: label.clone(),
                        relative_offset: state.relative_offsets[index],
                        relative_offset_hex: state.relative_offset_hex[index].clone(),
                        raw_u32: state.raw_u32[index],
                        raw_u32_hex: state.raw_hex[index].clone(),
                        value_i32: state.value_i32[index],
                        value_f32_text: state.value_f32_text[index].clone(),
                    })
                    .collect::<Vec<_>>()
            })
            .unwrap_or_default(),
        economic_tuning_mirror_raw_u32: save_slice
            .world_economic_tuning_state
            .as_ref()
            .map(|state| state.mirror_raw_u32),
        economic_tuning_mirror_value_f32_text: save_slice
            .world_economic_tuning_state
            .as_ref()
            .map(|state| state.mirror_value_f32_text.clone()),
        economic_tuning_lane_raw_u32: save_slice
            .world_economic_tuning_state
            .as_ref()
            .map(|state| state.lane_raw_u32.clone())
            .unwrap_or_default(),
        economic_tuning_lane_value_f32_text: save_slice
            .world_economic_tuning_state
            .as_ref()
            .map(|state| state.lane_value_f32_text.clone())
            .unwrap_or_default(),
        cached_available_locomotive_rating_raw_u32: save_slice
            .world_locomotive_policy_state
            .as_ref()
            .and_then(|state| state.cached_available_locomotive_rating_raw_u32),
        cached_available_locomotive_rating_value_f32_text: save_slice
            .world_locomotive_policy_state
            .as_ref()
            .and_then(|state| {
                state
                    .cached_available_locomotive_rating_value_f32_text
                    .clone()
            }),
        selected_year_bucket_direct_lane_raw_u32: Vec::new(),
        selected_year_bucket_direct_lane_value_f32_text: Vec::new(),
        selected_year_bucket_complement_lane_raw_u32: Vec::new(),
        selected_year_bucket_complement_lane_value_f32_text: Vec::new(),
        selected_year_bucket_scaled_companion_lane_raw_u32: Vec::new(),
        selected_year_bucket_scaled_companion_lane_value_f32_text: Vec::new(),
        selected_year_bucket_scalar_raw_u32: None,
        selected_year_bucket_scalar_value_f32_text: None,
        selected_year_gap_scalar_raw_u32: None,
        selected_year_gap_scalar_value_f32_text: None,
        absolute_counter_restore_kind: Some(
            if save_slice.world_finance_neighborhood_state.is_some() {
                "save-direct-world-absolute-counter".to_string()
            } else {
                "mode-adjusted-selected-year-lane".to_string()
            },
        ),
        absolute_counter_adjustment_context: Some(
            if save_slice.world_finance_neighborhood_state.is_some() {
                "save-direct-world-block-0x32c8".to_string()
            } else {
                "editor-map-mode,shell-selected-year-adjust-policy-0x9d26-0x9d28,save-special-condition-disable-cargo-economy-slot-30"
                    .to_string()
            },
        ),
    }
}
