use crate::derived::{
    runtime_company_annual_finance_state, runtime_company_control_transfer_stat_value_f64,
    runtime_company_stat_value_f64, runtime_company_support_adjusted_share_price_scalar,
    runtime_round_f64_to_i64, runtime_world_annual_finance_mode_active,
    runtime_world_bankruptcy_allowed,
};
use crate::event::metrics::{
    RUNTIME_COMPANY_STAT_FAMILY_CONTROL_TRANSFER, RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH,
    RuntimeCompanyStatSelector,
};
use crate::state::{
    RuntimeCompanyAnnualCreditorPressureState, RuntimeCompanyAnnualDeepDistressState, RuntimeState,
};

pub fn runtime_company_annual_creditor_pressure_state(
    state: &RuntimeState,
    company_id: u32,
) -> Option<RuntimeCompanyAnnualCreditorPressureState> {
    let annual_finance_state = runtime_company_annual_finance_state(state, company_id)?;
    let current_cash_plus_slot_12_total =
        runtime_company_control_transfer_stat_value_f64(state, company_id, 0x12)
            .and_then(runtime_round_f64_to_i64)
            .and_then(|slot_12| {
                runtime_company_control_transfer_stat_value_f64(
                    state,
                    company_id,
                    RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH,
                )
                .and_then(runtime_round_f64_to_i64)
                .map(|current_cash| current_cash + slot_12)
            });
    let support_adjusted_share_price_scalar =
        runtime_company_support_adjusted_share_price_scalar(state, company_id)
            .and_then(runtime_round_f64_to_i64);
    let current_fuel_cost = runtime_company_stat_value_f64(
        state,
        company_id,
        RuntimeCompanyStatSelector {
            family_id: RUNTIME_COMPANY_STAT_FAMILY_CONTROL_TRANSFER,
            slot_id: 0x09,
        },
    )
    .and_then(runtime_round_f64_to_i64);
    let recent_bad_net_profit_year_count = annual_finance_state
        .trailing_full_year_net_profits
        .iter()
        .take(3)
        .filter(|value| **value < -10_000)
        .count() as u32;
    let recent_peak_revenue = annual_finance_state
        .trailing_full_year_revenues
        .iter()
        .take(3)
        .copied()
        .max();
    let recent_three_year_net_profit_total =
        if annual_finance_state.trailing_full_year_net_profits.len() >= 3 {
            Some(
                annual_finance_state
                    .trailing_full_year_net_profits
                    .iter()
                    .take(3)
                    .sum::<i64>(),
            )
        } else {
            None
        };
    let pressure_ladder_cash_floor = recent_peak_revenue.map(|revenue| {
        if revenue < 120_000 {
            -600_000
        } else if revenue < 230_000 {
            -1_100_000
        } else if revenue < 340_000 {
            -1_600_000
        } else {
            -2_000_000
        }
    });
    let support_adjusted_share_price_floor = Some(if recent_bad_net_profit_year_count == 3 {
        20
    } else {
        15
    });
    let current_fuel_cost_floor = pressure_ladder_cash_floor.map(|floor| floor * 8 / 100);
    let eligible_for_bankruptcy_branch = runtime_world_annual_finance_mode_active(state)
        == Some(true)
        && runtime_world_bankruptcy_allowed(state) == Some(true)
        && annual_finance_state
            .years_since_last_bankruptcy
            .is_some_and(|years| years >= 13)
        && annual_finance_state
            .years_since_founding
            .is_some_and(|years| years >= 4)
        && recent_bad_net_profit_year_count >= 2
        && current_cash_plus_slot_12_total
            .zip(pressure_ladder_cash_floor)
            .is_some_and(|(value, floor)| value <= floor)
        && support_adjusted_share_price_scalar
            .zip(support_adjusted_share_price_floor)
            .is_some_and(|(value, floor)| value >= floor)
        && current_fuel_cost
            .zip(current_fuel_cost_floor)
            .is_some_and(|(value, floor)| value <= floor)
        && recent_three_year_net_profit_total.is_some_and(|value| value <= -60_000);
    Some(RuntimeCompanyAnnualCreditorPressureState {
        company_id,
        annual_mode_active: runtime_world_annual_finance_mode_active(state),
        bankruptcy_allowed: runtime_world_bankruptcy_allowed(state),
        years_since_last_bankruptcy: annual_finance_state.years_since_last_bankruptcy,
        years_since_founding: annual_finance_state.years_since_founding,
        recent_bad_net_profit_year_count,
        recent_peak_revenue,
        recent_three_year_net_profit_total,
        pressure_ladder_cash_floor,
        current_cash_plus_slot_12_total,
        support_adjusted_share_price_floor,
        support_adjusted_share_price_scalar,
        current_fuel_cost,
        current_fuel_cost_floor,
        eligible_for_bankruptcy_branch,
    })
}

pub fn runtime_company_annual_deep_distress_state(
    state: &RuntimeState,
    company_id: u32,
) -> Option<RuntimeCompanyAnnualDeepDistressState> {
    let annual_finance_state = runtime_company_annual_finance_state(state, company_id)?;
    let current_cash = runtime_company_control_transfer_stat_value_f64(
        state,
        company_id,
        RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH,
    )
    .and_then(runtime_round_f64_to_i64);
    let recent_first_three_net_profit_years = annual_finance_state
        .trailing_full_year_net_profits
        .iter()
        .take(3)
        .copied()
        .collect::<Vec<_>>();
    let deep_distress_cash_floor = Some(-300_000);
    let deep_distress_net_profit_floor = Some(-20_000);
    let eligible_for_bankruptcy_fallback = runtime_world_bankruptcy_allowed(state) == Some(true)
        && current_cash
            .zip(deep_distress_cash_floor)
            .is_some_and(|(value, floor)| value <= floor)
        && annual_finance_state
            .years_since_founding
            .is_some_and(|years| years >= 3)
        && recent_first_three_net_profit_years.len() == 3
        && recent_first_three_net_profit_years
            .iter()
            .all(|value| *value <= deep_distress_net_profit_floor.unwrap())
        && annual_finance_state
            .years_since_last_bankruptcy
            .is_some_and(|years| years >= 5);
    Some(RuntimeCompanyAnnualDeepDistressState {
        company_id,
        bankruptcy_allowed: runtime_world_bankruptcy_allowed(state),
        years_since_founding: annual_finance_state.years_since_founding,
        years_since_last_bankruptcy: annual_finance_state.years_since_last_bankruptcy,
        current_cash,
        recent_first_three_net_profit_years,
        deep_distress_cash_floor,
        deep_distress_net_profit_floor,
        eligible_for_bankruptcy_fallback,
    })
}
