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 WorkspaceEventType {
    RoomCreated,
    RoomDeleted,
    RoomRenamed,
    RoomMoved,
    RepoCreated,
    RepoUpdated,
    RepoDeleted,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum WorkspaceEvent {
    #[serde(rename = "workspace.room_created")]
    RoomCreated(WorkspaceRoomCreatedService),
    #[serde(rename = "workspace.room_deleted")]
    RoomDeleted(WorkspaceRoomDeletedService),
    #[serde(rename = "workspace.room_renamed")]
    RoomRenamed(WorkspaceRoomRenamedService),
    #[serde(rename = "workspace.room_moved")]
    RoomMoved(WorkspaceRoomMovedService),
    #[serde(rename = "workspace.repo_created")]
    RepoCreated(WorkspaceRepoCreatedService),
    #[serde(rename = "workspace.repo_updated")]
    RepoUpdated(WorkspaceRepoUpdatedService),
    #[serde(rename = "workspace.repo_deleted")]
    RepoDeleted(WorkspaceRepoDeletedService),
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorkspaceRoomCreatedService {
    pub workspace: WorkspaceInfo,
    pub room: RoomInfo,
    pub public: bool,
    pub category: Option<Uuid>,
    pub created_by: UserInfo,
    pub created_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorkspaceRoomDeletedService {
    pub workspace: WorkspaceInfo,
    pub room: RoomInfo,
    pub deleted_by: UserInfo,
    pub deleted_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorkspaceRoomRenamedService {
    pub workspace: WorkspaceInfo,
    pub room: RoomInfo,
    pub old_name: String,
    pub new_name: String,
    pub renamed_by: UserInfo,
    pub renamed_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorkspaceRoomMovedService {
    pub workspace: WorkspaceInfo,
    pub room: RoomInfo,
    pub old_category: Option<Uuid>,
    pub new_category: Option<Uuid>,
    pub moved_by: UserInfo,
    pub moved_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorkspaceRepoCreatedService {
    pub workspace: WorkspaceInfo,
    pub repo: Uuid,
    pub repo_name: String,
    pub created_by: UserInfo,
    pub created_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorkspaceRepoUpdatedService {
    pub workspace: WorkspaceInfo,
    pub repo: Uuid,
    pub updated_by: UserInfo,
    pub updated_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorkspaceRepoDeletedService {
    pub workspace: WorkspaceInfo,
    pub repo: Uuid,
    pub deleted_by: UserInfo,
    pub deleted_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorkspaceRoomCreateClient {
    pub workspace: Uuid,
    pub room_name: String,
    pub public: bool,
    pub category: Option<Uuid>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorkspaceRoomUpdateClient {
    pub room: Uuid,
    pub room_name: Option<String>,
    pub public: Option<bool>,
    pub category: Option<Uuid>,
}

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