use std::collections::BTreeSet;

use crate::engine::conditions::ResolvedConditionContext;
use crate::event::targets::RuntimeChairmanTarget;
use crate::state::{RuntimeChairmanProfile, RuntimeCompanyControllerKind, RuntimeState};

use super::shared;

pub(in crate::engine) fn resolve_chairman_target_ids(
    state: &RuntimeState,
    target: &RuntimeChairmanTarget,
    condition_context: &ResolvedConditionContext,
) -> Result<Vec<u32>, String> {
    match target {
        RuntimeChairmanTarget::AllActive => Ok(state
            .chairman_profiles
            .iter()
            .filter(|profile| profile.active)
            .map(|profile| profile.profile_id)
            .collect()),
        RuntimeChairmanTarget::HumanChairmen => Ok(state
            .chairman_profiles
            .iter()
            .filter(|profile| {
                chairman_profile_matches_company_controller_kind(
                    state,
                    profile,
                    RuntimeCompanyControllerKind::Human,
                )
            })
            .map(|profile| profile.profile_id)
            .collect()),
        RuntimeChairmanTarget::AiChairmen => Ok(state
            .chairman_profiles
            .iter()
            .filter(|profile| {
                chairman_profile_matches_company_controller_kind(
                    state,
                    profile,
                    RuntimeCompanyControllerKind::Ai,
                )
            })
            .map(|profile| profile.profile_id)
            .collect()),
        RuntimeChairmanTarget::Ids { ids } => {
            let known_ids = state
                .chairman_profiles
                .iter()
                .map(|profile| profile.profile_id)
                .collect::<BTreeSet<_>>();
            shared::validate_known_ids(ids, &known_ids, |profile_id| {
                format!("target references unknown chairman profile_id {profile_id}")
            })?;
            Ok(ids.clone())
        }
        RuntimeChairmanTarget::SelectedChairman => {
            let selected_profile_id = state.selected_chairman_profile_id.ok_or_else(|| {
                "target requires selected_chairman_profile_id context".to_string()
            })?;
            if state
                .chairman_profiles
                .iter()
                .any(|profile| profile.profile_id == selected_profile_id && profile.active)
            {
                Ok(vec![selected_profile_id])
            } else {
                Err(
                    "target requires selected_chairman_profile_id to reference an active chairman profile"
                        .to_string(),
                )
            }
        }
        RuntimeChairmanTarget::ConditionTrueChairman => {
            if condition_context.matching_chairman_profile_ids.is_empty() {
                Err("target requires chairman condition-evaluation context".to_string())
            } else {
                Ok(condition_context
                    .matching_chairman_profile_ids
                    .iter()
                    .copied()
                    .collect())
            }
        }
    }
}

pub(in crate::engine) fn chairman_profile_matches_company_controller_kind(
    state: &RuntimeState,
    profile: &RuntimeChairmanProfile,
    controller_kind: RuntimeCompanyControllerKind,
) -> bool {
    profile.active
        && profile
            .linked_company_id
            .and_then(|company_id| {
                state
                    .companies
                    .iter()
                    .find(|company| company.company_id == company_id)
            })
            .is_some_and(|company| company.controller_kind == controller_kind)
}
