use serde::{Deserialize, Serialize};

use crate::event::targets::RuntimeCargoClass;
use crate::inspect::smp::events::SmpLoadedEventRuntimeCollectionSummary;
use crate::inspect::smp::profiles::SmpRt3105SaveNameTableEntry;
use crate::inspect::smp::regions::{SmpLoadedRegionCollection, SmpLoadedRegionFixedRowRunSummary};
use crate::inspect::smp::special_conditions::SmpLoadedSpecialConditionsTable;
use crate::inspect::smp::structures::{
    SmpLoadedPlacedStructureCollection, SmpLoadedPlacedStructureDynamicSideBufferSummary,
};
use crate::inspect::smp::world::{
    SmpLoadedChairmanProfileTable, SmpLoadedCompanyRoster, SmpLoadedWorldEconomicTuningState,
    SmpLoadedWorldFinanceNeighborhoodState, SmpLoadedWorldIssue37State,
    SmpLoadedWorldLocomotivePolicyState,
};

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSaveLoadCandidateTableSummary {
    pub source_kind: String,
    pub semantic_family: String,
    pub observed_entry_count: usize,
    pub zero_availability_count: usize,
    pub zero_availability_names: Vec<String>,
    pub footer_progress_hex_words: Vec<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSaveLoadSummary {
    pub file_extension_hint: Option<String>,
    pub container_profile_family: Option<String>,
    pub mechanism_family: String,
    pub mechanism_confidence: String,
    pub packed_profile_kind: Option<String>,
    pub packed_profile_family: Option<String>,
    pub packed_profile_offset: Option<usize>,
    pub packed_profile_len: Option<usize>,
    pub map_path: Option<String>,
    pub display_name: Option<String>,
    pub profile_byte_0x77: Option<u8>,
    pub profile_byte_0x77_hex: Option<String>,
    pub profile_byte_0x82: Option<u8>,
    pub profile_byte_0x82_hex: Option<String>,
    pub profile_byte_0x97: Option<u8>,
    pub profile_byte_0x97_hex: Option<String>,
    pub profile_byte_0xc5: Option<u8>,
    pub profile_byte_0xc5_hex: Option<String>,
    pub trailer_family: Option<String>,
    pub bridge_family: Option<String>,
    pub candidate_table: Option<SmpSaveLoadCandidateTableSummary>,
    pub notes: Vec<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpLoadedProfile {
    pub profile_kind: String,
    pub profile_family: String,
    pub packed_profile_offset: usize,
    pub packed_profile_len: usize,
    pub packed_profile_len_hex: String,
    pub leading_word_0: u32,
    pub leading_word_0_hex: String,
    pub header_flag_word_3: Option<u32>,
    pub header_flag_word_3_hex: Option<String>,
    pub map_path: Option<String>,
    pub display_name: Option<String>,
    pub profile_byte_0x77: u8,
    pub profile_byte_0x77_hex: String,
    pub profile_byte_0x82: u8,
    pub profile_byte_0x82_hex: String,
    pub profile_byte_0x97: u8,
    pub profile_byte_0x97_hex: String,
    pub profile_byte_0xc5: u8,
    pub profile_byte_0xc5_hex: String,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpLoadedCandidateAvailabilityTable {
    pub source_kind: String,
    pub semantic_family: String,
    pub header_offset: usize,
    pub entries_offset: usize,
    pub entries_end_offset: usize,
    pub observed_entry_count: usize,
    pub zero_availability_count: usize,
    pub zero_availability_names: Vec<String>,
    pub footer_progress_hex_words: Vec<String>,
    pub entries: Vec<SmpRt3105SaveNameTableEntry>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpLoadedNamedLocomotiveAvailabilityTable {
    pub source_kind: String,
    pub semantic_family: String,
    #[serde(default)]
    pub header_offset: Option<usize>,
    #[serde(default)]
    pub entries_offset: Option<usize>,
    #[serde(default)]
    pub entries_end_offset: Option<usize>,
    pub observed_entry_count: usize,
    pub zero_availability_count: usize,
    pub zero_availability_names: Vec<String>,
    pub entries: Vec<SmpRt3105SaveNameTableEntry>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpLoadedLocomotiveCatalogEntry {
    pub locomotive_id: u32,
    pub name: String,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpLoadedLocomotiveCatalog {
    pub source_kind: String,
    pub semantic_family: String,
    #[serde(default)]
    pub entries_offset: Option<usize>,
    pub observed_entry_count: usize,
    pub entries: Vec<SmpLoadedLocomotiveCatalogEntry>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpLoadedCargoCatalogEntry {
    pub slot_id: u32,
    pub label: String,
    #[serde(default)]
    pub cargo_class: RuntimeCargoClass,
    pub book_index: usize,
    pub max_annual_production_word: u32,
    pub mode_word: u32,
    pub runtime_import_branch_kind: String,
    pub annual_amount_word: u32,
    pub supplied_cargo_token_word: u32,
    #[serde(default)]
    pub supplied_cargo_token_probable_high16_ascii_stem: Option<String>,
    pub demanded_cargo_token_word: u32,
    #[serde(default)]
    pub demanded_cargo_token_probable_high16_ascii_stem: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpLoadedCargoCatalog {
    pub source_kind: String,
    pub semantic_family: String,
    #[serde(default)]
    pub root_offset: Option<usize>,
    pub observed_entry_count: usize,
    pub entries: Vec<SmpLoadedCargoCatalogEntry>,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SmpLoadedSaveSlice {
    pub file_extension_hint: Option<String>,
    pub container_profile_family: Option<String>,
    pub mechanism_family: String,
    pub mechanism_confidence: String,
    pub trailer_family: Option<String>,
    pub bridge_family: Option<String>,
    pub profile: Option<SmpLoadedProfile>,
    pub candidate_availability_table: Option<SmpLoadedCandidateAvailabilityTable>,
    pub named_locomotive_availability_table: Option<SmpLoadedNamedLocomotiveAvailabilityTable>,
    #[serde(default)]
    pub locomotive_catalog: Option<SmpLoadedLocomotiveCatalog>,
    #[serde(default)]
    pub cargo_catalog: Option<SmpLoadedCargoCatalog>,
    #[serde(default)]
    pub world_issue_37_state: Option<SmpLoadedWorldIssue37State>,
    #[serde(default)]
    pub world_economic_tuning_state: Option<SmpLoadedWorldEconomicTuningState>,
    #[serde(default)]
    pub world_finance_neighborhood_state: Option<SmpLoadedWorldFinanceNeighborhoodState>,
    #[serde(default)]
    pub world_locomotive_policy_state: Option<SmpLoadedWorldLocomotivePolicyState>,
    #[serde(default)]
    pub company_roster: Option<SmpLoadedCompanyRoster>,
    #[serde(default)]
    pub chairman_profile_table: Option<SmpLoadedChairmanProfileTable>,
    #[serde(default)]
    pub region_collection: Option<SmpLoadedRegionCollection>,
    #[serde(default)]
    pub region_fixed_row_run_summary: Option<SmpLoadedRegionFixedRowRunSummary>,
    #[serde(default)]
    pub placed_structure_collection: Option<SmpLoadedPlacedStructureCollection>,
    #[serde(default)]
    pub placed_structure_dynamic_side_buffer_summary:
        Option<SmpLoadedPlacedStructureDynamicSideBufferSummary>,
    pub special_conditions_table: Option<SmpLoadedSpecialConditionsTable>,
    pub event_runtime_collection: Option<SmpLoadedEventRuntimeCollectionSummary>,
    pub notes: Vec<String>,
}
