use std::collections::BTreeMap;

use serde::{Deserialize, Serialize};

use crate::inspect::smp::common::{
    SmpSaveDwordCandidate, SmpSaveTaggedCollectionHeaderProbe,
    SmpSaveTrainCollectionDirectoryProbe, SmpSaveUnclassifiedTaggedCollectionHeaderProbe,
};
use crate::inspect::smp::regions::{
    SmpSaveRegionFixedRowRunCandidateProbe, SmpSaveRegionQueuedNoticeRecordProbe,
    SmpSaveRegionRecordTripletProbe,
};
use crate::inspect::smp::structures::{
    SmpSavePlacedStructureDynamicSideBufferAlignmentProbe,
    SmpSavePlacedStructureDynamicSideBufferProbe, SmpSavePlacedStructureRecordTripletProbe,
};
use crate::inspect::smp::world::{
    SmpSaveWorldEconomicTuningProbe, SmpSaveWorldFinanceNeighborhoodProbe,
    SmpSaveWorldIssue37Probe, SmpSaveWorldSelectionRoleAnalysis,
};

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SmpSaveScalarCandidate {
    pub relative_offset: usize,
    pub relative_offset_hex: String,
    pub raw_u64: u64,
    pub raw_u64_hex: String,
    pub value_i64: i64,
    pub value_f64: f64,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SmpSaveCompanyRecordAnalysisEntry {
    pub company_id: u32,
    pub name: String,
    pub active: bool,
    #[serde(default)]
    pub linked_chairman_profile_id: Option<u32>,
    pub outstanding_shares: u32,
    pub debt: u64,
    pub bond_count: u8,
    #[serde(default)]
    pub live_bond_slots: Vec<crate::state::RuntimeCompanyBondSlot>,
    #[serde(default)]
    pub largest_live_bond_principal: Option<u32>,
    #[serde(default)]
    pub highest_coupon_live_bond_principal: Option<u32>,
    #[serde(default)]
    pub available_track_laying_capacity: Option<u32>,
    pub company_value_scalar_f32: f32,
    pub cached_share_support_scalar_f32: f32,
    pub cached_share_price_f32: f32,
    pub chairman_salary_baseline: u32,
    pub chairman_salary_current: u32,
    pub chairman_bonus_year: u32,
    pub chairman_bonus_amount: i32,
    pub founding_year: u32,
    pub last_bankruptcy_year: u32,
    pub last_dividend_year: u32,
    pub preferred_locomotive_engine_type_raw_u8: u8,
    pub preferred_locomotive_engine_type_raw_hex: String,
    pub city_connection_latch: bool,
    pub linked_transit_latch: bool,
    pub linked_transit_autoroute_site_score_cache_refresh_absolute_counter: u32,
    pub linked_transit_site_peer_cache_refresh_absolute_counter: u32,
    #[serde(default)]
    pub linked_transit_route_anchor_entry_id: Option<u32>,
    #[serde(default)]
    pub linked_transit_route_anchor_fallback_counts: Vec<u32>,
    pub merger_cooldown_year: u32,
    pub takeover_cooldown_year: u32,
    #[serde(default)]
    pub scalar_dword_candidates: Vec<SmpSaveDwordCandidate>,
    #[serde(default)]
    pub post_capacity_dword_candidates: Vec<SmpSaveDwordCandidate>,
    #[serde(default)]
    pub stat_band_root_0cfb_candidates: Vec<SmpSaveDwordCandidate>,
    #[serde(default)]
    pub stat_band_root_0d7f_candidates: Vec<SmpSaveDwordCandidate>,
    #[serde(default)]
    pub stat_band_root_1c47_candidates: Vec<SmpSaveDwordCandidate>,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SmpSaveChairmanRecordAnalysisEntry {
    pub profile_id: u32,
    pub name: String,
    pub active: bool,
    pub current_cash: f64,
    #[serde(default)]
    pub linked_company_id: Option<u32>,
    #[serde(default)]
    pub holdings_by_company: BTreeMap<u32, u32>,
    #[serde(default)]
    pub derived_holdings_share_price_total: Option<i64>,
    #[serde(default)]
    pub derived_net_worth_share_price_total: Option<i64>,
    #[serde(default)]
    pub derived_cached_purchasing_power_total: Option<i64>,
    pub personality_byte_0x291: u8,
    pub personality_byte_0x291_hex: String,
    #[serde(default)]
    pub cached_scalar_candidates: Vec<SmpSaveScalarCandidate>,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SmpSaveCompanyChairmanAnalysisReport {
    pub profile_family: String,
    #[serde(default)]
    pub selected_company_id: Option<u32>,
    #[serde(default)]
    pub selected_chairman_profile_id: Option<u32>,
    #[serde(default)]
    pub world_selection_context: Option<SmpSaveWorldSelectionRoleAnalysis>,
    #[serde(default)]
    pub world_issue_37: Option<SmpSaveWorldIssue37Probe>,
    #[serde(default)]
    pub world_economic_tuning: Option<SmpSaveWorldEconomicTuningProbe>,
    #[serde(default)]
    pub world_finance_neighborhood: Option<SmpSaveWorldFinanceNeighborhoodProbe>,
    #[serde(default)]
    pub train_collection_header: Option<SmpSaveTaggedCollectionHeaderProbe>,
    #[serde(default)]
    pub train_collection_directory: Option<SmpSaveTrainCollectionDirectoryProbe>,
    #[serde(default)]
    pub region_collection_header: Option<SmpSaveTaggedCollectionHeaderProbe>,
    #[serde(default)]
    pub region_record_triplets: Option<SmpSaveRegionRecordTripletProbe>,
    #[serde(default)]
    pub region_queued_notice_records: Option<SmpSaveRegionQueuedNoticeRecordProbe>,
    #[serde(default)]
    pub region_fixed_row_run_candidates: Option<SmpSaveRegionFixedRowRunCandidateProbe>,
    #[serde(default)]
    pub placed_structure_collection_header: Option<SmpSaveTaggedCollectionHeaderProbe>,
    #[serde(default)]
    pub placed_structure_record_triplets: Option<SmpSavePlacedStructureRecordTripletProbe>,
    #[serde(default)]
    pub placed_structure_dynamic_side_buffer: Option<SmpSavePlacedStructureDynamicSideBufferProbe>,
    #[serde(default)]
    pub placed_structure_dynamic_side_buffer_alignment:
        Option<SmpSavePlacedStructureDynamicSideBufferAlignmentProbe>,
    #[serde(default)]
    pub unclassified_tagged_collection_headers: Vec<SmpSaveUnclassifiedTaggedCollectionHeaderProbe>,
    #[serde(default)]
    pub company_entries: Vec<SmpSaveCompanyRecordAnalysisEntry>,
    #[serde(default)]
    pub chairman_entries: Vec<SmpSaveChairmanRecordAnalysisEntry>,
    #[serde(default)]
    pub notes: Vec<String>,
}
