//! Chat message types for client-side state management.

use serde::{Deserialize, Serialize};
use std::collections::VecDeque;
use uuid::Uuid;

/// Maximum messages to keep in the local log.
pub const MAX_MESSAGE_LOG_SIZE: usize = 2000;

/// Default speech bubble timeout in milliseconds.
pub const DEFAULT_BUBBLE_TIMEOUT_MS: i64 = 60_000;

/// A chat message for display and logging.
/// Note: Guests are now regular users with the 'guest' tag, so all messages have a user_id.
/// System messages use Uuid::nil() as the user_id.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ChatMessage {
    pub message_id: Uuid,
    pub user_id: Uuid,
    pub display_name: String,
    pub content: String,
    /// Emotion name (e.g., "happy", "sad", "neutral").
    pub emotion: String,
    pub x: f64,
    pub y: f64,
    /// Timestamp in milliseconds since epoch.
    pub timestamp: i64,
    /// Whether this is a whisper (direct message).
    #[serde(default)]
    pub is_whisper: bool,
    /// Whether sender is in the same scene as recipient.
    /// For whispers: true = same scene (show as bubble), false = cross-scene (show as notification).
    #[serde(default = "default_true")]
    pub is_same_scene: bool,
    /// Whether this is a system/admin message (teleport, summon, mod commands).
    #[serde(default)]
    pub is_system: bool,
}

/// Default function for serde that returns true.
fn default_true() -> bool {
    true
}

/// Message log with bounded capacity for future replay support.
#[derive(Debug, Clone, Default)]
pub struct MessageLog {
    messages: VecDeque<ChatMessage>,
}

impl MessageLog {
    pub fn new() -> Self {
        Self {
            messages: VecDeque::with_capacity(MAX_MESSAGE_LOG_SIZE),
        }
    }

    pub fn push(&mut self, msg: ChatMessage) {
        if self.messages.len() >= MAX_MESSAGE_LOG_SIZE {
            self.messages.pop_front();
        }
        self.messages.push_back(msg);
    }

    /// Get messages within a time range (for replay).
    pub fn messages_in_range(&self, start_ms: i64, end_ms: i64) -> Vec<&ChatMessage> {
        self.messages
            .iter()
            .filter(|m| m.timestamp >= start_ms && m.timestamp <= end_ms)
            .collect()
    }

    /// Get the latest message from a specific user.
    pub fn latest_from_user(&self, user_id: Uuid) -> Option<&ChatMessage> {
        self.messages.iter().rev().find(|m| m.user_id == user_id)
    }

    /// Get all messages.
    pub fn all_messages(&self) -> &VecDeque<ChatMessage> {
        &self.messages
    }
}

/// Active speech bubble state for a user.
#[derive(Debug, Clone, PartialEq)]
pub struct ActiveBubble {
    pub message: ChatMessage,
    /// When the bubble should expire (milliseconds since epoch).
    pub expires_at: i64,
}

/// Get bubble colors based on emotion name.
/// Returns (background_color, border_color, text_color).
pub fn emotion_bubble_colors(emotion: &str) -> (&'static str, &'static str, &'static str) {
    match emotion {
        "neutral" => ("#374151", "#4B5563", "#F9FAFB"), // gray
        "happy" => ("#FBBF24", "#F59E0B", "#1F2937"),   // amber
        "sad" => ("#3B82F6", "#2563EB", "#F9FAFB"),     // blue
        "angry" => ("#EF4444", "#DC2626", "#F9FAFB"),   // red
        "surprised" => ("#A855F7", "#9333EA", "#F9FAFB"), // purple
        "thinking" => ("#6366F1", "#4F46E5", "#F9FAFB"), // indigo
        "laughing" => ("#FBBF24", "#F59E0B", "#1F2937"), // amber
        "crying" => ("#3B82F6", "#2563EB", "#F9FAFB"),  // blue
        "love" => ("#EC4899", "#DB2777", "#F9FAFB"),    // pink
        "confused" => ("#8B5CF6", "#7C3AED", "#F9FAFB"), // violet
        "sleeping" => ("#1F2937", "#374151", "#9CA3AF"), // dark gray
        "wink" => ("#10B981", "#059669", "#F9FAFB"),    // emerald
        _ => ("#374151", "#4B5563", "#F9FAFB"),         // default - gray
    }
}
