import { validate } from "super-easy-validator"
import { ISocket, SocketEvent, SocketEventHandler } from "../../utils/types"
import { IUser } from "../users/models"
import services from "../../utils/services"
import { Chat } from "../chats/models"

const messageSockets = {} as Record<SocketEvent, SocketEventHandler>

messageSockets['typing-started'] = async (socket: ISocket, data: Record<string, any>) => {
  await handleTypingUpdateSocketListener(socket, data, 'started')
}

messageSockets['typing-stopped'] = async (socket: ISocket, data: Record<string, any>) => {
  await handleTypingUpdateSocketListener(socket, data, 'stopped')
}

async function handleTypingUpdateSocketListener(socket: ISocket, data: Record<string, any>, type: 'started' | 'stopped') {
  const user = socket.data.user as IUser
  const rule = { chat: 'mongoid' }
  const {errors} = validate(rule, data)
  if(errors) {
    return services.socketErrorNotifyUser(socket, 'validation-failed', {message: errors[0]})
  }
  const chat = await Chat.findById(data.chat)
  if(!chat) {
    return services.socketErrorNotifyUser(socket, 'not-found', {message: 'chat not found'})
  }
  const currentParticipant = chat.participants.find(e => `${e.user}` === `${user._id}`)
  if(!currentParticipant) {
    return services.socketErrorNotifyUser(socket, 'permission-denied', {message: 'permission denied'})
  }
  // notify every participants in this chat (excluding current user) that typing is started/stopped
  const participants = chat.participants
    .map(e => `${e.user}`)
    .filter(e => e !== `${user._id}`)
  for(const participant of participants) {
    const payload = {
      user: {
        _id: `${user._id}`,
        name: user.name,
        username: user.username,
        photo: user.photo,
      },
      chat: `${chat._id}`
    }
    services.socketNotifyUser({
      userId: participant,
      event: type === 'started' ? 'typing-started' : 'typing-stopped',
      data: payload
    })
  }
}

export default messageSockets
