use std::collections::BTreeSet;

use crate::engine::command::ServiceEvent;
use crate::engine::service::{
    service_company_annual_finance_policy, service_company_near_city_acquisition,
    service_trigger_kind,
};
use crate::state::{RuntimeCompanyPeriodicSideLatchState, RuntimeState};

const PERIODIC_TRIGGER_KIND_ORDER: [u8; 6] = [1, 2, 3, 4, 5, 6];

pub(crate) fn service_periodic_boundary(
    state: &mut RuntimeState,
    service_events: &mut Vec<ServiceEvent>,
) -> Result<(), String> {
    state.service_state.periodic_boundary_calls += 1;
    service_refresh_company_periodic_side_latch_state(state);

    for trigger_kind in PERIODIC_TRIGGER_KIND_ORDER {
        service_trigger_kind(state, trigger_kind, service_events)?;
    }
    service_company_near_city_acquisition(state, service_events)?;
    service_company_annual_finance_policy(state, service_events)?;

    Ok(())
}

pub(crate) fn service_refresh_company_periodic_side_latch_state(state: &mut RuntimeState) {
    let active_company_ids = state
        .companies
        .iter()
        .filter(|company| company.active)
        .map(|company| company.company_id)
        .collect::<BTreeSet<_>>();
    state
        .service_state
        .company_periodic_side_latch_state
        .retain(|company_id, _| active_company_ids.contains(company_id));

    for company_id in active_company_ids {
        match (
            state
                .service_state
                .company_periodic_side_latch_state
                .get_mut(&company_id),
            state.service_state.company_market_state.get(&company_id),
        ) {
            (Some(latch_state), Some(market_state)) => {
                latch_state.preferred_locomotive_engine_type_raw_u8 = None;
                latch_state.city_connection_latch = market_state.city_connection_latch;
                latch_state.linked_transit_latch = market_state.linked_transit_latch;
            }
            (Some(latch_state), None) => {
                latch_state.preferred_locomotive_engine_type_raw_u8 = None;
            }
            (None, Some(market_state)) => {
                state
                    .service_state
                    .company_periodic_side_latch_state
                    .insert(
                        company_id,
                        RuntimeCompanyPeriodicSideLatchState {
                            preferred_locomotive_engine_type_raw_u8: None,
                            city_connection_latch: market_state.city_connection_latch,
                            linked_transit_latch: market_state.linked_transit_latch,
                        },
                    );
            }
            (None, None) => {}
        }
    }
}
