use std::collections::BTreeMap;

use serde::{Deserialize, Serialize};

use crate::event::packed::RuntimePackedEventCollectionSummary;
use crate::event::records::RuntimeEventRecord;
use crate::state::{
    CalendarPoint, RuntimeCargoCatalogEntry, RuntimeChairmanProfile, RuntimeCompany,
    RuntimeCompanyTerritoryAccess, RuntimeCompanyTerritoryTrackPieceCount,
    RuntimeLocomotiveCatalogEntry, RuntimePlayer, RuntimeSaveProfileState, RuntimeServiceState,
    RuntimeTerritory, RuntimeTrain, RuntimeWorldRestoreState,
};

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuntimeState {
    pub calendar: CalendarPoint,
    #[serde(default)]
    pub world_flags: BTreeMap<String, bool>,
    #[serde(default)]
    pub save_profile: RuntimeSaveProfileState,
    #[serde(default)]
    pub world_restore: RuntimeWorldRestoreState,
    #[serde(default)]
    pub metadata: BTreeMap<String, String>,
    #[serde(default)]
    pub companies: Vec<RuntimeCompany>,
    #[serde(default)]
    pub selected_company_id: Option<u32>,
    #[serde(default)]
    pub players: Vec<RuntimePlayer>,
    #[serde(default)]
    pub selected_player_id: Option<u32>,
    #[serde(default)]
    pub chairman_profiles: Vec<RuntimeChairmanProfile>,
    #[serde(default)]
    pub selected_chairman_profile_id: Option<u32>,
    #[serde(default)]
    pub trains: Vec<RuntimeTrain>,
    #[serde(default)]
    pub locomotive_catalog: Vec<RuntimeLocomotiveCatalogEntry>,
    #[serde(default)]
    pub cargo_catalog: Vec<RuntimeCargoCatalogEntry>,
    #[serde(default)]
    pub territories: Vec<RuntimeTerritory>,
    #[serde(default)]
    pub company_territory_track_piece_counts: Vec<RuntimeCompanyTerritoryTrackPieceCount>,
    #[serde(default)]
    pub company_territory_access: Vec<RuntimeCompanyTerritoryAccess>,
    #[serde(default)]
    pub packed_event_collection: Option<RuntimePackedEventCollectionSummary>,
    #[serde(default)]
    pub event_runtime_records: Vec<RuntimeEventRecord>,
    #[serde(default)]
    pub candidate_availability: BTreeMap<String, u32>,
    #[serde(default)]
    pub named_locomotive_availability: BTreeMap<String, u32>,
    #[serde(default)]
    pub named_locomotive_cost: BTreeMap<String, u32>,
    #[serde(default)]
    pub all_cargo_price_override: Option<u32>,
    #[serde(default)]
    pub named_cargo_price_overrides: BTreeMap<String, u32>,
    #[serde(default)]
    pub all_cargo_production_override: Option<u32>,
    #[serde(default)]
    pub factory_cargo_production_override: Option<u32>,
    #[serde(default)]
    pub farm_mine_cargo_production_override: Option<u32>,
    #[serde(default)]
    pub named_cargo_production_overrides: BTreeMap<String, u32>,
    #[serde(default)]
    pub cargo_production_overrides: BTreeMap<u32, u32>,
    #[serde(default)]
    pub world_runtime_variables: BTreeMap<u32, i64>,
    #[serde(default)]
    pub company_runtime_variables: BTreeMap<u32, BTreeMap<u32, i64>>,
    #[serde(default)]
    pub player_runtime_variables: BTreeMap<u32, BTreeMap<u32, i64>>,
    #[serde(default)]
    pub territory_runtime_variables: BTreeMap<u32, BTreeMap<u32, i64>>,
    #[serde(default)]
    pub world_scalar_overrides: BTreeMap<String, i64>,
    #[serde(default)]
    pub special_conditions: BTreeMap<String, u32>,
    #[serde(default)]
    pub service_state: RuntimeServiceState,
}
