import { sendToGateway, checkGatewayStatus, queryHandoverStatus, sendStartHandover, queryConversationIds } from '../api'
import { ISdk, IMessage } from '../interfaces'

export class HandoverClient implements ISdk {

  private jwt: string
  private backendUrl: string

  constructor (jwt: string, backendUrl: string) {
    if (!jwt || !backendUrl) {
      throw new Error('Please provide jwt token and backend url.')
    }
    this.jwt = jwt
    this.backendUrl = backendUrl
  }

  static buildMessage (role: string, type: string): IMessage {
    return {
      role,
      type
    }
  }

  static async callGateway (jwt: string, backendUrl: string, data: any) {
    const result = await sendToGateway(jwt, backendUrl, data)
    if (!result.success) {
      throw new Error(result.message)
    }
  }

  public async sendMessage (userId: string, message: any): Promise<any> {
    let messageData = HandoverClient.buildMessage(message.role, 'text')
    messageData.text = message.text
    if (message.actions) messageData.actions = message.actions
    if (message.nlpData) messageData.nlpData = message.nlpData
    const data = {
      userId,
      source: message.source,
      message: messageData
    }
    await HandoverClient.callGateway(this.jwt, this.backendUrl, data)
  }

  public async sendFile (userId: string, file: any, type: string): Promise<any> {
    let messageData = HandoverClient.buildMessage(file.role, type)
    messageData.mediaUrl = file.mediaUrl
    if (file.mediaType) messageData.mediaType = file.mediaType
    if (file.nlpData) messageData.nlpData = file.nlpData
    const data = {
      userId,
      source: file.source,
      message: messageData
    }
    await HandoverClient.callGateway(this.jwt, this.backendUrl, data)
  }

  public async sendCarousel (userId: string, carousel: any): Promise<any> {
    let messageData = HandoverClient.buildMessage(carousel.role, 'carousel')
    messageData.items = carousel.items
    if (carousel.nlpData) messageData.nlpData = carousel.nlpData
    const data = {
      userId,
      source: carousel.source,
      message: messageData
    }
    await HandoverClient.callGateway(this.jwt, this.backendUrl, data)
  }

  public async sendLocation (userId: string, location: any): Promise<any> {
    let messageData = HandoverClient.buildMessage(location.role, 'location')
    messageData.coordinates = location.coordinates
    if (location.nlpData) messageData.nlpData = location.nlpData
    const data = {
      userId,
      source: location.source,
      message: messageData
    }
    await HandoverClient.callGateway(this.jwt, this.backendUrl, data)
  }

  public async getOnlineAgents (): Promise<any> {
    const users = await checkGatewayStatus(this.jwt, this.backendUrl)
    if (!users.success) {
      throw new Error(users.message)
    }
    return users
  }

  public async getAllConversationIds (): Promise<any> {
    const conversationIdsRes = await queryConversationIds(this.jwt, this.backendUrl)
    if (!conversationIdsRes.success) {
      throw new Error(conversationIdsRes.message)
    }
    return conversationIdsRes.data
  }

  public async getHandoverStatus (userId: string): Promise<any> {
    const handoverRes = await queryHandoverStatus(this.jwt, this.backendUrl, userId)
    if (!handoverRes.success) {
      throw new Error(handoverRes.message)
    }
    return handoverRes.data
  }

  public async startHandover (userId: string): Promise<any> {
    const response = await sendStartHandover(this.jwt, this.backendUrl, userId)
    if (!response.success) {
      throw new Error(response.message)
    }
    return response.data
  }
}
