use std::collections::BTreeSet;

use crate::event::targets::{
    RuntimeChairmanTarget, RuntimeCompanyTarget, RuntimePlayerTarget, RuntimeTerritoryTarget,
};

pub(crate) fn validate_company_target(
    target: &RuntimeCompanyTarget,
    valid_company_ids: &BTreeSet<u32>,
) -> Result<(), String> {
    match target {
        RuntimeCompanyTarget::AllActive
        | RuntimeCompanyTarget::HumanCompanies
        | RuntimeCompanyTarget::AiCompanies
        | RuntimeCompanyTarget::SelectedCompany
        | RuntimeCompanyTarget::ConditionTrueCompany => Ok(()),
        RuntimeCompanyTarget::Ids { ids } => {
            if ids.is_empty() {
                return Err("target ids must not be empty".to_string());
            }
            for company_id in ids {
                if !valid_company_ids.contains(company_id) {
                    return Err(format!("target references unknown company_id {company_id}"));
                }
            }
            Ok(())
        }
    }
}

pub(crate) fn validate_player_target(
    target: &RuntimePlayerTarget,
    valid_player_ids: &BTreeSet<u32>,
) -> Result<(), String> {
    match target {
        RuntimePlayerTarget::AllActive
        | RuntimePlayerTarget::HumanPlayers
        | RuntimePlayerTarget::AiPlayers
        | RuntimePlayerTarget::SelectedPlayer
        | RuntimePlayerTarget::ConditionTruePlayer => Ok(()),
        RuntimePlayerTarget::Ids { ids } => {
            if ids.is_empty() {
                return Err("target ids must not be empty".to_string());
            }
            for player_id in ids {
                if !valid_player_ids.contains(player_id) {
                    return Err(format!("target references unknown player_id {player_id}"));
                }
            }
            Ok(())
        }
    }
}

pub(crate) fn validate_chairman_target(
    target: &RuntimeChairmanTarget,
    valid_chairman_profile_ids: &BTreeSet<u32>,
) -> Result<(), String> {
    match target {
        RuntimeChairmanTarget::AllActive
        | RuntimeChairmanTarget::HumanChairmen
        | RuntimeChairmanTarget::AiChairmen
        | RuntimeChairmanTarget::SelectedChairman
        | RuntimeChairmanTarget::ConditionTrueChairman => Ok(()),
        RuntimeChairmanTarget::Ids { ids } => {
            if ids.is_empty() {
                return Err("target ids must not be empty".to_string());
            }
            for profile_id in ids {
                if !valid_chairman_profile_ids.contains(profile_id) {
                    return Err(format!(
                        "target references unknown chairman profile_id {profile_id}"
                    ));
                }
            }
            Ok(())
        }
    }
}

pub(crate) fn validate_territory_target(
    target: &RuntimeTerritoryTarget,
    valid_territory_ids: &BTreeSet<u32>,
) -> Result<(), String> {
    match target {
        RuntimeTerritoryTarget::AllTerritories => Ok(()),
        RuntimeTerritoryTarget::Ids { ids } => {
            if ids.is_empty() {
                return Err("territory target ids must not be empty".to_string());
            }
            for territory_id in ids {
                if !valid_territory_ids.contains(territory_id) {
                    return Err(format!(
                        "territory target references unknown territory_id {territory_id}"
                    ));
                }
            }
            Ok(())
        }
    }
}
