import {
  TemplateDto,
  TemplateResponse,
  TemplatesResponse,
  TemplateSignedUrlResponse,
  TemplateWithCursorDto,
  CampaignTemplateCreateDto
} from 'types/templates'
import notification from 'utils/notification'
import { Maybe } from 'utils/types'
import { Api } from './api'
import { getApiResponse } from 'utils/api'
import {
  CountQueryParameters,
  PaginationQueryParameters
} from 'hooks/usePagination'
import { MessagingAdaptor } from './api/messaging-adaptor'

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

  async getTemplate(templateId: string): Promise<Maybe<TemplateDto>> {
    const res = await this.messagingAdaptor.getTemplate(templateId)

    if (!res) {
      return void notification.error({
        message: 'Something went wrong while querying template'
      })
    }
    if (!('ok' in res)) {
      return void notification.error({ message: res.message })
    }

    return (res.response as TemplateResponse).template
  }

  async getTemplates(): Promise<Maybe<TemplateDto[]>> {
    const res = await this.api.getTemplates()

    if (!res) {
      return void notification.error({
        message: 'Something went wrong while querying templates'
      })
    }
    if (!('ok' in res)) {
      return void notification.error({ message: res.message })
    }

    return (res.response as TemplatesResponse).templates
  }

  async getTemplatesWithCursor(
    queryParams: PaginationQueryParameters,
    searchTerm: string
  ): Promise<Maybe<TemplateWithCursorDto[]>> {
    const res = await this.messagingAdaptor.getTemplates(
      queryParams,
      searchTerm
    )

    if (!res)
      return void notification.error({ message: 'Something went wrong' })
    if (!('ok' in res)) return void notification.error({ message: res.message })

    return res.response.templates
  }

  async getTemplatesCount(
    countParams: CountQueryParameters,
    searchTerm: string
  ): Promise<Maybe<number>> {
    const res = await this.messagingAdaptor.getTemplatesCount(
      countParams,
      searchTerm
    )

    if (!res)
      return void notification.error({ message: 'Something went wrong' })
    if (!('ok' in res)) return void notification.error({ message: res.message })

    return res.response.count
  }

  async createTemplate(
    template: CampaignTemplateCreateDto
  ): Promise<Maybe<TemplateDto>> {
    const res = await this.messagingAdaptor.createTemplate(template)

    if (!res) {
      return void notification.error({
        message: 'Something went wrong while creating template'
      })
    }
    if (!('ok' in res)) {
      return void notification.error({ message: res.message })
    }

    if (template.templateJson?.classic) {
      notification.success({
        message: 'Custom template imported successfully'
      })
    }

    return res.response.template
  }

  async updateTemplate(
    templateId: string,
    template: CampaignTemplateCreateDto
  ): Promise<Maybe<TemplateDto>> {
    const res = await this.messagingAdaptor.updateTemplate(templateId, template)

    if (!res) {
      return void notification.error({
        message: 'Something went wrong while updating template'
      })
    }
    if (!('ok' in res)) {
      return void notification.error({ message: res.message })
    }

    notification.success({ message: 'Template updated successfully' })
    return res
  }

  async deleteTemplate(
    templateId: string,
    templateName: string
  ): Promise<Maybe<TemplateDto>> {
    const res = await this.messagingAdaptor.deleteTemplate(templateId)

    if (!res) {
      return void notification.error({
        message: 'Something went wrong while deleting template'
      })
    }
    if (!('ok' in res)) {
      return void notification.error({ message: res.message })
    }

    notification.success({ message: `${templateName} deleted successfully` })
  }

  async getSignedThumbnailUploadUrl(): Promise<
    Maybe<TemplateSignedUrlResponse>
  > {
    return getApiResponse(this.api.getSignedThumbnailUploadUrl())
  }
}
