//! Demo bot — deterministic, predictable action ordering for QA / mechanic testing.
//!
//! Selects actions by priority tier so that the opponent reliably demonstrates
//! all Phase-4 mechanics when given the matching test deck:
//!
//!   UseAbility (4) > PlayCardOverload (3) > PlayCard (2) > Attack (1) > EndTurn (0)
//!
//! Within a tier, picks randomly (seeded) to avoid degenerate loops.
//! Never listed in the normal bot picker — only used by Test Lab scenarios.

use rand::rngs::SmallRng;
use rand::{Rng, SeedableRng};

use crate::actions::Action;
use crate::bots::Bot;
use crate::tensor::STATE_TENSOR_SIZE;

/// A bot that selects actions by a fixed priority order.
///
/// Designed for QA use: always activates abilities (Prepare/Ambush),
/// uses Overload when available, plays cards (Ritual/Level-Up/Flanking),
/// and attacks — ensuring every Phase-4 mechanic is exercised.
#[derive(Clone)]
pub struct DemoBot {
    name: String,
    rng: SmallRng,
    seed: u64,
}

impl DemoBot {
    pub fn new(seed: u64) -> Self {
        Self {
            name: "DemoBot".to_string(),
            rng: SmallRng::seed_from_u64(seed),
            seed,
        }
    }

    fn priority(action: &Action) -> i32 {
        match action {
            Action::UseAbility { .. }       => 4,
            Action::PlayCardOverload { .. } => 3,
            Action::PlayCard { .. }         => 2,
            Action::Attack { .. }           => 1,
            Action::EndTurn                 => 0,
            _                               => -1,
        }
    }
}

impl Bot for DemoBot {
    fn name(&self) -> &str {
        &self.name
    }

    fn select_action(
        &mut self,
        _state_tensor: &[f32; STATE_TENSOR_SIZE],
        _legal_mask: &[f32; Action::ACTION_SPACE_SIZE],
        legal_actions: &[Action],
    ) -> Action {
        // Find the highest priority tier present.
        let best_priority = legal_actions
            .iter()
            .map(Self::priority)
            .max()
            .unwrap_or(0);

        // Collect all actions in that tier.
        let candidates: Vec<&Action> = legal_actions
            .iter()
            .filter(|a| Self::priority(a) == best_priority)
            .collect();

        // Pick randomly within the tier for variety.
        let idx = self.rng.gen_range(0..candidates.len());
        *candidates[idx]
    }

    fn reset(&mut self) {
        self.rng = SmallRng::seed_from_u64(self.seed);
    }

    fn clone_box(&self) -> Box<dyn Bot> {
        Box::new(self.clone())
    }
}
