//! The Notification plugin syncs notifications between devices.
use serde::{Deserialize, Serialize};

#[cfg(not(feature = "std"))]
use alloc::{string::String, vec::Vec};

/// A message sent in the conversation.
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct NotificationMessage {
    /// The name of the person who sent the message.
    pub sender: String,

    /// The content of the message.
    pub content: String,
}

/// This packet is a notification.
///
/// <https://invent.kde.org/network/kdeconnect-meta/blob/master/protocol.md#kdeconnectnotification>
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct NotificationPacket {
    /// The notification ID.
    pub id: String,

    /// If true the notification with the indicated ID has been closed.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub is_cancel: Option<bool>,

    /// If true the notification with the indicated ID can be closed.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub is_clearable: Option<bool>,

    /// If true the notification is preexisting, otherwise the remote device just received it.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub silent: Option<bool>,

    /// A UNIX epoch timestamp (ms) in string form.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub time: Option<String>,

    /// The notifying application name.
    pub app_name: String,

    /// The notification title and text in a single string.
    pub ticker: String,

    /// The notification title.
    pub title: String,

    /// The notification body.
    pub text: String,

    /// The group name if the notification is a conversation message coming from a group.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub group_name: Option<String>,

    /// An MD5 hash of the notification icon. If the packet contains this field, it will be accompanied by payload transfer information.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub payload_hash: Option<String>,

    /// A list of messages in the notification if it's a conversation.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub conversation: Option<Vec<NotificationMessage>>,

    /// A list of action names for the notification. Respond with kdeconnect.notification.action to activate.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub actions: Option<Vec<String>>,

    /// The UUID for repliable notifications (eg. chat). Respond with kdeconnect.notification.reply to reply.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub request_reply_id: Option<String>,
}

/// This packet is an activation of a notification action.
///
/// <https://invent.kde.org/network/kdeconnect-meta/blob/master/protocol.md#kdeconnectnotificationaction>
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct NotificationActionPacket {
    /// The notification ID.
    pub key: String,

    /// The notification action name.
    pub action: String,
}

/// This packet is a reply for a repliable notification.
///
/// <https://invent.kde.org/network/kdeconnect-meta/blob/master/protocol.md#kdeconnectnotificationreply>
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct NotificationReplyPacket {
    /// The message to reply with.
    pub message: String,

    /// The reply ID of the notification.
    pub request_reply_id: String,
}

/// This packet is a request for notifications.
///
/// <https://invent.kde.org/network/kdeconnect-meta/blob/master/protocol.md#kdeconnectnotificationrequest>
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct NotificationRequestPacket {
    /// If present, holds the ID of a notification that should be closed.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub cancel: Option<bool>,

    /// Indicates this is a request for the notifications.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub request: Option<bool>,
}
