use std::collections::BTreeSet;

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

use super::shared;

pub(in crate::engine) fn resolve_company_target_ids(
    state: &RuntimeState,
    target: &RuntimeCompanyTarget,
    condition_context: &ResolvedConditionContext,
) -> Result<Vec<u32>, String> {
    match target {
        RuntimeCompanyTarget::AllActive => Ok(state
            .companies
            .iter()
            .filter(|company| company.active)
            .map(|company| company.company_id)
            .collect()),
        RuntimeCompanyTarget::Ids { ids } => {
            let known_ids = state
                .companies
                .iter()
                .map(|company| company.company_id)
                .collect::<BTreeSet<_>>();
            shared::validate_known_ids(ids, &known_ids, |company_id| {
                format!("target references unknown company_id {company_id}")
            })?;
            Ok(ids.clone())
        }
        RuntimeCompanyTarget::HumanCompanies => {
            shared::ensure_no_unknown_company_controller_kinds(
                &state.companies,
                "target requires company role context but at least one company has unknown controller_kind",
            )?;
            Ok(state
                .companies
                .iter()
                .filter(|company| {
                    company.active && company.controller_kind == RuntimeCompanyControllerKind::Human
                })
                .map(|company| company.company_id)
                .collect())
        }
        RuntimeCompanyTarget::AiCompanies => {
            shared::ensure_no_unknown_company_controller_kinds(
                &state.companies,
                "target requires company role context but at least one company has unknown controller_kind",
            )?;
            Ok(state
                .companies
                .iter()
                .filter(|company| {
                    company.active && company.controller_kind == RuntimeCompanyControllerKind::Ai
                })
                .map(|company| company.company_id)
                .collect())
        }
        RuntimeCompanyTarget::SelectedCompany => {
            let selected_company_id = state
                .selected_company_id
                .ok_or_else(|| "target requires selected_company_id context".to_string())?;
            if state
                .companies
                .iter()
                .any(|company| company.company_id == selected_company_id && company.active)
            {
                Ok(vec![selected_company_id])
            } else {
                Err(
                    "target requires selected_company_id to reference an active company"
                        .to_string(),
                )
            }
        }
        RuntimeCompanyTarget::ConditionTrueCompany => {
            if condition_context.matching_company_ids.is_empty() {
                Err("target requires condition-evaluation context".to_string())
            } else {
                Ok(condition_context
                    .matching_company_ids
                    .iter()
                    .copied()
                    .collect())
            }
        }
    }
}
