import {
  GetEmailDomainResponse,
  PostEmailDomainRequest,
  PatchEmailDomainRequest,
  PostSendTestEmailRequest
} from 'types/email-domains'
import notification from 'utils/notification'
import { Maybe } from 'yup/lib/types'
import { Api } from './api'
import { Response, OkResponse } from 'redux/Common/types'
import { MessagingAdaptor } from './api/messaging-adaptor'

export default class EmailDomainService {
  constructor(
    private readonly api: Api,
    private messagingAdaptor: MessagingAdaptor
  ) {
    this.api = api
  }

  isOk<TData>(res: Response<TData>): res is OkResponse<TData> {
    return !!res && 'ok' in res && res.ok
  }

  async getEmailDomain(): Promise<Maybe<GetEmailDomainResponse>> {
    const res = await this.messagingAdaptor.getEmailDomain()

    if (!this.isOk(res)) {
      if (res?.kind === 'not-found') {
        return null
      }
      return void notification.error({ message: res?.message })
    }

    return res.response
  }

  async postEmailDomain(
    data: PostEmailDomainRequest
  ): Promise<Maybe<GetEmailDomainResponse>> {
    const res = await this.messagingAdaptor.postEmailDomain(data)

    if (!this.isOk(res))
      return void notification.error({ message: res?.message })

    return res.response
  }

  async patchEmailDomain(
    data: PatchEmailDomainRequest
  ): Promise<Maybe<GetEmailDomainResponse>> {
    const res = await this.messagingAdaptor.patchEmailDomain(data)

    if (!this.isOk(res))
      return void notification.error({ message: res?.message })

    return res.response
  }

  async verifyEmailDomain(): Promise<Maybe<GetEmailDomainResponse>> {
    const res = await this.messagingAdaptor.verifyEmailDomain()

    if (!this.isOk(res)) {
      if (res?.kind === 'not-found') {
        return null
      }
      return void notification.error({ message: res?.message })
    }

    return res.response
  }

  async deleteEmailDomain(): Promise<Maybe<GetEmailDomainResponse>> {
    const res = await this.messagingAdaptor.deleteEmailDomain()

    if (!this.isOk(res))
      return void notification.error({ message: res?.message })

    return
  }

  async sendTestEmail(data: PostSendTestEmailRequest): Promise<Maybe<any>> {
    const res = await this.messagingAdaptor.sendTestEmail(data)

    if (!this.isOk(res))
      return void notification.error({ message: res?.message })

    notification.success({ message: 'Email(s) sent successfully' })
  }
}
