use super::id::Id;
use serde::{Deserialize, Serialize};
use tritools::time::unix_epoch_timestamp;
use serde_valid::Validate;

#[derive(Clone, Debug, Serialize, Deserialize, Default, Validate)]
pub struct GroupSettings {
    #[serde(default)]
    pub require_approval: bool,
    #[validate(min_length = 0)]
    #[validate(max_length = 4096)]
    #[serde(default)]
    pub biography: String,
}

#[derive(Serialize, Deserialize, Clone)]
pub struct Group {
    pub id: Id,
    pub created: u128,
    pub owner: Id,
    pub name: String,
    pub settings: GroupSettings,
    pub members: i32,
}

impl Group {
    /// Create a new [`Group`].
    pub fn new(owner: Id, name: String) -> Self {
        Self {
            id: Id::new(),
            created: unix_epoch_timestamp(),
            owner,
            name,
            settings: GroupSettings::default(),
            members: 0,
        }
    }
}

#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Default)]
pub enum GroupRole {
    Owner,
    #[default]
    Member,
    Banned,
    Pending,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct GroupMembership {
    pub id: Id,
    pub created: u128,
    pub owner: Id,
    pub group: Id,
    pub role: GroupRole,
}

impl GroupMembership {
    /// Create a new [`GroupMembership`].
    pub fn new(owner: Id, group: Id, role: GroupRole) -> Self {
        Self {
            id: Id::new(),
            created: unix_epoch_timestamp(),
            owner,
            group,
            role,
        }
    }

    pub fn owner() -> Self {
        Self {
            id: Id::Legacy(0),
            created: 0,
            owner: Id::Legacy(0),
            group: Id::Legacy(0),
            role: GroupRole::Owner,
        }
    }
}
