use chrono::Utc;
use uuid::Uuid;

use crate::event::{RoomInfo, UserInfo, draft};
use crate::{ChannelBus, ChannelError, ChannelResult};

use super::MAX_TEXT_LEN;
use super::WsHandler;
use super::WsOutEvent;

impl WsHandler {
    pub(super) async fn draft_save(
        bus: &ChannelBus,
        user_id: Uuid,
        room: Uuid,
        content: String,
    ) -> ChannelResult<Option<WsOutEvent>> {
        Self::ensure_room_access(bus, user_id, room).await?;
        if content.len() > MAX_TEXT_LEN {
            return Err(ChannelError::Validation("draft too long".into()));
        }
        let key = format!("draft:{}:{}", user_id, room);
        bus.inner.cache.set(&key, &content).await?;
        let ds_room = bus
            .lookup_room(room)
            .await
            .unwrap_or_else(|_| RoomInfo::unknown(room));
        let ds_user = bus
            .lookup_user(user_id)
            .await
            .unwrap_or_else(|_| UserInfo::unknown(user_id));
        let data = draft::DraftSavedService {
            user: ds_user,
            room: ds_room,
            content,
            saved_at: Utc::now(),
        };
        Ok(Some(WsOutEvent::DraftSaved {
            room: data.room.clone(),
            data,
        }))
    }

    pub(super) async fn draft_clear(
        bus: &ChannelBus,
        user_id: Uuid,
        room: Uuid,
    ) -> ChannelResult<Option<WsOutEvent>> {
        Self::ensure_room_access(bus, user_id, room).await?;
        let key = format!("draft:{}:{}", user_id, room);
        bus.inner.cache.remove(&key).await?;
        let dc_room = bus
            .lookup_room(room)
            .await
            .unwrap_or_else(|_| RoomInfo::unknown(room));
        let dc_user = bus
            .lookup_user(user_id)
            .await
            .unwrap_or_else(|_| UserInfo::unknown(user_id));
        let data = draft::DraftClearedService {
            user: dc_user,
            room: dc_room,
            cleared_at: Utc::now(),
        };
        Ok(Some(WsOutEvent::DraftCleared {
            room: data.room.clone(),
            data,
        }))
    }
}
