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

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

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ConversationEventType {
    Pinned,
    Unpinned,
    Muted,
    Unmuted,
    UnreadUpdated,
    NotifyLevelChanged,
}

impl ConversationEventType {
    pub fn as_str(&self) -> &str {
        match self {
            Self::Pinned => "conversation.pinned",
            Self::Unpinned => "conversation.unpinned",
            Self::Muted => "conversation.muted",
            Self::Unmuted => "conversation.unmuted",
            Self::UnreadUpdated => "conversation.unread_updated",
            Self::NotifyLevelChanged => "conversation.notify_level_changed",
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum ConversationEvent {
    #[serde(rename = "conversation.pinned")]
    Pinned(ConversationPinnedService),
    #[serde(rename = "conversation.unpinned")]
    Unpinned(ConversationUnpinnedService),
    #[serde(rename = "conversation.muted")]
    Muted(ConversationMutedService),
    #[serde(rename = "conversation.unmuted")]
    Unmuted(ConversationUnmutedService),
    #[serde(rename = "conversation.unread_updated")]
    UnreadUpdated(ConversationUnreadUpdatedService),
    #[serde(rename = "conversation.notify_level_changed")]
    NotifyLevelChanged(ConversationNotifyLevelChangedService),
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConversationPinnedService {
    pub user: UserInfo,
    pub room: RoomInfo,
    pub pinned_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConversationUnpinnedService {
    pub user: UserInfo,
    pub room: RoomInfo,
    pub unpinned_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConversationMutedService {
    pub user: UserInfo,
    pub room: RoomInfo,
    pub muted_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConversationUnmutedService {
    pub user: UserInfo,
    pub room: RoomInfo,
    pub unmuted_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConversationUnreadUpdatedService {
    pub user: UserInfo,
    pub room: RoomInfo,
    pub last_read_seq: i64,
    pub unread_count: i64,
    pub updated_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConversationNotifyLevelChangedService {
    pub user: UserInfo,
    pub room: RoomInfo,
    pub old_level: String,
    pub new_level: String,
    pub updated_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConversationPinClient {
    pub room: Uuid,
    pub pin: bool,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConversationMuteClient {
    pub room: Uuid,
    pub mute: bool,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConversationNotifyLevelClient {
    pub room: Uuid,
    pub notify_level: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConversationSummary {
    pub room: Uuid,
    pub room_name: String,
    pub room_type: String,
    pub is_pinned: bool,
    pub is_muted: bool,
    pub notify_level: String,
    pub last_read_seq: i64,
    pub max_seq: i64,
    pub unread_count: i64,
    pub last_read_at: Option<DateTime<Utc>>,
}
