use serde::{Deserialize, Serialize};

use super::entry::ActionDefinition;


#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct ChatMessage {
    /// message text, `{item}` can be used to refer to items and such, where item is of the path such as `items/sword` or `spells/fireball`
    pub text: String,
    /// Source user initiated the action/sent the message
    #[serde(default = "default_source")]
    pub source: String,
    /// Character "sending" the message
    pub character: Option<String>,
    /// whisper item
    pub whisper: Option<String>,
    /// If the originating action had a dice roll with a DC (or similar), an option to show if the action roll succeeded
    pub success: Option<bool>,
    /// Optional action buttons, for a chat message this will be empty
    pub actions: Option<Vec<ActionDefinition>>,
    /// Targets of the action, for a chat message this will be empty
    pub targets: Option<Vec<String>>,
    /// message id, should be left emitted or 0 for new messages
    #[serde(default = "default_id")]
    pub id: usize,
}
fn default_source() -> String {
    String::new()
}

impl ChatMessage {
    /// Creates a new chat message with a given text and source
    pub fn new(text: String) -> Self {
        Self {
            text, ..Default::default()
        }
    }
    pub fn character(mut self, character: Option<String>) -> Self {
        self.character = character;
        self
    }
    pub fn source(mut self, source: String) -> Self {
        self.source = source;
        self
    }
    /// sets the whisper value of the message
    pub fn whisper(mut self, whisper: Option<String>) -> Self {
        self.whisper = whisper;
        self
    }
    /// sets the roll value for the message (chaining multiple will override each other) 
    pub fn success(mut self, success: Option<bool>) -> Self {
        self.success = success;
        self
    }
    /// sets the actions value (chaining multiple will override)
    pub fn actions(mut self, actions: Option<Vec<ActionDefinition>>) -> Self {
        self.actions = actions;
        self
    }
    /// adds a single action to the message (chaining  multiple will add multiple actions)
    pub fn with_action(mut self, action: ActionDefinition) -> Self {
        if let Some(acts) = &mut self.actions {
            acts.push(action);
        }
        else {
            self.actions = Some(vec![action]);
        }
        self
    }
    /// sets the targets value (chaining multiple will override)
    pub fn targets(mut self, targets: Option<Vec<String>>) -> Self {
        self.targets = targets;
        self
    }
    /// adds a single target to the message (chaining  multiple will add multiple targets)
    pub fn with_target(mut self, target: String) -> Self {
        if let Some(targets) = &mut self.targets {
            targets.push(target);
        }
        else {
            self.targets = Some(vec![target]);
        }
        self
    }
    /// Sets the message id
    /// 
    /// WARNING: duplicate message id will cause an overwrite of the original message (and an edit at the client)
    pub fn id(mut self, id: usize) -> Self {
        self.id = id;
        self
    }
    
}

fn default_id() -> usize { 0 }