use serde::{Deserialize, Serialize};
use uuid::Uuid;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChannelEnvelope<T> {
    #[serde(default = "uuid::Uuid::now_v7")]
    pub message_id: Uuid,
    pub user_id: Uuid,
    pub payload: T,
    #[serde(default = "default_timestamp")]
    pub created_at: chrono::DateTime<chrono::Utc>,
    #[serde(default)]
    pub attempt: u8,
}

fn default_timestamp() -> chrono::DateTime<chrono::Utc> {
    chrono::Utc::now()
}

impl<T> ChannelEnvelope<T> {
    pub fn new(user_id: Uuid, payload: T) -> Self {
        Self {
            message_id: Uuid::now_v7(),
            user_id,
            payload,
            created_at: chrono::Utc::now(),
            attempt: 1,
        }
    }

    pub fn retry(self) -> Self {
        Self {
            attempt: self.attempt + 1,
            ..self
        }
    }
}
