import { Action } from 'redux-actions'
import { SagaIterator } from 'redux-saga'
import { call, put, takeLatest } from 'typed-redux-saga'
import { specialRequestService } from 'services'
import {
  getListSpecialRequestsActions,
  getSpecialRequestByIdActions,
  setSpecialRequestStatusActions
} from './actions'
import { GetSpecialRequests } from './types'
import { Booking, BookingStatusType } from 'redux/Booking/types'

function* getListSpecialRequests({
  payload
}: Action<GetSpecialRequests & { callback?: () => void }>) {
  const result: any = yield* call(specialRequestService.getList, payload)
  if (result.ok) {
    yield* put(getListSpecialRequestsActions.SUCCESS(result.response))
  } else {
    yield* put(getListSpecialRequestsActions.FAILURE(result.message))
  }
  payload?.callback && payload.callback()
}

function* getSpecialRequestById({ payload }: Action<string>) {
  const result: any = yield* call(specialRequestService.getById, payload)
  if (result.ok) {
    yield* put(getSpecialRequestByIdActions.SUCCESS(result.response))
  } else {
    yield* put(getSpecialRequestByIdActions.FAILURE(result.message))
  }
}

function* setSpecialRequestStatus({
  payload
}: Action<{
  status: BookingStatusType
  bookingId: Booking['id']
  notes?: string
}>) {
  let result: any
  switch (payload.status) {
    case BookingStatusType.ACCEPTED:
      result = yield* call(specialRequestService.accept, payload.bookingId)
      break
    case BookingStatusType?.COMPLETED:
      result = yield* call(specialRequestService.complete, payload.bookingId)
      break
    case BookingStatusType?.REJECTED:
    case BookingStatusType?.DECLINED:
      result = yield* call(specialRequestService.reject, {
        bookingId: payload?.bookingId,
        notes: payload?.notes || ''
      })
  }
  if (result?.ok) {
    yield* put(setSpecialRequestStatusActions.SUCCESS(result?.response))
  } else {
    yield* put(setSpecialRequestStatusActions.FAILURE(result?.message))
  }
}

export default function* specialRequestSagas(): SagaIterator {
  yield* takeLatest(
    getListSpecialRequestsActions.REQUEST,
    getListSpecialRequests
  )
  yield* takeLatest(getSpecialRequestByIdActions.REQUEST, getSpecialRequestById)
  yield* takeLatest(
    setSpecialRequestStatusActions.REQUEST,
    setSpecialRequestStatus
  )
}
