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

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

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum InviteEventType {
    Created,
    Accepted,
    Rejected,
    Revoked,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum InviteEvent {
    #[serde(rename = "invite.created")]
    Created(InviteCreatedService),
    #[serde(rename = "invite.accepted")]
    Accepted(InviteAcceptedService),
    #[serde(rename = "invite.rejected")]
    Rejected(InviteRejectedService),
    #[serde(rename = "invite.revoked")]
    Revoked(InviteRevokedService),
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InviteCreatedService {
    pub id: Uuid,
    pub workspace: WorkspaceInfo,
    pub room: Option<RoomInfo>,
    pub inviter: UserInfo,
    pub invitee: Option<UserInfo>,
    pub code: String,
    pub max_uses: Option<i32>,
    pub expires_at: Option<DateTime<Utc>>,
    pub created_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InviteAcceptedService {
    pub id: Uuid,
    pub workspace: WorkspaceInfo,
    pub room: Option<RoomInfo>,
    pub user: UserInfo,
    pub accepted_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InviteRejectedService {
    pub id: Uuid,
    pub workspace: WorkspaceInfo,
    pub user: UserInfo,
    pub rejected_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InviteRevokedService {
    pub id: Uuid,
    pub workspace: WorkspaceInfo,
    pub revoked_by: UserInfo,
    pub revoked_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InviteCreateClient {
    pub workspace: WorkspaceInfo,
    pub room: Option<Uuid>,
    pub max_uses: Option<i32>,
    pub expires_at: Option<DateTime<Utc>>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InviteAcceptClient {
    pub code: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InviteRevokeClient {
    pub id: Uuid,
}
