use super::*;

#[test]
fn periodic_boundary_applies_dividend_adjustment_from_annual_finance_policy() {
    let mut year_stat_family_qword_bits = vec![
        0u64;
        ((RUNTIME_COMPANY_STAT_SLOT_COUNT + 2) * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
            as usize
    ];
    let write_current_value = |bits: &mut Vec<u64>, slot_id: u32, value: f64| {
        let index = (slot_id * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize;
        bits[index] = value.to_bits();
    };
    let write_prior_year_value =
        |bits: &mut Vec<u64>, slot_id: u32, year_delta: u32, value: f64| {
            let index = (slot_id * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN + year_delta) as usize;
            bits[index] = value.to_bits();
        };
    write_current_value(&mut year_stat_family_qword_bits, 0x0d, 300_000.0);
    write_current_value(&mut year_stat_family_qword_bits, 0x01, 300_000.0);
    write_current_value(&mut year_stat_family_qword_bits, 0x09, -180_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 1, 280_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 1, -190_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 2, 260_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 2, -200_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x1c, 1, 5.0);

    let mut state = RuntimeState {
        calendar: crate::CalendarPoint {
            year: 1845,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: crate::state::RuntimeSaveProfileState::default(),
        world_restore: crate::state::RuntimeWorldRestoreState {
            packed_year_word_raw_u16: Some(1845),
            partial_year_progress_raw_u8: Some(0x0c),
            dividend_policy_raw_u8: Some(0),
            dividend_adjustment_allowed: Some(true),
            stock_issue_and_buyback_policy_raw_u8: Some(0),
            stock_issue_and_buyback_allowed: Some(true),
            bond_issue_and_repayment_policy_raw_u8: Some(0),
            bond_issue_and_repayment_allowed: Some(true),
            bankruptcy_policy_raw_u8: Some(0),
            bankruptcy_allowed: Some(true),
            building_density_growth_setting_raw_u32: Some(1),
            ..crate::state::RuntimeWorldRestoreState::default()
        },
        metadata: BTreeMap::new(),
        companies: vec![crate::state::RuntimeCompany {
            company_id: 21,
            controller_kind: crate::state::RuntimeCompanyControllerKind::Unknown,
            current_cash: 0,
            debt: 0,
            credit_rating_score: None,
            prime_rate: None,
            track_piece_counts: crate::state::RuntimeTrackPieceCounts::default(),
            active: true,
            available_track_laying_capacity: None,
            linked_chairman_profile_id: Some(7),
            book_value_per_share: 0,
            investor_confidence: 0,
            management_attitude: 0,
            takeover_cooldown_year: None,
            merger_cooldown_year: None,
        }],
        selected_company_id: Some(21),
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: vec![crate::state::RuntimeChairmanProfile {
            profile_id: 7,
            name: "Chairman Seven".to_string(),
            active: true,
            current_cash: 0,
            linked_company_id: Some(21),
            company_holdings: BTreeMap::from([(21, 9_500)]),
            holdings_value_total: 0,
            net_worth_total: 0,
            purchasing_power_total: 0,
        }],
        selected_chairman_profile_id: None,
        trains: Vec::new(),
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: crate::state::RuntimeServiceState {
            company_market_state: BTreeMap::from([(
                21,
                crate::state::RuntimeCompanyMarketState {
                    outstanding_shares: 10_000,
                    founding_year: 1840,
                    last_dividend_year: 1844,
                    year_stat_family_qword_bits,
                    direct_control_transfer_float_fields_raw_u32: BTreeMap::from([(
                        0x33f,
                        0.4f32.to_bits(),
                    )]),
                    ..crate::state::RuntimeCompanyMarketState::default()
                },
            )]),
            ..crate::state::RuntimeServiceState::default()
        },
    };

    let result = execute_step_command(&mut state, &StepCommand::ServicePeriodicBoundary)
        .expect("periodic boundary should apply annual finance policy");

    assert_eq!(state.service_state.annual_finance_service_calls, 1);
    assert_eq!(
        state.service_state.annual_dividend_adjustment_commit_count,
        1
    );
    assert_eq!(
        state.service_state.annual_finance_last_actions.get(&21),
        Some(&crate::state::RuntimeCompanyAnnualFinancePolicyAction::DividendAdjustment)
    );
    assert_eq!(
        state.service_state.company_market_state[&21]
            .direct_control_transfer_float_fields_raw_u32
            .get(&0x33f),
        Some(&1.8f32.to_bits())
    );
    assert!(
        result
            .service_events
            .iter()
            .any(|event| event.kind == "annual_finance_policy"
                && event.applied_effect_count == 1
                && event.mutated_company_ids == vec![21]
                && event.finance_news_family_candidates.is_empty())
    );
}

#[test]
fn periodic_boundary_applies_stock_issue_from_annual_finance_policy() {
    let mut year_stat_family_qword_bits = vec![
        0u64;
        (RUNTIME_COMPANY_STAT_SLOT_COUNT * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
            as usize
    ];
    year_stat_family_qword_bits[(RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH
        * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize] = 250_000.0f64.to_bits();

    let current_issue_calendar_word = 0x0101_0725;
    let current_issue_calendar_word_2 = 0x0001_0001;
    let prior_issue_calendar_word = 0x0101_0701;
    let prior_issue_calendar_word_2 = 0x0001_0001;

    let mut state = RuntimeState {
        calendar: crate::CalendarPoint {
            year: 1845,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: crate::state::RuntimeSaveProfileState::default(),
        world_restore: crate::state::RuntimeWorldRestoreState {
            packed_year_word_raw_u16: Some(1845),
            partial_year_progress_raw_u8: Some(0x0c),
            current_calendar_tuple_word_raw_u32: Some(0x0101_0726),
            current_calendar_tuple_word_2_raw_u32: Some(0x0001_0001),
            absolute_counter_raw_u32: Some(885_911_040),
            stock_issue_and_buyback_policy_raw_u8: Some(0),
            stock_issue_and_buyback_allowed: Some(true),
            bond_issue_and_repayment_policy_raw_u8: Some(0),
            bond_issue_and_repayment_allowed: Some(true),
            bankruptcy_policy_raw_u8: Some(0),
            bankruptcy_allowed: Some(true),
            issue_37_value: Some(5.0f32.to_bits()),
            issue_38_value: Some(2),
            ..crate::state::RuntimeWorldRestoreState::default()
        },
        metadata: BTreeMap::new(),
        companies: vec![crate::state::RuntimeCompany {
            company_id: 22,
            controller_kind: crate::state::RuntimeCompanyControllerKind::Unknown,
            current_cash: 0,
            debt: 0,
            credit_rating_score: None,
            prime_rate: None,
            track_piece_counts: crate::state::RuntimeTrackPieceCounts::default(),
            active: true,
            available_track_laying_capacity: None,
            linked_chairman_profile_id: None,
            book_value_per_share: 0,
            investor_confidence: 0,
            management_attitude: 0,
            takeover_cooldown_year: None,
            merger_cooldown_year: None,
        }],
        selected_company_id: Some(22),
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: Vec::new(),
        selected_chairman_profile_id: None,
        trains: Vec::new(),
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: crate::state::RuntimeServiceState {
            world_issue_opinion_base_terms_raw_i32: vec![0; 0x3b],
            company_market_state: BTreeMap::from([(
                22,
                crate::state::RuntimeCompanyMarketState {
                    outstanding_shares: 20_000,
                    bond_count: 2,
                    highest_coupon_live_bond_principal: Some(300_000),
                    founding_year: 1840,
                    cached_share_price_raw_u32: 35.0f32.to_bits(),
                    recent_per_share_cache_absolute_counter: 885_911_040,
                    recent_per_share_cached_value_bits: 34.0f64.to_bits(),
                    current_issue_calendar_word,
                    current_issue_calendar_word_2,
                    prior_issue_calendar_word,
                    prior_issue_calendar_word_2,
                    live_bond_slots: vec![
                        crate::state::RuntimeCompanyBondSlot {
                            slot_index: 0,
                            principal: 300_000,
                            maturity_year: 0,
                            coupon_rate_raw_u32: 0.11f32.to_bits(),
                        },
                        crate::state::RuntimeCompanyBondSlot {
                            slot_index: 1,
                            principal: 200_000,
                            maturity_year: 0,
                            coupon_rate_raw_u32: 0.07f32.to_bits(),
                        },
                    ],
                    direct_control_transfer_float_fields_raw_u32: BTreeMap::from([(
                        0x32f,
                        30.0f32.to_bits(),
                    )]),
                    year_stat_family_qword_bits,
                    ..crate::state::RuntimeCompanyMarketState::default()
                },
            )]),
            ..crate::state::RuntimeServiceState::default()
        },
    };

    let result = execute_step_command(&mut state, &StepCommand::ServicePeriodicBoundary)
        .expect("periodic boundary should apply annual stock issue policy");

    assert_eq!(
        state.service_state.annual_finance_last_actions.get(&22),
        Some(&crate::state::RuntimeCompanyAnnualFinancePolicyAction::StockIssue)
    );
    assert_eq!(
        state
            .service_state
            .annual_finance_last_news_family_candidates
            .get(&22),
        Some(&"4053".to_string())
    );
    assert_eq!(
        state.service_state.annual_stock_issue_last_share_count,
        4_000
    );
    assert_eq!(
        state.service_state.annual_stock_repurchase_last_share_count,
        0
    );
    assert_eq!(state.companies[0].current_cash, 390_000);
    assert_eq!(
        state.service_state.company_market_state[&22].outstanding_shares,
        24_000
    );
    assert_eq!(
        state.service_state.company_market_state[&22].prior_issue_calendar_word,
        current_issue_calendar_word
    );
    assert_eq!(
        state.service_state.company_market_state[&22].prior_issue_calendar_word_2,
        current_issue_calendar_word_2
    );
    assert_eq!(
        state.service_state.company_market_state[&22].current_issue_calendar_word,
        0x0101_0726
    );
    assert_eq!(
        state.service_state.company_market_state[&22].current_issue_calendar_word_2,
        0x0001_0001
    );
    assert!(result.service_events.iter().any(|event| {
        event.kind == "annual_finance_policy"
            && event.applied_effect_count == 1
            && event.mutated_company_ids == vec![22]
            && event.finance_news_family_candidates.get(&22) == Some(&"4053".to_string())
            && event.annual_finance_news_events.iter().any(|news| {
                news.company_id == 22
                    && news.selector_label == "4053"
                    && news.action_label == "stock_issue"
                    && news.issued_share_count == 4_000
            })
    }));
}

#[test]
fn periodic_boundary_applies_stock_repurchase_from_annual_finance_policy() {
    let mut year_stat_family_qword_bits = vec![
        0u64;
        (RUNTIME_COMPANY_STAT_SLOT_COUNT * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
            as usize
    ];
    year_stat_family_qword_bits[(RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH
        * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize] = 1_600_000.0f64.to_bits();

    let base_state = RuntimeState {
        calendar: crate::CalendarPoint {
            year: 1845,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: crate::state::RuntimeSaveProfileState::default(),
        world_restore: crate::state::RuntimeWorldRestoreState {
            packed_year_word_raw_u16: Some(1845),
            partial_year_progress_raw_u8: Some(0x0c),
            absolute_counter_raw_u32: Some(1_000),
            stock_issue_and_buyback_policy_raw_u8: Some(0),
            stock_issue_and_buyback_allowed: Some(true),
            bond_issue_and_repayment_policy_raw_u8: Some(0),
            bond_issue_and_repayment_allowed: Some(true),
            bankruptcy_policy_raw_u8: Some(0),
            bankruptcy_allowed: Some(true),
            building_density_growth_setting_raw_u32: Some(0),
            ..crate::state::RuntimeWorldRestoreState::default()
        },
        metadata: BTreeMap::new(),
        companies: vec![crate::state::RuntimeCompany {
            company_id: 23,
            controller_kind: crate::state::RuntimeCompanyControllerKind::Unknown,
            current_cash: 0,
            debt: 0,
            credit_rating_score: None,
            prime_rate: None,
            track_piece_counts: crate::state::RuntimeTrackPieceCounts::default(),
            active: true,
            available_track_laying_capacity: None,
            linked_chairman_profile_id: Some(8),
            book_value_per_share: 0,
            investor_confidence: 0,
            management_attitude: 0,
            takeover_cooldown_year: None,
            merger_cooldown_year: None,
        }],
        selected_company_id: Some(23),
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: vec![crate::state::RuntimeChairmanProfile {
            profile_id: 8,
            name: "Chairman".to_string(),
            active: true,
            current_cash: 0,
            linked_company_id: Some(23),
            company_holdings: BTreeMap::from([(23, 9_000)]),
            holdings_value_total: 0,
            net_worth_total: 0,
            purchasing_power_total: 0,
        }],
        selected_chairman_profile_id: Some(8),
        trains: Vec::new(),
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: crate::state::RuntimeServiceState {
            world_issue_opinion_base_terms_raw_i32: vec![0; 0x3b],
            company_market_state: BTreeMap::from([(
                23,
                crate::state::RuntimeCompanyMarketState {
                    outstanding_shares: 10_000,
                    founding_year: 1840,
                    city_connection_latch: true,
                    recent_per_share_cache_absolute_counter: 1_000,
                    recent_per_share_cached_value_bits: 50.0f64.to_bits(),
                    mutable_support_scalar_raw_u32: 0.0f32.to_bits(),
                    young_company_support_scalar_raw_u32: 0.0f32.to_bits(),
                    year_stat_family_qword_bits,
                    ..crate::state::RuntimeCompanyMarketState::default()
                },
            )]),
            ..crate::state::RuntimeServiceState::default()
        },
    };

    let pressured_share_price =
        crate::derived::runtime_company_support_adjusted_share_price_scalar_with_pressure_f64(
            &base_state,
            23,
            700,
        )
        .expect("repurchase share price");
    let expected_repurchase_total =
        crate::derived::runtime_round_f64_to_i64(pressured_share_price * 1_000.0)
            .expect("repurchase total should round");

    let mut state = base_state;
    let result = execute_step_command(&mut state, &StepCommand::ServicePeriodicBoundary)
        .expect("periodic boundary should apply annual stock repurchase policy");

    assert_eq!(
        state.service_state.annual_finance_last_actions.get(&23),
        Some(&crate::state::RuntimeCompanyAnnualFinancePolicyAction::StockRepurchase)
    );
    assert_eq!(
        state
            .service_state
            .annual_finance_last_news_family_candidates
            .get(&23),
        Some(&"2887".to_string())
    );
    assert_eq!(state.service_state.annual_stock_issue_last_share_count, 0);
    assert_eq!(
        state.service_state.annual_stock_repurchase_last_share_count,
        1_000
    );
    assert_eq!(
        state.companies[0].current_cash,
        1_600_000 - expected_repurchase_total
    );
    assert_eq!(
        state.service_state.company_market_state[&23].outstanding_shares,
        9_000
    );
    assert!(result.service_events.iter().any(|event| {
        event.kind == "annual_finance_policy"
            && event.applied_effect_count == 1
            && event.mutated_company_ids == vec![23]
            && event.finance_news_family_candidates.get(&23) == Some(&"2887".to_string())
            && event.annual_finance_news_events.iter().any(|news| {
                news.company_id == 23
                    && news.selector_label == "2887"
                    && news.action_label == "stock_repurchase"
                    && news.repurchased_share_count == 1_000
            })
    }));
}

#[test]
fn periodic_boundary_applies_bond_issue_from_annual_finance_policy() {
    let mut year_stat_family_qword_bits = vec![
        0u64;
        (RUNTIME_COMPANY_STAT_SLOT_COUNT * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
            as usize
    ];
    year_stat_family_qword_bits[(RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH
        * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize] = (-400_000.0f64).to_bits();

    let mut state = RuntimeState {
        calendar: crate::CalendarPoint {
            year: 1845,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: crate::state::RuntimeSaveProfileState::default(),
        world_restore: crate::state::RuntimeWorldRestoreState {
            packed_year_word_raw_u16: Some(1845),
            partial_year_progress_raw_u8: Some(0x0c),
            bond_issue_and_repayment_policy_raw_u8: Some(0),
            bond_issue_and_repayment_allowed: Some(true),
            stock_issue_and_buyback_policy_raw_u8: Some(0),
            stock_issue_and_buyback_allowed: Some(true),
            bankruptcy_policy_raw_u8: Some(0),
            bankruptcy_allowed: Some(true),
            ..crate::state::RuntimeWorldRestoreState::default()
        },
        metadata: BTreeMap::new(),
        companies: vec![crate::state::RuntimeCompany {
            company_id: 24,
            controller_kind: crate::state::RuntimeCompanyControllerKind::Unknown,
            current_cash: 0,
            debt: 0,
            credit_rating_score: Some(6),
            prime_rate: Some(5),
            track_piece_counts: crate::state::RuntimeTrackPieceCounts::default(),
            active: true,
            available_track_laying_capacity: None,
            linked_chairman_profile_id: None,
            book_value_per_share: 0,
            investor_confidence: 0,
            management_attitude: 0,
            takeover_cooldown_year: None,
            merger_cooldown_year: None,
        }],
        selected_company_id: Some(24),
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: Vec::new(),
        selected_chairman_profile_id: None,
        trains: Vec::new(),
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: crate::state::RuntimeServiceState {
            company_market_state: BTreeMap::from([(
                24,
                crate::state::RuntimeCompanyMarketState {
                    outstanding_shares: 10_000,
                    founding_year: 1840,
                    year_stat_family_qword_bits,
                    ..crate::state::RuntimeCompanyMarketState::default()
                },
            )]),
            ..crate::state::RuntimeServiceState::default()
        },
    };

    let result = execute_step_command(&mut state, &StepCommand::ServicePeriodicBoundary)
        .expect("periodic boundary should apply annual bond issue policy");

    assert_eq!(
        state.service_state.annual_finance_last_actions.get(&24),
        Some(&crate::state::RuntimeCompanyAnnualFinancePolicyAction::BondIssue)
    );
    assert_eq!(
        state
            .service_state
            .annual_finance_last_news_family_candidates
            .get(&24),
        Some(&"2886".to_string())
    );
    assert_eq!(state.companies[0].current_cash, 100_000);
    assert_eq!(state.service_state.company_market_state[&24].bond_count, 1);
    assert_eq!(
        state.service_state.annual_bond_last_retired_principal_total,
        0
    );
    assert_eq!(
        state.service_state.annual_bond_last_issued_principal_total,
        500_000
    );
    assert_eq!(
        state.service_state.company_market_state[&24].largest_live_bond_principal,
        Some(500_000)
    );
    assert_eq!(
        state.service_state.company_market_state[&24].highest_coupon_live_bond_principal,
        Some(500_000)
    );
    assert_eq!(
        state.service_state.company_market_state[&24].live_bond_slots,
        vec![crate::state::RuntimeCompanyBondSlot {
            slot_index: 0,
            principal: 500_000,
            maturity_year: 1875,
            coupon_rate_raw_u32: 0.09f32.to_bits(),
        }]
    );
    assert!(result.service_events.iter().any(|event| {
        event.kind == "annual_finance_policy"
            && event.applied_effect_count == 1
            && event.mutated_company_ids == vec![24]
            && event.finance_news_family_candidates.get(&24) == Some(&"2886".to_string())
            && event.annual_finance_news_events.iter().any(|news| {
                news.company_id == 24
                    && news.selector_label == "2886"
                    && news.action_label == "bond_issue"
                    && news.retired_principal_total == 0
                    && news.issued_principal_total == 500_000
            })
    }));
}

#[test]
fn periodic_boundary_retires_live_bonds_when_annual_bond_lane_needs_no_reissue() {
    let mut year_stat_family_qword_bits = vec![
        0u64;
        ((RUNTIME_COMPANY_STAT_SLOT_COUNT + 2) * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
            as usize
    ];
    let write_current_value = |bits: &mut Vec<u64>, slot_id: u32, value: f64| {
        let index = (slot_id * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize;
        bits[index] = value.to_bits();
    };
    write_current_value(
        &mut year_stat_family_qword_bits,
        RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH,
        900_000.0,
    );
    write_current_value(&mut year_stat_family_qword_bits, 0x12, -350_000.0);

    let mut state = crate::RuntimeState {
        calendar: crate::CalendarPoint {
            year: 1845,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_restore: crate::state::RuntimeWorldRestoreState {
            packed_year_word_raw_u16: Some(1845),
            partial_year_progress_raw_u8: Some(0x0c),
            bond_issue_and_repayment_policy_raw_u8: Some(0),
            bond_issue_and_repayment_allowed: Some(true),
            stock_issue_and_buyback_policy_raw_u8: Some(0),
            stock_issue_and_buyback_allowed: Some(true),
            bankruptcy_policy_raw_u8: Some(0),
            bankruptcy_allowed: Some(true),
            ..crate::state::RuntimeWorldRestoreState::default()
        },
        world_flags: BTreeMap::new(),
        save_profile: crate::state::RuntimeSaveProfileState::default(),
        metadata: BTreeMap::new(),
        companies: vec![crate::state::RuntimeCompany {
            company_id: 25,
            current_cash: 900_000,
            debt: 350_000,
            active: true,
            credit_rating_score: Some(7),
            prime_rate: Some(6),
            controller_kind: crate::state::RuntimeCompanyControllerKind::Unknown,
            linked_chairman_profile_id: None,
            available_track_laying_capacity: None,
            book_value_per_share: 0,
            investor_confidence: 0,
            management_attitude: 0,
            takeover_cooldown_year: None,
            merger_cooldown_year: None,
            track_piece_counts: crate::state::RuntimeTrackPieceCounts::default(),
        }],
        selected_company_id: Some(25),
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: Vec::new(),
        selected_chairman_profile_id: None,
        trains: Vec::new(),
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: crate::state::RuntimeServiceState {
            company_market_state: BTreeMap::from([(
                25,
                crate::state::RuntimeCompanyMarketState {
                    bond_count: 2,
                    live_bond_slots: vec![
                        crate::state::RuntimeCompanyBondSlot {
                            slot_index: 0,
                            principal: 200_000,
                            maturity_year: 1845,
                            coupon_rate_raw_u32: 0.09f32.to_bits(),
                        },
                        crate::state::RuntimeCompanyBondSlot {
                            slot_index: 1,
                            principal: 150_000,
                            maturity_year: 1845,
                            coupon_rate_raw_u32: 0.08f32.to_bits(),
                        },
                    ],
                    year_stat_family_qword_bits,
                    ..crate::state::RuntimeCompanyMarketState::default()
                },
            )]),
            ..crate::state::RuntimeServiceState::default()
        },
    };

    let result = execute_step_command(&mut state, &StepCommand::ServicePeriodicBoundary)
        .expect("periodic boundary should apply annual bond repayment lane");

    assert_eq!(
        state.service_state.annual_finance_last_actions.get(&25),
        Some(&crate::state::RuntimeCompanyAnnualFinancePolicyAction::BondIssue)
    );
    assert_eq!(
        state
            .service_state
            .annual_finance_last_news_family_candidates
            .get(&25),
        Some(&"2885".to_string())
    );
    assert_eq!(state.companies[0].current_cash, 550_000);
    assert_eq!(state.companies[0].debt, 0);
    assert_eq!(
        state.service_state.annual_bond_last_retired_principal_total,
        350_000
    );
    assert_eq!(
        state.service_state.annual_bond_last_issued_principal_total,
        0
    );
    assert_eq!(state.service_state.company_market_state[&25].bond_count, 0);
    assert!(
        state.service_state.company_market_state[&25]
            .live_bond_slots
            .is_empty()
    );
    assert_eq!(
        state.service_state.company_market_state[&25].largest_live_bond_principal,
        None
    );
    assert_eq!(
        state.service_state.company_market_state[&25].highest_coupon_live_bond_principal,
        None
    );
    assert!(result.service_events.iter().any(|event| {
        event.kind == "annual_finance_policy"
            && event.applied_effect_count == 1
            && event.mutated_company_ids == vec![25]
            && event.finance_news_family_candidates.get(&25) == Some(&"2885".to_string())
            && event.annual_finance_news_events.iter().any(|news| {
                news.company_id == 25
                    && news.selector_label == "2885"
                    && news.action_label == "bond_issue"
                    && news.retired_principal_total == 350_000
                    && news.issued_principal_total == 0
            })
    }));
}

#[test]
fn periodic_boundary_retires_then_reissues_exact_annual_bond_count() {
    let mut year_stat_family_qword_bits = vec![
        0u64;
        ((RUNTIME_COMPANY_STAT_SLOT_COUNT + 2) * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
            as usize
    ];
    let write_current_value = |bits: &mut Vec<u64>, slot_id: u32, value: f64| {
        let index = (slot_id * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize;
        bits[index] = value.to_bits();
    };
    write_current_value(
        &mut year_stat_family_qword_bits,
        RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH,
        -400_000.0,
    );
    write_current_value(&mut year_stat_family_qword_bits, 0x12, -350_000.0);

    let mut state = crate::RuntimeState {
        calendar: crate::CalendarPoint {
            year: 1845,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_restore: crate::state::RuntimeWorldRestoreState {
            packed_year_word_raw_u16: Some(1845),
            partial_year_progress_raw_u8: Some(0x0c),
            bond_issue_and_repayment_policy_raw_u8: Some(0),
            bond_issue_and_repayment_allowed: Some(true),
            stock_issue_and_buyback_policy_raw_u8: Some(0),
            stock_issue_and_buyback_allowed: Some(true),
            bankruptcy_policy_raw_u8: Some(0),
            bankruptcy_allowed: Some(true),
            ..crate::state::RuntimeWorldRestoreState::default()
        },
        world_flags: BTreeMap::new(),
        save_profile: crate::state::RuntimeSaveProfileState::default(),
        metadata: BTreeMap::new(),
        companies: vec![crate::state::RuntimeCompany {
            company_id: 26,
            current_cash: -400_000,
            debt: 350_000,
            active: true,
            credit_rating_score: Some(7),
            prime_rate: Some(6),
            controller_kind: crate::state::RuntimeCompanyControllerKind::Unknown,
            linked_chairman_profile_id: None,
            available_track_laying_capacity: None,
            book_value_per_share: 0,
            investor_confidence: 0,
            management_attitude: 0,
            takeover_cooldown_year: None,
            merger_cooldown_year: None,
            track_piece_counts: crate::state::RuntimeTrackPieceCounts::default(),
        }],
        selected_company_id: Some(26),
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: Vec::new(),
        selected_chairman_profile_id: None,
        trains: Vec::new(),
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: crate::state::RuntimeServiceState {
            company_market_state: BTreeMap::from([(
                26,
                crate::state::RuntimeCompanyMarketState {
                    bond_count: 2,
                    linked_transit_latch: true,
                    live_bond_slots: vec![
                        crate::state::RuntimeCompanyBondSlot {
                            slot_index: 0,
                            principal: 200_000,
                            maturity_year: 1845,
                            coupon_rate_raw_u32: 0.09f32.to_bits(),
                        },
                        crate::state::RuntimeCompanyBondSlot {
                            slot_index: 1,
                            principal: 150_000,
                            maturity_year: 1845,
                            coupon_rate_raw_u32: 0.08f32.to_bits(),
                        },
                    ],
                    year_stat_family_qword_bits,
                    ..crate::state::RuntimeCompanyMarketState::default()
                },
            )]),
            ..crate::state::RuntimeServiceState::default()
        },
    };

    let result = execute_step_command(&mut state, &StepCommand::ServicePeriodicBoundary)
        .expect("periodic boundary should apply annual bond restructure lane");

    assert_eq!(
        state.service_state.annual_finance_last_actions.get(&26),
        Some(&crate::state::RuntimeCompanyAnnualFinancePolicyAction::BondIssue)
    );
    assert_eq!(
        state
            .service_state
            .annual_finance_last_news_family_candidates
            .get(&26),
        Some(&"2883".to_string())
    );
    assert_eq!(state.companies[0].current_cash, 250_000);
    assert_eq!(state.companies[0].debt, 1_000_000);
    assert_eq!(
        state.service_state.annual_bond_last_retired_principal_total,
        350_000
    );
    assert_eq!(
        state.service_state.annual_bond_last_issued_principal_total,
        1_000_000
    );
    assert_eq!(state.service_state.company_market_state[&26].bond_count, 2);
    assert_eq!(
        state.service_state.company_market_state[&26].largest_live_bond_principal,
        Some(500_000)
    );
    assert_eq!(
        state.service_state.company_market_state[&26].highest_coupon_live_bond_principal,
        Some(500_000)
    );
    assert_eq!(
        state.service_state.company_market_state[&26].live_bond_slots,
        vec![
            crate::state::RuntimeCompanyBondSlot {
                slot_index: 0,
                principal: 500_000,
                maturity_year: 1875,
                coupon_rate_raw_u32: 0.09f32.to_bits(),
            },
            crate::state::RuntimeCompanyBondSlot {
                slot_index: 1,
                principal: 500_000,
                maturity_year: 1875,
                coupon_rate_raw_u32: 0.09f32.to_bits(),
            },
        ]
    );
    assert!(result.service_events.iter().any(|event| {
        event.kind == "annual_finance_policy"
            && event.applied_effect_count == 1
            && event.mutated_company_ids == vec![26]
            && event.finance_news_family_candidates.get(&26) == Some(&"2883".to_string())
            && event.annual_finance_news_events.iter().any(|news| {
                news.company_id == 26
                    && news.selector_label == "2883"
                    && news.action_label == "bond_issue"
                    && news.retired_principal_total == 350_000
                    && news.issued_principal_total == 1_000_000
            })
    }));
}

#[test]
fn periodic_boundary_applies_creditor_pressure_bankruptcy_from_annual_finance_policy() {
    let mut year_stat_family_qword_bits = vec![
        0u64;
        ((RUNTIME_COMPANY_STAT_SLOT_COUNT + 2) * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
            as usize
    ];
    let write_current_value = |bits: &mut Vec<u64>, slot_id: u32, value: f64| {
        let index = (slot_id * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize;
        bits[index] = value.to_bits();
    };
    let write_prior_year_value =
        |bits: &mut Vec<u64>, slot_id: u32, year_delta: u32, value: f64| {
            let index = (slot_id * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN + year_delta) as usize;
            bits[index] = value.to_bits();
        };
    write_current_value(
        &mut year_stat_family_qword_bits,
        RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH,
        -200_000.0,
    );
    write_current_value(&mut year_stat_family_qword_bits, 0x12, -500_000.0);
    write_current_value(&mut year_stat_family_qword_bits, 0x09, -50_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 1, 100_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 2, 90_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 3, 95_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 1, -125_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 2, -110_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 3, -115_000.0);

    let mut state = RuntimeState {
        calendar: crate::CalendarPoint {
            year: 1845,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: crate::state::RuntimeSaveProfileState::default(),
        world_restore: crate::state::RuntimeWorldRestoreState {
            packed_year_word_raw_u16: Some(1845),
            partial_year_progress_raw_u8: Some(0x0c),
            bankruptcy_policy_raw_u8: Some(0),
            bankruptcy_allowed: Some(true),
            ..crate::state::RuntimeWorldRestoreState::default()
        },
        metadata: BTreeMap::new(),
        companies: vec![crate::state::RuntimeCompany {
            company_id: 31,
            controller_kind: crate::state::RuntimeCompanyControllerKind::Unknown,
            current_cash: 0,
            debt: 200_000,
            credit_rating_score: None,
            prime_rate: None,
            track_piece_counts: crate::state::RuntimeTrackPieceCounts::default(),
            active: true,
            available_track_laying_capacity: None,
            linked_chairman_profile_id: None,
            book_value_per_share: 0,
            investor_confidence: 0,
            management_attitude: 0,
            takeover_cooldown_year: None,
            merger_cooldown_year: None,
        }],
        selected_company_id: Some(31),
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: Vec::new(),
        selected_chairman_profile_id: None,
        trains: vec![crate::state::RuntimeTrain {
            train_id: 88,
            owner_company_id: 31,
            territory_id: None,
            locomotive_name: Some("Mikado".to_string()),
            active: true,
            retired: false,
        }],
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: crate::state::RuntimeServiceState {
            company_market_state: BTreeMap::from([(
                31,
                crate::state::RuntimeCompanyMarketState {
                    outstanding_shares: 10_000,
                    bond_count: 1,
                    largest_live_bond_principal: Some(500_000),
                    highest_coupon_live_bond_principal: Some(500_000),
                    cached_share_price_raw_u32: 25.0f32.to_bits(),
                    founding_year: 1841,
                    last_bankruptcy_year: 1832,
                    year_stat_family_qword_bits,
                    live_bond_slots: vec![crate::state::RuntimeCompanyBondSlot {
                        slot_index: 0,
                        principal: 500_000,
                        maturity_year: 0,
                        coupon_rate_raw_u32: 0.08f32.to_bits(),
                    }],
                    ..crate::state::RuntimeCompanyMarketState::default()
                },
            )]),
            ..crate::state::RuntimeServiceState::default()
        },
    };

    let result = execute_step_command(&mut state, &StepCommand::ServicePeriodicBoundary)
        .expect("periodic boundary should apply creditor-pressure bankruptcy");

    assert_eq!(
        state.service_state.annual_finance_last_actions.get(&31),
        Some(&crate::state::RuntimeCompanyAnnualFinancePolicyAction::CreditorPressureBankruptcy)
    );
    assert_eq!(
        state
            .service_state
            .annual_finance_last_news_family_candidates
            .get(&31),
        Some(&"2881".to_string())
    );
    assert_eq!(state.companies[0].current_cash, 0);
    assert_eq!(state.companies[0].debt, 250_000);
    assert!(state.companies[0].active);
    assert_eq!(state.selected_company_id, Some(31));
    assert!(!state.trains[0].retired);
    assert_eq!(
        state.service_state.company_market_state[&31].last_bankruptcy_year,
        1845
    );
    assert_eq!(state.service_state.company_market_state[&31].bond_count, 1);
    assert_eq!(
        state.service_state.company_market_state[&31].largest_live_bond_principal,
        Some(250_000)
    );
    assert_eq!(
        state.service_state.company_market_state[&31].highest_coupon_live_bond_principal,
        Some(250_000)
    );
    assert!(
        state.service_state.company_market_state[&31].live_bond_slots
            == vec![crate::state::RuntimeCompanyBondSlot {
                slot_index: 0,
                principal: 250_000,
                maturity_year: 0,
                coupon_rate_raw_u32: 0.08f32.to_bits(),
            }]
    );
    assert!(
        result
            .service_events
            .iter()
            .any(|event| event.kind == "annual_finance_policy"
                && event.applied_effect_count == 1
                && event.mutated_company_ids == vec![31]
                && event.finance_news_family_candidates.get(&31) == Some(&"2881".to_string()))
    );
}

#[test]
fn periodic_boundary_applies_deep_distress_bankruptcy_fallback_from_annual_finance_policy() {
    let mut year_stat_family_qword_bits = vec![
        0u64;
        ((RUNTIME_COMPANY_STAT_SLOT_COUNT + 2) * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
            as usize
    ];
    let write_current_value = |bits: &mut Vec<u64>, slot_id: u32, value: f64| {
        let index = (slot_id * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize;
        bits[index] = value.to_bits();
    };
    let write_prior_year_value =
        |bits: &mut Vec<u64>, slot_id: u32, year_delta: u32, value: f64| {
            let index = (slot_id * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN + year_delta) as usize;
            bits[index] = value.to_bits();
        };
    write_current_value(
        &mut year_stat_family_qword_bits,
        RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH,
        -350_000.0,
    );
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 1, 10_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 2, 15_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 3, 12_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 1, -35_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 2, -38_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 3, -33_000.0);

    let mut state = RuntimeState {
        calendar: crate::CalendarPoint {
            year: 1845,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: crate::state::RuntimeSaveProfileState::default(),
        world_restore: crate::state::RuntimeWorldRestoreState {
            packed_year_word_raw_u16: Some(1845),
            partial_year_progress_raw_u8: Some(0x0c),
            bankruptcy_policy_raw_u8: Some(0),
            bankruptcy_allowed: Some(true),
            ..crate::state::RuntimeWorldRestoreState::default()
        },
        metadata: BTreeMap::new(),
        companies: vec![crate::state::RuntimeCompany {
            company_id: 32,
            controller_kind: crate::state::RuntimeCompanyControllerKind::Unknown,
            current_cash: 0,
            debt: 50_000,
            credit_rating_score: None,
            prime_rate: None,
            track_piece_counts: crate::state::RuntimeTrackPieceCounts::default(),
            active: true,
            available_track_laying_capacity: None,
            linked_chairman_profile_id: None,
            book_value_per_share: 0,
            investor_confidence: 0,
            management_attitude: 0,
            takeover_cooldown_year: None,
            merger_cooldown_year: None,
        }],
        selected_company_id: Some(32),
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: Vec::new(),
        selected_chairman_profile_id: None,
        trains: vec![crate::state::RuntimeTrain {
            train_id: 89,
            owner_company_id: 32,
            territory_id: None,
            locomotive_name: Some("Orca".to_string()),
            active: true,
            retired: false,
        }],
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: crate::state::RuntimeServiceState {
            company_market_state: BTreeMap::from([(
                32,
                crate::state::RuntimeCompanyMarketState {
                    outstanding_shares: 8_000,
                    bond_count: 1,
                    largest_live_bond_principal: Some(250_000),
                    highest_coupon_live_bond_principal: Some(250_000),
                    founding_year: 1841,
                    last_bankruptcy_year: 1840,
                    year_stat_family_qword_bits,
                    live_bond_slots: vec![crate::state::RuntimeCompanyBondSlot {
                        slot_index: 0,
                        principal: 250_000,
                        maturity_year: 0,
                        coupon_rate_raw_u32: 0.07f32.to_bits(),
                    }],
                    ..crate::state::RuntimeCompanyMarketState::default()
                },
            )]),
            ..crate::state::RuntimeServiceState::default()
        },
    };

    let result = execute_step_command(&mut state, &StepCommand::ServicePeriodicBoundary)
        .expect("periodic boundary should apply deep-distress bankruptcy fallback");

    assert_eq!(
        state.service_state.annual_finance_last_actions.get(&32),
        Some(
            &crate::state::RuntimeCompanyAnnualFinancePolicyAction::DeepDistressBankruptcyFallback
        )
    );
    assert_eq!(
        state
            .service_state
            .annual_finance_last_news_family_candidates
            .get(&32),
        Some(&"2881".to_string())
    );
    assert_eq!(state.companies[0].current_cash, 0);
    assert_eq!(state.companies[0].debt, 125_000);
    assert!(state.companies[0].active);
    assert_eq!(state.selected_company_id, Some(32));
    assert!(!state.trains[0].retired);
    assert_eq!(
        state.service_state.company_market_state[&32].last_bankruptcy_year,
        1845
    );
    assert_eq!(state.service_state.company_market_state[&32].bond_count, 1);
    assert_eq!(
        state.service_state.company_market_state[&32].largest_live_bond_principal,
        Some(125_000)
    );
    assert_eq!(
        state.service_state.company_market_state[&32].highest_coupon_live_bond_principal,
        Some(125_000)
    );
    assert!(
        state.service_state.company_market_state[&32].live_bond_slots
            == vec![crate::state::RuntimeCompanyBondSlot {
                slot_index: 0,
                principal: 125_000,
                maturity_year: 0,
                coupon_rate_raw_u32: 0.07f32.to_bits(),
            }]
    );
    assert!(
        result
            .service_events
            .iter()
            .any(|event| event.kind == "annual_finance_policy"
                && event.applied_effect_count == 1
                && event.mutated_company_ids == vec![32]
                && event.finance_news_family_candidates.get(&32) == Some(&"2881".to_string()))
    );
}
