//! Commander-specific type definitions.
//!
//! Covers factions, commander passives and triggered abilities, and `CommanderDefinition`.

use serde::{Deserialize, Serialize};
use crate::core::types::Rarity;
use super::card_types::EffectDefinition;

// =============================================================================
// Faction
// =============================================================================

/// Faction for commanders and cards
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Faction {
    Argentum,
    Symbiote,
    Obsidion,
    Neutral,
}

// =============================================================================
// Commander Passive Abilities
// =============================================================================

/// Effect type for commander passive abilities
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum CommanderPassiveEffect {
    /// Grant a keyword to all friendly creatures
    GrantKeyword { keyword: String },
    /// Grant multiple keywords to all friendly creatures
    GrantKeywords { keywords: Vec<String> },
    /// Buff stats of all friendly creatures
    BuffStats { attack: i8, health: i8 },
    /// Grant a keyword AND buff stats (combined effect)
    GrantKeywordAndBuff {
        keyword: String,
        attack: i8,
        health: i8,
    },
    /// Buff stats only for creatures that have a specific keyword
    BuffStatsIfKeyword {
        required_keyword: String,
        attack: i8,
        health: i8,
    },
    /// Grant a keyword only to creatures that have another specific keyword
    GrantKeywordIfKeyword {
        required_keyword: String,
        granted_keyword: String,
    },
}

/// Commander passive ability (always active)
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct CommanderPassiveAbility {
    pub description: String,
    pub effect: CommanderPassiveEffect,
}

// =============================================================================
// Commander Triggered Abilities
// =============================================================================

/// Trigger condition for commander triggered abilities
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub struct CommanderTriggerCondition {
    /// Creature must have this keyword
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub has_keyword: Option<String>,
}

/// Commander trigger types (some are new, some reuse existing)
#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)]
#[serde(rename_all = "PascalCase")]
pub enum CommanderTrigger {
    /// At the start of owner's turn
    StartOfTurn,
    /// When owner plays a creature
    OnCreaturePlayed,
    /// When a friendly creature dies
    OnAllyDeath,
    /// When an enemy creature dies
    OnEnemyDeath,
    /// When a friendly creature attacks
    OnAttack,
    /// When any creature dies (ally or enemy)
    OnAnyDeath,
    /// When a friendly creature kills an enemy creature
    OnKill,
}

/// Commander triggered ability
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct CommanderTriggeredAbility {
    pub trigger: CommanderTrigger,
    pub description: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub condition: Option<CommanderTriggerCondition>,
    pub effects: Vec<EffectDefinition>,
}

// =============================================================================
// CommanderDefinition & CommanderSet
// =============================================================================

/// Complete definition of a commander
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct CommanderDefinition {
    pub id: u16,
    pub name: String,
    pub faction: Faction,
    #[serde(default)]
    pub rarity: Rarity,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub passive_ability: Option<CommanderPassiveAbility>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub triggered_ability: Option<CommanderTriggeredAbility>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub flavor: Option<String>,
}

impl CommanderDefinition {
    /// Get the passive ability if this commander has one
    pub fn passive(&self) -> Option<&CommanderPassiveAbility> {
        self.passive_ability.as_ref()
    }

    /// Get the triggered ability if this commander has one
    pub fn triggered(&self) -> Option<&CommanderTriggeredAbility> {
        self.triggered_ability.as_ref()
    }

    /// Check if this commander has a passive ability
    pub fn has_passive(&self) -> bool {
        self.passive_ability.is_some()
    }

    /// Check if this commander has a triggered ability
    pub fn has_triggered(&self) -> bool {
        self.triggered_ability.is_some()
    }

    /// Get the description of all abilities
    pub fn ability_description(&self) -> String {
        let mut parts = Vec::new();
        if let Some(passive) = &self.passive_ability {
            parts.push(passive.description.clone());
        }
        if let Some(triggered) = &self.triggered_ability {
            parts.push(triggered.description.clone());
        }
        parts.join(". ")
    }
}

/// Commander set loaded from YAML (container for multiple commanders)
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct CommanderSet {
    pub commanders: Vec<CommanderDefinition>,
}
