import Sugar from 'sugar'

export {}

// Enum with String values "Group" and "Private"
export enum ChatType {
  Group = 'Group',
  Private = 'Private',
}

export type Participant = {
  id: number
  name: string
}

export type ChatAttachment = {
  id: number
  name: string
  type: 'Image' | 'Video'
  url: string
}

export type ChatMessage = {
  id: number
  timestamp: string
  author: Participant
  content: string
  read?: boolean
  draft?: boolean
  chatId?: number

  attachments: ChatAttachment[]
}

export type Chat = {
  id: number
  name: string
  type: ChatType
  participants: Participant[]
  lastMessage: ChatMessage
  lastRead: number
  unread: number
}

export const showNotification = (message: string) => {
  const notification = new Notification('Chat', {
    body: message,
  })
}

export const getChatName = (chat: Chat, loggedInUserId: number): string => {
  switch (chat.type) {
    case ChatType.Group:
      return chat.name || `Group ${chat.id}`
    case ChatType.Private:
      return (
        chat.participants.find(p => p.id !== loggedInUserId)?.name ||
        'Unknown user'
      )
  }
}

export const getFileType = (file: File): 'Image' | 'Video' | 'File' => {
  if (file.type.startsWith('image')) {
    return 'Image'
  }

  if (file.type.startsWith('video')) {
    return 'Video'
  }

  return 'File'
}

/**
 * Format a timestamp to display dates in chats
 * @param timestamp Timestamp like "2021-03-01T12:00:00.000Z"
 * @returns String to display in the chat frontend
 */
export const formatChatMessageDate = (
  timestamp: string,
  includeTime = true,
) => {
  const date = Sugar.Date.create(timestamp, { fromUTC: true })
  const formattedTime = includeTime
    ? Sugar.Date.format(date, '{hh}:{mm}{tt}')
    : ''
  let formattedDate: string

  if (Sugar.Date.isToday(date)) {
    return Sugar.Date.format(date, '{hh}:{mm}{tt}')
  }

  if (Sugar.Date.isYesterday(date)) {
    formattedDate = 'Yesterday'
  } else if (Sugar.Date.isThisYear(date)) {
    formattedDate = Sugar.Date.format(date, '{dd} {Mon}')
  } else {
    formattedDate = Sugar.Date.format(date, '{Mon} {dd} {yyyy}')
  }

  if (includeTime) {
    return `${formattedDate} ${formattedTime}`
  }

  return formattedDate
}

export type ChatCreationFormType = {
  type: ChatType
  /** Only for ChatType.Private */
  userId?: number
  /** Only for ChatType.Group */
  name?: string
}

export type ChatAddParticipantFormType = {
  userId: number
}

export type ChatAttachmentForm = {
  type: 'Image' | 'Video' | 'File'
  copyUrl?: string
  name?: string
  sendAsFile?: boolean

  file: File
}

export type ChatAttachmentResponse = {
  attachmentId: number
  contentType: string
  mediaType: string
  uploadUrl: string
}

export type SendMessageEvent = {
  content: string
  chatId: number
  attachments?: ChatAttachmentForm[]
}

/**
 * @method GET - Get all chats
 */
export const ALL_CHATS_ENDPOINT = '/dashboard/api/v1/chats'

/**
 * @method POST - Create a new chat
 * @returns {Chat} Chat - Chat objet
 */
export const CREATE_CHAT_ENDPOINT = '/dashboard/api/v1/chat'

/**
 * @method GET - Get a single chat
 * @param chatId ID of the chat
 * @returns {Chat} Chat - Chat object
 */
export const GET_SINGLE_CHAT_ENDPOINT = (chatId: number): string =>
  `/dashboard/api/v1/chat/${chatId}`

/**
 * @method PUT - Update a chat
 * @param chatId ID of the chat
 * @returns {Chat} Chat - Chat object
 */
export const UPDATE_CHAT_ENDPOINT = (chatId: number): string =>
  `/dashboard/api/v1/chat/${chatId}`

/**
 * @method DELETE - Delete a chat
 * @param chatId ID of the chat
 * @returns {Chat} Chat - Chat object
 */
export const DELETE_CHAT_ENDPOINT = (chatId: number): string =>
  `/dashboard/api/v1/chat/${chatId}`

/**
 * @method GET - Get all messages in a chat
 * @param chatId ID of the chat
 * @returns {ChatMessage[]} ChatMessages - Array of chat messages
 */
export const GET_ALL_MESSAGES_IN_CHAT_ENDPOINT = (
  chatId: number,
  page = 0,
  order = 'Desc',
): string =>
  `/dashboard/api/v1/chat/${chatId}/messages?page=${page}&order=${order}`

/**
 * @method POST - Create a new message in a chat
 * @param chatId ID of the chat
 * @returns {ChatMessage} ChatMessage - Chat message object
 * @bodyParam {string} text - Text of the message
 */
export const CREATE_MESSAGE_IN_CHAT_ENDPOINT = (chatId: number): string =>
  `/dashboard/api/v1/chat/${chatId}/message`

/**
 * @method POST - Create an attachment to a message draft
 * @param chatId ID of the chat
 * @param messageId ID of the message to attach to
 * @returns {AttachmentResponse} ChatMessage - Chat message object
 * @bodyParam {'Image' | 'Video'} type - Attachment type
 * @bodyParam {string?} copyUrl - Resource URL to copy from
 * @bodyParam {string?} name - Name of the file
 */
export const CREATE_ATTACHMENT_IN_CHAT_ENDPOINT = (
  chatId: number,
  messageId: number,
): string => `/dashboard/api/v1/chat/${chatId}/message/${messageId}/attachments`

/**
 * @Method POST - Send a message
 * @param chatId ID of the chat
 * @param messageId ID of the message to send
 * @returns {void}
 */
export const SEND_MESSAGE_ENDPOINT = (
  chatId: number,
  messageId: number,
): string => `/dashboard/api/v1/chat/${chatId}/message/${messageId}/send`

/**
 * @method POST - Add a participant to a chat
 * @param chatId ID of the chat
 * @returns {Participant} Participant - Participant object
 */
export const ADD_PARTICIPANT_TO_CHAT_ENDPOINT = (chatId: number): string =>
  `/dashboard/api/v1/chat/${chatId}/participant`

/**
 * @method DELETE - Remove a participant from a chat
 * @param chatId ID of the chat
 * @requestParam {number} userId - ID of the user to remove
 * @returns {null}
 */
export const REMOVE_PARTICIPANT_FROM_CHAT_ENDPOINT = (
  chatId: number,
  userId: number,
): string => `/dashboard/api/v1/chat/${chatId}/participant?userId=${userId}`

declare global {}
