use crate::derived::runtime_company_annual_stock_issue_state;
use crate::engine::service::annual_finance::constants::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_issue(state: &mut RuntimeState, company_id: u32) -> bool {
    let Some(issue_state) = runtime_company_annual_stock_issue_state(state, company_id) else {
        return false;
    };
    let Some(batch_size) = issue_state.trimmed_issue_batch_size else {
        return false;
    };
    let Some(proceeds_per_tranche) = issue_state.pressured_proceeds else {
        return false;
    };
    let Some(current_tuple_word_0) = state.world_restore.current_calendar_tuple_word_raw_u32 else {
        return false;
    };
    let Some(current_tuple_word_1) = state.world_restore.current_calendar_tuple_word_2_raw_u32
    else {
        return false;
    };
    let Some(total_share_delta) = batch_size.checked_mul(2) else {
        return false;
    };
    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_add(total_share_delta))
    else {
        return false;
    };

    let mut mutated = false;
    for _ in 0..2 {
        mutated |= service_post_company_stat_delta(
            state,
            company_id,
            0x0c,
            (batch_size 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,
            proceeds_per_tranche as f64,
            false,
        );
        state.service_state.annual_stock_issue_last_share_count = state
            .service_state
            .annual_stock_issue_last_share_count
            .saturating_add(u64::from(batch_size));
    }
    let Some(market_state) = state
        .service_state
        .company_market_state
        .get_mut(&company_id)
    else {
        return false;
    };
    market_state.outstanding_shares = next_outstanding_shares;
    market_state.prior_issue_calendar_word = market_state.current_issue_calendar_word;
    market_state.prior_issue_calendar_word_2 = market_state.current_issue_calendar_word_2;
    market_state.current_issue_calendar_word = current_tuple_word_0;
    market_state.current_issue_calendar_word_2 = current_tuple_word_1;
    mutated
}
