use crate::derived::{
    derive_runtime_company_elapsed_years, runtime_decode_saved_f32_value,
    runtime_decode_saved_f64_bits, runtime_world_absolute_counter,
    runtime_world_issue_opinion_multiplier,
};
use crate::event::metrics::RUNTIME_WORLD_ISSUE_INVESTOR_CONFIDENCE;
use crate::state::RuntimeState;

pub(crate) fn runtime_company_support_adjusted_share_price_scalar_with_pressure_f64(
    state: &RuntimeState,
    company_id: u32,
    share_pressure_shares: i64,
) -> Option<f64> {
    let market_state = state.service_state.company_market_state.get(&company_id)?;
    if let Some(cached_value) =
        runtime_decode_saved_f32_value(market_state.cached_share_price_raw_u32)
    {
        if share_pressure_shares == 0 {
            return Some(cached_value.max(0.0001));
        }
    }

    if market_state.outstanding_shares == 0 {
        return Some(0.0010000000474974513);
    }

    let company = state
        .companies
        .iter()
        .find(|company| company.company_id == company_id)?;
    let mut recent_per_share = runtime_company_recent_per_share_subscore(state, company_id)?;
    let young_company_support =
        runtime_decode_saved_f32_value(market_state.young_company_support_scalar_raw_u32)?;
    if recent_per_share < young_company_support {
        let years_since_founding =
            derive_runtime_company_elapsed_years(state.calendar.year, market_state.founding_year)
                .unwrap_or(u32::MAX);
        if years_since_founding <= 5 {
            let elapsed_support_ticks = runtime_world_absolute_counter(state)
                .unwrap_or(0)
                .saturating_sub(market_state.support_progress_word);
            let interpolation = (elapsed_support_ticks / 50).min(50) as f64;
            recent_per_share = ((50.0 - interpolation) * young_company_support
                + (50.0 + interpolation) * recent_per_share)
                / 100.0;
        }
    }

    let mutable_support =
        runtime_decode_saved_f32_value(market_state.mutable_support_scalar_raw_u32)?;
    let share_pressure =
        (share_pressure_shares as f64 / market_state.outstanding_shares as f64).clamp(-0.2, 0.2);
    let effective_mutable_support = mutable_support + share_pressure;
    let share_count_growth_ratio = ((market_state.outstanding_shares as f64
        + 1.4
            * effective_mutable_support
            * ((market_state.outstanding_shares as f64 / 20_000.0).powf(0.33)))
        / market_state.outstanding_shares as f64)
        .clamp(0.3, 6.0);

    let investor_multiplier = runtime_world_issue_opinion_multiplier(
        state,
        RUNTIME_WORLD_ISSUE_INVESTOR_CONFIDENCE,
        company.linked_chairman_profile_id,
        Some(company_id),
        None,
    )?;

    Some(((recent_per_share * share_count_growth_ratio * investor_multiplier) + 1.0).max(0.0001))
}

pub fn runtime_company_recent_per_share_subscore(
    state: &RuntimeState,
    company_id: u32,
) -> Option<f64> {
    let market_state = state.service_state.company_market_state.get(&company_id)?;
    if runtime_world_absolute_counter(state)
        .is_some_and(|counter| counter == market_state.recent_per_share_cache_absolute_counter)
    {
        if let Some(cached_value) =
            runtime_decode_saved_f64_bits(market_state.recent_per_share_cached_value_bits)
        {
            return Some(cached_value);
        }
    }
    runtime_decode_saved_f32_value(market_state.recent_per_share_subscore_raw_u32)
}

pub fn runtime_company_support_adjusted_share_price_scalar(
    state: &RuntimeState,
    company_id: u32,
) -> Option<f64> {
    runtime_company_support_adjusted_share_price_scalar_with_pressure_f64(state, company_id, 0)
}
