use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

use crate::event::{UserInfo, WorkspaceInfo};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum PresenceEventType {
    Changed,
    CustomStatusUpdated,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum UserPresenceStatus {
    Online,
    Idle,
    Dnd,
    Offline,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum PresenceEvent {
    #[serde(rename = "presence.changed")]
    Changed(PresenceChangedService),
    #[serde(rename = "presence.custom_status_updated")]
    CustomStatusUpdated(CustomStatusUpdatedService),
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PresenceChangedService {
    pub user: UserInfo,
    #[serde(rename = "workspace")]
    pub project: Option<WorkspaceInfo>,
    pub status: UserPresenceStatus,
    pub last_seen_at: Option<DateTime<Utc>>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CustomStatusUpdatedService {
    pub user: UserInfo,
    pub emoji: Option<String>,
    pub text: Option<String>,
    pub expires_at: Option<DateTime<Utc>>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PresenceUpdateClient {
    pub status: UserPresenceStatus,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CustomStatusUpdateClient {
    pub emoji: Option<String>,
    pub text: Option<String>,
    pub expires_at: Option<DateTime<Utc>>,
}
