use crate::derived::{
    runtime_annual_bond_principal_flow_relation_label, runtime_company_annual_bond_policy_state,
    runtime_company_annual_creditor_pressure_state, runtime_company_annual_deep_distress_state,
    runtime_company_annual_dividend_policy_state, runtime_company_annual_finance_state,
    runtime_company_annual_stock_issue_state, runtime_company_annual_stock_repurchase_state,
};
use crate::state::{
    RuntimeCompanyAnnualFinancePolicyAction, RuntimeCompanyAnnualFinancePolicyState, RuntimeState,
};

pub fn runtime_world_annual_finance_mode_active(state: &RuntimeState) -> Option<bool> {
    Some(state.world_restore.partial_year_progress_raw_u8? == 0x0c)
}

pub fn runtime_world_bankruptcy_allowed(state: &RuntimeState) -> Option<bool> {
    Some(state.world_restore.bankruptcy_policy_raw_u8? == 0)
}

pub fn runtime_world_bond_issue_and_repayment_allowed(state: &RuntimeState) -> Option<bool> {
    Some(state.world_restore.bond_issue_and_repayment_policy_raw_u8? == 0)
}

pub fn runtime_world_stock_issue_and_buyback_allowed(state: &RuntimeState) -> Option<bool> {
    Some(state.world_restore.stock_issue_and_buyback_policy_raw_u8? == 0)
}

pub fn runtime_world_dividend_adjustment_allowed(state: &RuntimeState) -> Option<bool> {
    Some(state.world_restore.dividend_policy_raw_u8? == 0)
}

pub fn runtime_world_building_density_growth_setting(state: &RuntimeState) -> Option<u32> {
    state.world_restore.building_density_growth_setting_raw_u32
}

pub fn runtime_company_annual_finance_policy_state(
    state: &RuntimeState,
    company_id: u32,
) -> Option<RuntimeCompanyAnnualFinancePolicyState> {
    runtime_company_annual_finance_state(state, company_id)?;
    let creditor_pressure_bankruptcy_eligible =
        runtime_company_annual_creditor_pressure_state(state, company_id)
            .map(|state| state.eligible_for_bankruptcy_branch)
            .unwrap_or(false);
    let deep_distress_bankruptcy_fallback_eligible =
        runtime_company_annual_deep_distress_state(state, company_id)
            .map(|state| state.eligible_for_bankruptcy_fallback)
            .unwrap_or(false);
    let bond_issue_eligible = runtime_company_annual_bond_policy_state(state, company_id)
        .map(|state| state.eligible_for_bond_issue_branch)
        .unwrap_or(false);
    let stock_repurchase_eligible =
        runtime_company_annual_stock_repurchase_state(state, company_id)
            .map(|state| state.eligible_for_single_batch_repurchase)
            .unwrap_or(false);
    let stock_issue_eligible = runtime_company_annual_stock_issue_state(state, company_id)
        .map(|state| state.eligible_for_double_tranche_issue)
        .unwrap_or(false);
    let dividend_adjustment_eligible =
        runtime_company_annual_dividend_policy_state(state, company_id)
            .map(|state| state.eligible_for_dividend_adjustment_branch)
            .unwrap_or(false);
    let action = if creditor_pressure_bankruptcy_eligible {
        RuntimeCompanyAnnualFinancePolicyAction::CreditorPressureBankruptcy
    } else if deep_distress_bankruptcy_fallback_eligible {
        RuntimeCompanyAnnualFinancePolicyAction::DeepDistressBankruptcyFallback
    } else if bond_issue_eligible {
        RuntimeCompanyAnnualFinancePolicyAction::BondIssue
    } else if stock_repurchase_eligible {
        RuntimeCompanyAnnualFinancePolicyAction::StockRepurchase
    } else if stock_issue_eligible {
        RuntimeCompanyAnnualFinancePolicyAction::StockIssue
    } else if dividend_adjustment_eligible {
        RuntimeCompanyAnnualFinancePolicyAction::DividendAdjustment
    } else {
        RuntimeCompanyAnnualFinancePolicyAction::None
    };
    Some(RuntimeCompanyAnnualFinancePolicyState {
        company_id,
        action,
        creditor_pressure_bankruptcy_eligible,
        deep_distress_bankruptcy_fallback_eligible,
        bond_issue_eligible,
        stock_repurchase_eligible,
        stock_issue_eligible,
        dividend_adjustment_eligible,
    })
}

pub fn runtime_company_annual_finance_policy_action_label(
    action: RuntimeCompanyAnnualFinancePolicyAction,
) -> &'static str {
    match action {
        RuntimeCompanyAnnualFinancePolicyAction::None => "none",
        RuntimeCompanyAnnualFinancePolicyAction::CreditorPressureBankruptcy => {
            "creditor_pressure_bankruptcy"
        }
        RuntimeCompanyAnnualFinancePolicyAction::DeepDistressBankruptcyFallback => {
            "deep_distress_bankruptcy_fallback"
        }
        RuntimeCompanyAnnualFinancePolicyAction::BondIssue => "bond_issue",
        RuntimeCompanyAnnualFinancePolicyAction::StockRepurchase => "stock_repurchase",
        RuntimeCompanyAnnualFinancePolicyAction::StockIssue => "stock_issue",
        RuntimeCompanyAnnualFinancePolicyAction::DividendAdjustment => "dividend_adjustment",
    }
}

pub fn runtime_annual_finance_news_family_candidate_label(
    action: RuntimeCompanyAnnualFinancePolicyAction,
    retired_principal_total: u64,
    issued_principal_total: u64,
    repurchased_share_count: u64,
    issued_share_count: u64,
) -> Option<&'static str> {
    match action {
        RuntimeCompanyAnnualFinancePolicyAction::CreditorPressureBankruptcy
        | RuntimeCompanyAnnualFinancePolicyAction::DeepDistressBankruptcyFallback => Some("2881"),
        RuntimeCompanyAnnualFinancePolicyAction::BondIssue => {
            match runtime_annual_bond_principal_flow_relation_label(
                retired_principal_total,
                issued_principal_total,
            ) {
                Some("retired_equals_issued") => Some("2882"),
                Some("issued_exceeds_retired") => Some("2883"),
                Some("retired_exceeds_issued") => Some("2884"),
                Some("retired_only") => Some("2885"),
                Some("issued_only") => Some("2886"),
                _ => None,
            }
        }
        RuntimeCompanyAnnualFinancePolicyAction::StockRepurchase => {
            (repurchased_share_count > 0).then_some("2887")
        }
        RuntimeCompanyAnnualFinancePolicyAction::StockIssue => {
            (issued_share_count > 0).then_some("4053")
        }
        _ => None,
    }
}
