use crate::derived::{
    runtime_company_annual_stock_repurchase_state,
    runtime_company_support_adjusted_share_price_scalar_with_pressure_f64,
    runtime_round_f64_to_i64,
};
use crate::engine::service::annual_finance::constants::{
    COMPANY_REPURCHASE_PRESSURE_SCALE, COMPANY_STOCK_AND_BOND_CAPITAL_POST_SCALE,
};
use crate::engine::service::service_post_company_stat_delta;
use crate::event::metrics::RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH;
use crate::state::RuntimeState;

pub(super) fn apply_stock_repurchase(state: &mut RuntimeState, company_id: u32) -> bool {
    let mut mutated = false;
    for _ in 0..128 {
        let Some(repurchase_state) =
            runtime_company_annual_stock_repurchase_state(state, company_id)
        else {
            break;
        };
        if !repurchase_state.eligible_for_single_batch_repurchase {
            break;
        }
        let Some(batch_size) = repurchase_state.repurchase_batch_size else {
            break;
        };
        let Some(pressure_shares) =
            runtime_round_f64_to_i64(batch_size as f64 * COMPANY_REPURCHASE_PRESSURE_SCALE)
        else {
            break;
        };
        let Some(share_price_scalar) =
            runtime_company_support_adjusted_share_price_scalar_with_pressure_f64(
                state,
                company_id,
                pressure_shares,
            )
        else {
            break;
        };
        let Some(repurchase_total) =
            runtime_round_f64_to_i64(share_price_scalar * batch_size as f64)
        else {
            break;
        };
        if repurchase_total <= 0 {
            break;
        }
        let Some(next_outstanding_shares) = state
            .service_state
            .company_market_state
            .get(&company_id)
            .map(|market_state| market_state.outstanding_shares)
            .and_then(|value| value.checked_sub(batch_size))
        else {
            break;
        };
        mutated |= service_post_company_stat_delta(
            state,
            company_id,
            0x0c,
            (repurchase_total as f64) * COMPANY_STOCK_AND_BOND_CAPITAL_POST_SCALE,
            true,
        );
        mutated |= service_post_company_stat_delta(
            state,
            company_id,
            RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH,
            -(repurchase_total as f64),
            false,
        );
        let Some(market_state) = state
            .service_state
            .company_market_state
            .get_mut(&company_id)
        else {
            break;
        };
        market_state.outstanding_shares = next_outstanding_shares;
        state.service_state.annual_stock_repurchase_last_share_count = state
            .service_state
            .annual_stock_repurchase_last_share_count
            .saturating_add(u64::from(batch_size));
    }
    mutated
}
