use super::*;

#[test]
fn resolves_symbolic_company_targets() {
    let mut state = RuntimeState {
        companies: vec![
            RuntimeCompany {
                company_id: 1,
                controller_kind: RuntimeCompanyControllerKind::Human,
                current_cash: 10,
                debt: 0,
                credit_rating_score: None,
                prime_rate: None,
                track_piece_counts: 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,
            },
            RuntimeCompany {
                company_id: 2,
                controller_kind: RuntimeCompanyControllerKind::Ai,
                current_cash: 20,
                debt: 2,
                credit_rating_score: None,
                prime_rate: None,
                track_piece_counts: 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(1),
        event_runtime_records: vec![
            RuntimeEventRecord {
                record_id: 11,
                trigger_kind: 7,
                active: true,
                service_count: 0,
                marks_collection_dirty: false,
                one_shot: false,
                has_fired: false,
                conditions: Vec::new(),
                effects: vec![RuntimeEffect::AdjustCompanyCash {
                    target: RuntimeCompanyTarget::HumanCompanies,
                    delta: 5,
                }],
            },
            RuntimeEventRecord {
                record_id: 12,
                trigger_kind: 7,
                active: true,
                service_count: 0,
                marks_collection_dirty: false,
                one_shot: false,
                has_fired: false,
                conditions: Vec::new(),
                effects: vec![RuntimeEffect::AdjustCompanyDebt {
                    target: RuntimeCompanyTarget::AiCompanies,
                    delta: 3,
                }],
            },
            RuntimeEventRecord {
                record_id: 13,
                trigger_kind: 7,
                active: true,
                service_count: 0,
                marks_collection_dirty: false,
                one_shot: false,
                has_fired: false,
                conditions: Vec::new(),
                effects: vec![RuntimeEffect::AdjustCompanyCash {
                    target: RuntimeCompanyTarget::SelectedCompany,
                    delta: 7,
                }],
            },
        ],
        ..state()
    };

    let result = execute_step_command(
        &mut state,
        &StepCommand::ServiceTriggerKind { trigger_kind: 7 },
    )
    .expect("symbolic target effects should succeed");

    assert_eq!(state.companies[0].current_cash, 22);
    assert_eq!(state.companies[0].debt, 0);
    assert_eq!(state.companies[1].current_cash, 20);
    assert_eq!(state.companies[1].debt, 5);
    assert_eq!(result.service_events[0].mutated_company_ids, vec![1, 2]);
}

#[test]
fn rejects_selected_company_target_without_selection_context() {
    let mut state = RuntimeState {
        event_runtime_records: vec![RuntimeEventRecord {
            record_id: 14,
            trigger_kind: 7,
            active: true,
            service_count: 0,
            marks_collection_dirty: false,
            one_shot: false,
            has_fired: false,
            conditions: Vec::new(),
            effects: vec![RuntimeEffect::AdjustCompanyCash {
                target: RuntimeCompanyTarget::SelectedCompany,
                delta: 1,
            }],
        }],
        ..state()
    };

    let error = execute_step_command(
        &mut state,
        &StepCommand::ServiceTriggerKind { trigger_kind: 7 },
    )
    .expect_err("selected company target should require selection context");

    assert!(error.contains("selected_company_id"));
}

#[test]
fn rejects_human_or_ai_targets_without_role_context() {
    let mut state = RuntimeState {
        event_runtime_records: vec![RuntimeEventRecord {
            record_id: 15,
            trigger_kind: 7,
            active: true,
            service_count: 0,
            marks_collection_dirty: false,
            one_shot: false,
            has_fired: false,
            conditions: Vec::new(),
            effects: vec![RuntimeEffect::AdjustCompanyCash {
                target: RuntimeCompanyTarget::HumanCompanies,
                delta: 1,
            }],
        }],
        ..state()
    };

    let error = execute_step_command(
        &mut state,
        &StepCommand::ServiceTriggerKind { trigger_kind: 7 },
    )
    .expect_err("human target should require controller metadata");

    assert!(error.contains("controller_kind"));
}

#[test]
fn all_active_and_role_targets_exclude_inactive_companies() {
    let mut state = RuntimeState {
        companies: vec![
            RuntimeCompany {
                company_id: 1,
                controller_kind: RuntimeCompanyControllerKind::Human,
                current_cash: 10,
                debt: 1,
                credit_rating_score: None,
                prime_rate: None,
                track_piece_counts: 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,
            },
            RuntimeCompany {
                company_id: 2,
                controller_kind: RuntimeCompanyControllerKind::Human,
                current_cash: 20,
                debt: 2,
                credit_rating_score: None,
                prime_rate: None,
                track_piece_counts: RuntimeTrackPieceCounts::default(),
                active: false,
                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,
            },
            RuntimeCompany {
                company_id: 3,
                controller_kind: RuntimeCompanyControllerKind::Ai,
                current_cash: 30,
                debt: 3,
                credit_rating_score: None,
                prime_rate: None,
                track_piece_counts: 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,
            },
        ],
        event_runtime_records: vec![
            RuntimeEventRecord {
                record_id: 16,
                trigger_kind: 7,
                active: true,
                service_count: 0,
                marks_collection_dirty: false,
                one_shot: false,
                has_fired: false,
                conditions: Vec::new(),
                effects: vec![RuntimeEffect::AdjustCompanyCash {
                    target: RuntimeCompanyTarget::AllActive,
                    delta: 5,
                }],
            },
            RuntimeEventRecord {
                record_id: 17,
                trigger_kind: 7,
                active: true,
                service_count: 0,
                marks_collection_dirty: false,
                one_shot: false,
                has_fired: false,
                conditions: Vec::new(),
                effects: vec![RuntimeEffect::AdjustCompanyDebt {
                    target: RuntimeCompanyTarget::HumanCompanies,
                    delta: 4,
                }],
            },
            RuntimeEventRecord {
                record_id: 18,
                trigger_kind: 7,
                active: true,
                service_count: 0,
                marks_collection_dirty: false,
                one_shot: false,
                has_fired: false,
                conditions: Vec::new(),
                effects: vec![RuntimeEffect::AdjustCompanyDebt {
                    target: RuntimeCompanyTarget::AiCompanies,
                    delta: 6,
                }],
            },
        ],
        ..state()
    };

    execute_step_command(
        &mut state,
        &StepCommand::ServiceTriggerKind { trigger_kind: 7 },
    )
    .expect("active-company filtering should succeed");

    assert_eq!(state.companies[0].current_cash, 15);
    assert_eq!(state.companies[1].current_cash, 20);
    assert_eq!(state.companies[2].current_cash, 35);
    assert_eq!(state.companies[0].debt, 5);
    assert_eq!(state.companies[1].debt, 2);
    assert_eq!(state.companies[2].debt, 9);
}

#[test]
fn deactivating_selected_company_clears_selection() {
    let mut state = RuntimeState {
        companies: vec![RuntimeCompany {
            company_id: 1,
            controller_kind: RuntimeCompanyControllerKind::Human,
            current_cash: 10,
            debt: 0,
            credit_rating_score: None,
            prime_rate: None,
            track_piece_counts: RuntimeTrackPieceCounts::default(),
            active: true,
            available_track_laying_capacity: Some(8),
            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(1),
        event_runtime_records: vec![RuntimeEventRecord {
            record_id: 19,
            trigger_kind: 7,
            active: true,
            service_count: 0,
            marks_collection_dirty: false,
            one_shot: false,
            has_fired: false,
            conditions: Vec::new(),
            effects: vec![RuntimeEffect::DeactivateCompany {
                target: RuntimeCompanyTarget::SelectedCompany,
            }],
        }],
        ..state()
    };

    let result = execute_step_command(
        &mut state,
        &StepCommand::ServiceTriggerKind { trigger_kind: 7 },
    )
    .expect("deactivate company effect should succeed");

    assert!(!state.companies[0].active);
    assert_eq!(state.selected_company_id, None);
    assert_eq!(result.service_events[0].mutated_company_ids, vec![1]);
}

#[test]
fn deactivating_selected_player_clears_selection() {
    let mut state = RuntimeState {
        players: vec![RuntimePlayer {
            player_id: 1,
            current_cash: 500,
            active: true,
            controller_kind: RuntimeCompanyControllerKind::Human,
        }],
        selected_player_id: Some(1),
        event_runtime_records: vec![RuntimeEventRecord {
            record_id: 19,
            trigger_kind: 7,
            active: true,
            service_count: 0,
            marks_collection_dirty: false,
            one_shot: false,
            has_fired: false,
            conditions: Vec::new(),
            effects: vec![RuntimeEffect::DeactivatePlayer {
                target: RuntimePlayerTarget::SelectedPlayer,
            }],
        }],
        ..state()
    };

    let result = execute_step_command(
        &mut state,
        &StepCommand::ServiceTriggerKind { trigger_kind: 7 },
    )
    .expect("deactivate player effect should succeed");

    assert!(!state.players[0].active);
    assert_eq!(state.selected_player_id, None);
    assert_eq!(result.service_events[0].mutated_player_ids, vec![1]);
}

#[test]
fn sets_track_laying_capacity_for_resolved_targets() {
    let mut state = RuntimeState {
        companies: vec![
            RuntimeCompany {
                company_id: 1,
                controller_kind: RuntimeCompanyControllerKind::Human,
                current_cash: 10,
                debt: 0,
                credit_rating_score: None,
                prime_rate: None,
                track_piece_counts: 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,
            },
            RuntimeCompany {
                company_id: 2,
                controller_kind: RuntimeCompanyControllerKind::Ai,
                current_cash: 20,
                debt: 0,
                credit_rating_score: None,
                prime_rate: None,
                track_piece_counts: 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,
            },
        ],
        event_runtime_records: vec![RuntimeEventRecord {
            record_id: 20,
            trigger_kind: 7,
            active: true,
            service_count: 0,
            marks_collection_dirty: false,
            one_shot: false,
            has_fired: false,
            conditions: Vec::new(),
            effects: vec![RuntimeEffect::SetCompanyTrackLayingCapacity {
                target: RuntimeCompanyTarget::Ids { ids: vec![2] },
                value: Some(14),
            }],
        }],
        ..state()
    };

    let result = execute_step_command(
        &mut state,
        &StepCommand::ServiceTriggerKind { trigger_kind: 7 },
    )
    .expect("track capacity effect should succeed");

    assert_eq!(state.companies[0].available_track_laying_capacity, None);
    assert_eq!(state.companies[1].available_track_laying_capacity, Some(14));
    assert_eq!(result.service_events[0].mutated_company_ids, vec![2]);
}

#[test]
fn sets_and_clears_company_territory_access_for_resolved_targets() {
    let mut state = RuntimeState {
        companies: vec![
            RuntimeCompany {
                company_id: 1,
                controller_kind: RuntimeCompanyControllerKind::Human,
                current_cash: 10,
                debt: 0,
                credit_rating_score: None,
                prime_rate: None,
                track_piece_counts: 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,
            },
            RuntimeCompany {
                company_id: 2,
                controller_kind: RuntimeCompanyControllerKind::Ai,
                current_cash: 20,
                debt: 0,
                credit_rating_score: None,
                prime_rate: None,
                track_piece_counts: 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,
            },
        ],
        territories: vec![
            RuntimeTerritory {
                territory_id: 7,
                name: Some("Appalachia".to_string()),
                track_piece_counts: RuntimeTrackPieceCounts::default(),
            },
            RuntimeTerritory {
                territory_id: 8,
                name: Some("Great Plains".to_string()),
                track_piece_counts: RuntimeTrackPieceCounts::default(),
            },
        ],
        event_runtime_records: vec![
            RuntimeEventRecord {
                record_id: 21,
                trigger_kind: 7,
                active: true,
                service_count: 0,
                marks_collection_dirty: false,
                one_shot: true,
                has_fired: false,
                conditions: Vec::new(),
                effects: vec![RuntimeEffect::SetCompanyTerritoryAccess {
                    target: RuntimeCompanyTarget::SelectedCompany,
                    territory: RuntimeTerritoryTarget::Ids { ids: vec![7, 8] },
                    value: true,
                }],
            },
            RuntimeEventRecord {
                record_id: 22,
                trigger_kind: 8,
                active: true,
                service_count: 0,
                marks_collection_dirty: false,
                one_shot: true,
                has_fired: false,
                conditions: Vec::new(),
                effects: vec![RuntimeEffect::SetCompanyTerritoryAccess {
                    target: RuntimeCompanyTarget::SelectedCompany,
                    territory: RuntimeTerritoryTarget::Ids { ids: vec![8] },
                    value: false,
                }],
            },
        ],
        selected_company_id: Some(1),
        ..state()
    };

    let first = execute_step_command(
        &mut state,
        &StepCommand::ServiceTriggerKind { trigger_kind: 7 },
    )
    .expect("territory access grant should succeed");

    assert_eq!(
        state.company_territory_access,
        vec![
            crate::state::RuntimeCompanyTerritoryAccess {
                company_id: 1,
                territory_id: 7,
            },
            crate::state::RuntimeCompanyTerritoryAccess {
                company_id: 1,
                territory_id: 8,
            },
        ]
    );
    assert_eq!(first.service_events[0].mutated_company_ids, vec![1]);

    execute_step_command(
        &mut state,
        &StepCommand::ServiceTriggerKind { trigger_kind: 8 },
    )
    .expect("territory access clear should succeed");

    assert_eq!(
        state.company_territory_access,
        vec![crate::state::RuntimeCompanyTerritoryAccess {
            company_id: 1,
            territory_id: 7,
        }]
    );
}

#[test]
fn rejects_condition_true_company_target_without_condition_context() {
    let mut state = RuntimeState {
        event_runtime_records: vec![RuntimeEventRecord {
            record_id: 16,
            trigger_kind: 7,
            active: true,
            service_count: 0,
            marks_collection_dirty: false,
            one_shot: false,
            has_fired: false,
            conditions: Vec::new(),
            effects: vec![RuntimeEffect::AdjustCompanyCash {
                target: RuntimeCompanyTarget::ConditionTrueCompany,
                delta: 1,
            }],
        }],
        ..state()
    };

    let error = execute_step_command(
        &mut state,
        &StepCommand::ServiceTriggerKind { trigger_kind: 7 },
    )
    .expect_err("condition-relative target should remain blocked");

    assert!(error.contains("condition-evaluation context"));
}

#[test]
fn evaluates_world_state_conditions_before_effects_run() {
    let mut state = RuntimeState {
        world_restore: RuntimeWorldRestoreState {
            economic_status_code: Some(3),
            ..RuntimeWorldRestoreState::default()
        },
        world_flags: BTreeMap::from([(
            String::from("world.disable_stock_buying_and_selling"),
            true,
        )]),
        candidate_availability: BTreeMap::from([(String::from("Mogul"), 2)]),
        special_conditions: BTreeMap::from([(String::from("Use Wartime Cargos"), 1)]),
        event_runtime_records: vec![
            RuntimeEventRecord {
                record_id: 23,
                trigger_kind: 7,
                active: true,
                service_count: 0,
                marks_collection_dirty: false,
                one_shot: false,
                has_fired: false,
                conditions: vec![
                    RuntimeCondition::SpecialConditionThreshold {
                        label: "Use Wartime Cargos".to_string(),
                        comparator: RuntimeConditionComparator::Ge,
                        value: 1,
                    },
                    RuntimeCondition::CandidateAvailabilityThreshold {
                        name: "Mogul".to_string(),
                        comparator: RuntimeConditionComparator::Eq,
                        value: 2,
                    },
                    RuntimeCondition::EconomicStatusCodeThreshold {
                        comparator: RuntimeConditionComparator::Eq,
                        value: 3,
                    },
                    RuntimeCondition::WorldFlagEquals {
                        key: "world.disable_stock_buying_and_selling".to_string(),
                        value: true,
                    },
                ],
                effects: vec![RuntimeEffect::SetWorldFlag {
                    key: "world_condition_passed".to_string(),
                    value: true,
                }],
            },
            RuntimeEventRecord {
                record_id: 24,
                trigger_kind: 7,
                active: true,
                service_count: 0,
                marks_collection_dirty: false,
                one_shot: false,
                has_fired: false,
                conditions: vec![RuntimeCondition::SpecialConditionThreshold {
                    label: "Disable Cargo Economy".to_string(),
                    comparator: RuntimeConditionComparator::Gt,
                    value: 0,
                }],
                effects: vec![RuntimeEffect::SetWorldFlag {
                    key: "world_condition_failed".to_string(),
                    value: true,
                }],
            },
        ],
        ..state()
    };

    let result = execute_step_command(
        &mut state,
        &StepCommand::ServiceTriggerKind { trigger_kind: 7 },
    )
    .expect("world-state conditions should evaluate successfully");

    assert_eq!(result.service_events[0].serviced_record_ids, vec![23]);
    assert_eq!(state.world_flags.get("world_condition_passed"), Some(&true));
    assert_eq!(state.world_flags.get("world_condition_failed"), None);
}

#[test]
fn evaluates_world_scalar_conditions_before_effects_run() {
    let mut state = RuntimeState {
        world_restore: RuntimeWorldRestoreState {
            limited_track_building_amount: Some(18),
            territory_access_cost: Some(750000),
            ..RuntimeWorldRestoreState::default()
        },
        cargo_catalog: vec![
            crate::state::RuntimeCargoCatalogEntry {
                slot_id: 1,
                label: "Cargo Production Slot 1".to_string(),
                cargo_class: RuntimeCargoClass::Factory,
                supplied_token_stem: None,
                demanded_token_stem: None,
            },
            crate::state::RuntimeCargoCatalogEntry {
                slot_id: 5,
                label: "Cargo Production Slot 5".to_string(),
                cargo_class: RuntimeCargoClass::FarmMine,
                supplied_token_stem: None,
                demanded_token_stem: None,
            },
            crate::state::RuntimeCargoCatalogEntry {
                slot_id: 9,
                label: "Cargo Production Slot 9".to_string(),
                cargo_class: RuntimeCargoClass::Other,
                supplied_token_stem: None,
                demanded_token_stem: None,
            },
        ],
        named_locomotive_availability: BTreeMap::from([(String::from("Big Boy"), 42)]),
        named_locomotive_cost: BTreeMap::from([(String::from("GP7"), 175000)]),
        cargo_production_overrides: BTreeMap::from([(1, 125), (5, 75), (9, 30)]),
        event_runtime_records: vec![
            RuntimeEventRecord {
                record_id: 25,
                trigger_kind: 7,
                active: true,
                service_count: 0,
                marks_collection_dirty: false,
                one_shot: false,
                has_fired: false,
                conditions: vec![
                    RuntimeCondition::NamedLocomotiveAvailabilityThreshold {
                        name: "Big Boy".to_string(),
                        comparator: RuntimeConditionComparator::Eq,
                        value: 42,
                    },
                    RuntimeCondition::NamedLocomotiveCostThreshold {
                        name: "GP7".to_string(),
                        comparator: RuntimeConditionComparator::Eq,
                        value: 175000,
                    },
                    RuntimeCondition::CargoProductionSlotThreshold {
                        slot: 1,
                        label: "Cargo Production Slot 1".to_string(),
                        comparator: RuntimeConditionComparator::Eq,
                        value: 125,
                    },
                    RuntimeCondition::CargoProductionTotalThreshold {
                        comparator: RuntimeConditionComparator::Eq,
                        value: 230,
                    },
                    RuntimeCondition::FactoryProductionTotalThreshold {
                        comparator: RuntimeConditionComparator::Eq,
                        value: 125,
                    },
                    RuntimeCondition::FarmMineProductionTotalThreshold {
                        comparator: RuntimeConditionComparator::Eq,
                        value: 75,
                    },
                    RuntimeCondition::OtherCargoProductionTotalThreshold {
                        comparator: RuntimeConditionComparator::Eq,
                        value: 30,
                    },
                    RuntimeCondition::LimitedTrackBuildingAmountThreshold {
                        comparator: RuntimeConditionComparator::Eq,
                        value: 18,
                    },
                    RuntimeCondition::TerritoryAccessCostThreshold {
                        comparator: RuntimeConditionComparator::Eq,
                        value: 750000,
                    },
                ],
                effects: vec![RuntimeEffect::SetWorldFlag {
                    key: "world_scalar_condition_passed".to_string(),
                    value: true,
                }],
            },
            RuntimeEventRecord {
                record_id: 26,
                trigger_kind: 7,
                active: true,
                service_count: 0,
                marks_collection_dirty: false,
                one_shot: false,
                has_fired: false,
                conditions: vec![RuntimeCondition::NamedLocomotiveAvailabilityThreshold {
                    name: "Missing Loco".to_string(),
                    comparator: RuntimeConditionComparator::Gt,
                    value: 0,
                }],
                effects: vec![RuntimeEffect::SetWorldFlag {
                    key: "world_scalar_condition_failed".to_string(),
                    value: true,
                }],
            },
        ],
        ..state()
    };

    let result = execute_step_command(
        &mut state,
        &StepCommand::ServiceTriggerKind { trigger_kind: 7 },
    )
    .expect("world-scalar conditions should evaluate successfully");

    assert_eq!(result.service_events[0].serviced_record_ids, vec![25]);
    assert_eq!(
        state.world_flags.get("world_scalar_condition_passed"),
        Some(&true)
    );
    assert_eq!(state.world_flags.get("world_scalar_condition_failed"), None);
}

#[test]
fn company_governance_metric_conditions_gate_execution() {
    let mut state = RuntimeState {
        companies: vec![RuntimeCompany {
            company_id: 1,
            controller_kind: RuntimeCompanyControllerKind::Human,
            current_cash: 100,
            debt: 0,
            credit_rating_score: None,
            prime_rate: None,
            track_piece_counts: RuntimeTrackPieceCounts::default(),
            active: true,
            available_track_laying_capacity: None,
            linked_chairman_profile_id: None,
            book_value_per_share: 2620,
            investor_confidence: 37,
            management_attitude: 58,
            takeover_cooldown_year: Some(1844),
            merger_cooldown_year: Some(1845),
        }],
        selected_company_id: Some(1),
        event_runtime_records: vec![RuntimeEventRecord {
            record_id: 95,
            trigger_kind: 6,
            active: true,
            service_count: 0,
            marks_collection_dirty: false,
            one_shot: false,
            has_fired: false,
            conditions: vec![RuntimeCondition::CompanyNumericThreshold {
                target: RuntimeCompanyTarget::SelectedCompany,
                metric: RuntimeCompanyMetric::BookValuePerShare,
                comparator: RuntimeConditionComparator::Eq,
                value: 2620,
            }],
            effects: vec![RuntimeEffect::SetWorldFlag {
                key: "world.book_value_gate_passed".to_string(),
                value: true,
            }],
        }],
        ..state()
    };

    execute_step_command(
        &mut state,
        &StepCommand::ServiceTriggerKind { trigger_kind: 6 },
    )
    .expect("book-value company condition should gate execution");

    assert_eq!(
        state.world_flags.get("world.book_value_gate_passed"),
        Some(&true)
    );
}

#[test]
fn derived_prime_rate_condition_reads_rehosted_issue_owner_state() {
    let mut issue_terms = vec![0; 0x3b];
    issue_terms[RUNTIME_WORLD_ISSUE_PRIME_RATE as usize] = 100;
    let mut state = RuntimeState {
        companies: vec![RuntimeCompany {
            company_id: 1,
            controller_kind: RuntimeCompanyControllerKind::Human,
            current_cash: 100,
            debt: 0,
            credit_rating_score: None,
            prime_rate: None,
            track_piece_counts: RuntimeTrackPieceCounts::default(),
            active: true,
            available_track_laying_capacity: None,
            linked_chairman_profile_id: None,
            book_value_per_share: 2620,
            investor_confidence: 37,
            management_attitude: 58,
            takeover_cooldown_year: Some(1844),
            merger_cooldown_year: Some(1845),
        }],
        selected_company_id: Some(1),
        world_restore: RuntimeWorldRestoreState {
            issue_37_value: Some(5.0f32.to_bits()),
            ..RuntimeWorldRestoreState::default()
        },
        service_state: RuntimeServiceState {
            world_issue_opinion_base_terms_raw_i32: issue_terms,
            ..RuntimeServiceState::default()
        },
        event_runtime_records: vec![RuntimeEventRecord {
            record_id: 195,
            trigger_kind: 6,
            active: true,
            service_count: 0,
            marks_collection_dirty: false,
            one_shot: false,
            has_fired: false,
            conditions: vec![RuntimeCondition::CompanyNumericThreshold {
                target: RuntimeCompanyTarget::SelectedCompany,
                metric: RuntimeCompanyMetric::PrimeRate,
                comparator: RuntimeConditionComparator::Eq,
                value: 6,
            }],
            effects: vec![RuntimeEffect::SetWorldFlag {
                key: "world.derived_prime_rate_gate_passed".to_string(),
                value: true,
            }],
        }],
        ..state()
    };

    execute_step_command(
        &mut state,
        &StepCommand::ServiceTriggerKind { trigger_kind: 6 },
    )
    .expect("derived prime-rate company condition should gate execution");

    assert_eq!(
        state
            .world_flags
            .get("world.derived_prime_rate_gate_passed"),
        Some(&true)
    );
}

#[test]
fn derived_investor_confidence_condition_reads_rehosted_share_price_cache() {
    let mut state = RuntimeState {
        companies: vec![RuntimeCompany {
            company_id: 1,
            controller_kind: RuntimeCompanyControllerKind::Human,
            current_cash: 100,
            debt: 0,
            credit_rating_score: None,
            prime_rate: None,
            track_piece_counts: RuntimeTrackPieceCounts::default(),
            active: true,
            available_track_laying_capacity: None,
            linked_chairman_profile_id: None,
            book_value_per_share: 2620,
            investor_confidence: 0,
            management_attitude: 58,
            takeover_cooldown_year: Some(1844),
            merger_cooldown_year: Some(1845),
        }],
        selected_company_id: Some(1),
        service_state: RuntimeServiceState {
            company_market_state: BTreeMap::from([(
                1,
                crate::state::RuntimeCompanyMarketState {
                    recent_per_share_subscore_raw_u32: 12.0f32.to_bits(),
                    cached_share_price_raw_u32: 37.0f32.to_bits(),
                    ..crate::state::RuntimeCompanyMarketState::default()
                },
            )]),
            ..RuntimeServiceState::default()
        },
        event_runtime_records: vec![RuntimeEventRecord {
            record_id: 196,
            trigger_kind: 6,
            active: true,
            service_count: 0,
            marks_collection_dirty: false,
            one_shot: false,
            has_fired: false,
            conditions: vec![RuntimeCondition::CompanyNumericThreshold {
                target: RuntimeCompanyTarget::SelectedCompany,
                metric: RuntimeCompanyMetric::InvestorConfidence,
                comparator: RuntimeConditionComparator::Eq,
                value: 37,
            }],
            effects: vec![RuntimeEffect::SetWorldFlag {
                key: "world.derived_investor_confidence_gate_passed".to_string(),
                value: true,
            }],
        }],
        ..state()
    };

    execute_step_command(
        &mut state,
        &StepCommand::ServiceTriggerKind { trigger_kind: 6 },
    )
    .expect("derived investor-confidence company condition should gate execution");

    assert_eq!(
        state
            .world_flags
            .get("world.derived_investor_confidence_gate_passed"),
        Some(&true)
    );
}

#[test]
fn derived_management_attitude_condition_reads_issue3a_owner_state() {
    let mut issue_terms = vec![0; 0x3b];
    issue_terms[RUNTIME_WORLD_ISSUE_MANAGEMENT_ATTITUDE as usize] = 40;
    let mut company_terms = vec![0; 0x3b];
    company_terms[RUNTIME_WORLD_ISSUE_MANAGEMENT_ATTITUDE as usize] = 12;
    let mut chairman_terms = vec![0; 0x3b];
    chairman_terms[RUNTIME_WORLD_ISSUE_MANAGEMENT_ATTITUDE as usize] = 6;

    let mut state = RuntimeState {
        companies: vec![RuntimeCompany {
            company_id: 1,
            controller_kind: RuntimeCompanyControllerKind::Human,
            current_cash: 100,
            debt: 0,
            credit_rating_score: None,
            prime_rate: None,
            track_piece_counts: RuntimeTrackPieceCounts::default(),
            active: true,
            available_track_laying_capacity: None,
            linked_chairman_profile_id: Some(3),
            book_value_per_share: 2620,
            investor_confidence: 0,
            management_attitude: 0,
            takeover_cooldown_year: Some(1844),
            merger_cooldown_year: Some(1845),
        }],
        selected_company_id: Some(1),
        chairman_profiles: vec![crate::state::RuntimeChairmanProfile {
            profile_id: 3,
            name: "Chairman".to_string(),
            active: true,
            current_cash: 0,
            linked_company_id: Some(1),
            company_holdings: BTreeMap::new(),
            holdings_value_total: 0,
            net_worth_total: 0,
            purchasing_power_total: 0,
        }],
        service_state: RuntimeServiceState {
            world_issue_opinion_base_terms_raw_i32: issue_terms,
            company_market_state: BTreeMap::from([(
                1,
                crate::state::RuntimeCompanyMarketState {
                    issue_opinion_terms_raw_i32: company_terms,
                    ..crate::state::RuntimeCompanyMarketState::default()
                },
            )]),
            chairman_issue_opinion_terms_raw_i32: BTreeMap::from([(3, chairman_terms)]),
            ..RuntimeServiceState::default()
        },
        event_runtime_records: vec![RuntimeEventRecord {
            record_id: 196,
            trigger_kind: 6,
            active: true,
            service_count: 0,
            marks_collection_dirty: false,
            one_shot: false,
            has_fired: false,
            conditions: vec![RuntimeCondition::CompanyNumericThreshold {
                target: RuntimeCompanyTarget::SelectedCompany,
                metric: RuntimeCompanyMetric::ManagementAttitude,
                comparator: RuntimeConditionComparator::Eq,
                value: 58,
            }],
            effects: vec![RuntimeEffect::SetWorldFlag {
                key: "world.derived_management_attitude_gate_passed".to_string(),
                value: true,
            }],
        }],
        ..state()
    };

    execute_step_command(
        &mut state,
        &StepCommand::ServiceTriggerKind { trigger_kind: 6 },
    )
    .expect("derived management-attitude company condition should gate execution");

    assert_eq!(
        state
            .world_flags
            .get("world.derived_management_attitude_gate_passed"),
        Some(&true)
    );
}

#[test]
fn book_value_condition_reads_rehosted_direct_company_field_band() {
    let mut state = RuntimeState {
        companies: vec![RuntimeCompany {
            company_id: 1,
            controller_kind: RuntimeCompanyControllerKind::Human,
            current_cash: 0,
            debt: 0,
            credit_rating_score: None,
            prime_rate: None,
            track_piece_counts: RuntimeTrackPieceCounts::default(),
            active: true,
            available_track_laying_capacity: None,
            linked_chairman_profile_id: None,
            book_value_per_share: 0,
            investor_confidence: 37,
            management_attitude: 58,
            takeover_cooldown_year: Some(1844),
            merger_cooldown_year: Some(1845),
        }],
        selected_company_id: Some(1),
        service_state: RuntimeServiceState {
            company_market_state: BTreeMap::from([(
                1,
                crate::state::RuntimeCompanyMarketState {
                    direct_control_transfer_float_fields_raw_u32: BTreeMap::from([(
                        0x32f,
                        2620.0f32.to_bits(),
                    )]),
                    ..crate::state::RuntimeCompanyMarketState::default()
                },
            )]),
            ..RuntimeServiceState::default()
        },
        event_runtime_records: vec![RuntimeEventRecord {
            record_id: 197,
            trigger_kind: 6,
            active: true,
            service_count: 0,
            marks_collection_dirty: false,
            one_shot: false,
            has_fired: false,
            conditions: vec![RuntimeCondition::CompanyNumericThreshold {
                target: RuntimeCompanyTarget::SelectedCompany,
                metric: RuntimeCompanyMetric::BookValuePerShare,
                comparator: RuntimeConditionComparator::Eq,
                value: 2620,
            }],
            effects: vec![RuntimeEffect::SetWorldFlag {
                key: "world.rehosted_book_value_gate_passed".to_string(),
                value: true,
            }],
        }],
        ..state()
    };

    execute_step_command(
        &mut state,
        &StepCommand::ServiceTriggerKind { trigger_kind: 6 },
    )
    .expect("rehosted direct-field book-value condition should gate execution");

    assert_eq!(
        state
            .world_flags
            .get("world.rehosted_book_value_gate_passed"),
        Some(&true)
    );
}

#[test]
fn derived_credit_rating_condition_reads_rehosted_finance_owner_state() {
    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[(0x12 * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize] =
        20.0f64.to_bits();
    year_stat_family_qword_bits[(0x01 * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN + 1) as usize] =
        100.0f64.to_bits();
    year_stat_family_qword_bits[(0x09 * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN + 1) as usize] =
        0.0f64.to_bits();

    let mut state = RuntimeState {
        companies: vec![RuntimeCompany {
            company_id: 1,
            controller_kind: RuntimeCompanyControllerKind::Human,
            current_cash: 100,
            debt: 0,
            credit_rating_score: None,
            prime_rate: None,
            track_piece_counts: RuntimeTrackPieceCounts::default(),
            active: true,
            available_track_laying_capacity: None,
            linked_chairman_profile_id: None,
            book_value_per_share: 0,
            investor_confidence: 37,
            management_attitude: 58,
            takeover_cooldown_year: Some(1844),
            merger_cooldown_year: Some(1845),
        }],
        selected_company_id: Some(1),
        world_restore: RuntimeWorldRestoreState {
            issue_37_value: Some(5.0f32.to_bits()),
            issue_38_value: Some(2),
            packed_year_word_raw_u16: Some(1835),
            ..RuntimeWorldRestoreState::default()
        },
        service_state: RuntimeServiceState {
            world_issue_opinion_base_terms_raw_i32: vec![0; 0x3b],
            company_market_state: BTreeMap::from([(
                1,
                crate::state::RuntimeCompanyMarketState {
                    outstanding_shares: 10_000,
                    founding_year: 1830,
                    last_bankruptcy_year: 1800,
                    year_stat_family_qword_bits,
                    live_bond_slots: vec![crate::state::RuntimeCompanyBondSlot {
                        slot_index: 0,
                        principal: 100_000,
                        maturity_year: 0,
                        coupon_rate_raw_u32: 0.05f32.to_bits(),
                    }],
                    ..crate::state::RuntimeCompanyMarketState::default()
                },
            )]),
            ..RuntimeServiceState::default()
        },
        event_runtime_records: vec![RuntimeEventRecord {
            record_id: 196,
            trigger_kind: 6,
            active: true,
            service_count: 0,
            marks_collection_dirty: false,
            one_shot: false,
            has_fired: false,
            conditions: vec![RuntimeCondition::CompanyNumericThreshold {
                target: RuntimeCompanyTarget::SelectedCompany,
                metric: RuntimeCompanyMetric::CreditRating,
                comparator: RuntimeConditionComparator::Eq,
                value: 10,
            }],
            effects: vec![RuntimeEffect::SetWorldFlag {
                key: "world.derived_credit_rating_gate_passed".to_string(),
                value: true,
            }],
        }],
        ..state()
    };

    execute_step_command(
        &mut state,
        &StepCommand::ServiceTriggerKind { trigger_kind: 6 },
    )
    .expect("derived credit-rating company condition should gate execution");

    assert_eq!(
        state
            .world_flags
            .get("world.derived_credit_rating_gate_passed"),
        Some(&true)
    );
}

#[test]
fn chairman_metric_conditions_support_all_active_target() {
    let mut state = RuntimeState {
        chairman_profiles: vec![
            RuntimeChairmanProfile {
                profile_id: 1,
                name: "Chairman One".to_string(),
                active: true,
                current_cash: 20,
                linked_company_id: None,
                company_holdings: BTreeMap::new(),
                holdings_value_total: 500,
                net_worth_total: 700,
                purchasing_power_total: 900,
            },
            RuntimeChairmanProfile {
                profile_id: 2,
                name: "Chairman Two".to_string(),
                active: true,
                current_cash: 30,
                linked_company_id: None,
                company_holdings: BTreeMap::new(),
                holdings_value_total: 600,
                net_worth_total: 800,
                purchasing_power_total: 1000,
            },
        ],
        event_runtime_records: vec![RuntimeEventRecord {
            record_id: 96,
            trigger_kind: 6,
            active: true,
            service_count: 0,
            marks_collection_dirty: false,
            one_shot: false,
            has_fired: false,
            conditions: vec![RuntimeCondition::ChairmanNumericThreshold {
                target: RuntimeChairmanTarget::AllActive,
                metric: RuntimeChairmanMetric::PurchasingPowerTotal,
                comparator: RuntimeConditionComparator::Ge,
                value: 900,
            }],
            effects: vec![RuntimeEffect::SetWorldFlag {
                key: "world.chairman_gate_passed".to_string(),
                value: true,
            }],
        }],
        ..state()
    };

    execute_step_command(
        &mut state,
        &StepCommand::ServiceTriggerKind { trigger_kind: 6 },
    )
    .expect("all-active chairman condition should gate execution");

    assert_eq!(
        state.world_flags.get("world.chairman_gate_passed"),
        Some(&true)
    );
}
