import { Action } from "redux-actions";
import { SagaIterator } from "redux-saga";
import { call, put, takeLatest } from "typed-redux-saga";
import { GetExperienceByIdRequest } from "redux/Experience/types";
import { experience1To1Service, timeRangeService } from "services";
import {
  copyTimeRangeActions,
  createDateOffActions,
  createTimeRangeActions,
  deleteDateOffActions,
  deleteTimeRangeActions,
  deleteWeekDayActions,
  getTimeRangesInMonthActions,
  removeRepeatTimeRangeActions,
  setRepeatTimeRangeActions,
  updateTimeRangeActions,
} from "./actions";
import {
  CopyTimeRangeRequest,
  CreateDateOffRequest,
  CreateTimeRangeRequest,
  DeleteDateOffRequest,
  DeleteTimeRangeRequest,
  DeleteWeekDayRequest,
  GetTimeRangesInMonthRequest,
  UpdateTimeRangeRequest,
  RepeatTimeRangeRequest,
} from "./types";

function* getTimeRangesInMonth({
  payload,
}: Action<GetTimeRangesInMonthRequest>) {
  const requestData: GetExperienceByIdRequest = {
    expId: payload.expId as string,
  };

  const experienceDetailResult: any = yield* call(
    experience1To1Service.getExperienceById,
    requestData
  );
  if (experienceDetailResult.ok) {
    const result: any = yield* call(timeRangeService.getSlotsInMonth, {
      ...payload,
      experience: experienceDetailResult.response,
    });
    if (result.ok) {
      yield* put(getTimeRangesInMonthActions.SUCCESS(result.response));
    } else {
      yield* put(getTimeRangesInMonthActions.FAILURE(result.message));
    }
  } else {
    yield* put(
      getTimeRangesInMonthActions.FAILURE(experienceDetailResult.message)
    );
  }
}

function* createTimeRange({ payload }: Action<CreateTimeRangeRequest>) {
  const result: any = yield* call(timeRangeService.createSlotEvent, payload);
  if (result.ok) {
    yield* put(createTimeRangeActions.SUCCESS(new Date()));
  } else {
    yield* put(createTimeRangeActions.FAILURE(result.message));
  }
}

function* updateTimeRange({ payload }: Action<UpdateTimeRangeRequest>) {
  const result: any = yield* call(timeRangeService.updateSlot, payload);

  if (result.ok) {
    yield* put(updateTimeRangeActions.SUCCESS(new Date()));
  } else {
    yield* put(updateTimeRangeActions.FAILURE(result.message));
  }
}

function* createDateOff({ payload }: Action<CreateDateOffRequest>) {
  const result: any = yield* call(timeRangeService.createDateOff, payload);

  if (result.ok) {
    yield* put(createDateOffActions.SUCCESS(result.response));
  } else {
    yield* put(createDateOffActions.FAILURE(result.message));
  }
}

function* deleteTimeRange({ payload }: Action<DeleteTimeRangeRequest>) {
  const result: any = yield* call(timeRangeService.deleteSlot, payload);

  if (result.ok) {
    yield* put(deleteTimeRangeActions.SUCCESS(new Date()));
  } else {
    yield* put(deleteTimeRangeActions.FAILURE(result.message));
  }
}

function* deleteDateOff({ payload }: Action<DeleteDateOffRequest>) {
  const result: any = yield* call(timeRangeService.deleteDateOff, payload);

  if (result.ok) {
    yield* put(deleteDateOffActions.SUCCESS(result.response));
  } else {
    yield* put(deleteDateOffActions.FAILURE(result.message));
  }
}

function* deleteWeekDay({ payload }: Action<DeleteWeekDayRequest>) {
  const result: any = yield* call(timeRangeService.deleteWeekDay, payload);

  if (result.ok) {
    yield* put(deleteWeekDayActions.SUCCESS(result.response));
  } else {
    yield* put(deleteWeekDayActions.FAILURE(result.message));
  }
}

function* copyTimeRange({ payload }: Action<CopyTimeRangeRequest>) {
  const result: any = yield* call(timeRangeService.copyTimeRange, payload);

  if (result.ok) {
    yield* put(copyTimeRangeActions.SUCCESS(new Date()));
  } else {
    yield* put(copyTimeRangeActions.FAILURE(result.message));
  }
}

function* setRepeatTimeRange({ payload }: Action<RepeatTimeRangeRequest>) {
  const result: any = yield* call(timeRangeService.setRepeatTimeRange, payload);

  if (result.ok) {
    yield* put(setRepeatTimeRangeActions.SUCCESS(new Date()));
  } else {
    yield* put(setRepeatTimeRangeActions.FAILURE(result.message));
  }
}

function* removeRepeatTimeRange({ payload }: Action<RepeatTimeRangeRequest>) {
  const result: any = yield* call(
    timeRangeService.removeRepeatTimeRange,
    payload
  );

  if (result.ok) {
    yield* put(removeRepeatTimeRangeActions.SUCCESS(new Date()));
  } else {
    yield* put(removeRepeatTimeRangeActions.FAILURE(result.message));
  }
}

export default function* timeRangeSagas(): SagaIterator {
  yield* takeLatest(getTimeRangesInMonthActions.REQUEST, getTimeRangesInMonth);
  yield* takeLatest(updateTimeRangeActions.REQUEST, updateTimeRange);
  yield* takeLatest(createDateOffActions.REQUEST, createDateOff);
  yield* takeLatest(createTimeRangeActions.REQUEST, createTimeRange);
  yield* takeLatest(deleteTimeRangeActions.REQUEST, deleteTimeRange);
  yield* takeLatest(deleteDateOffActions.REQUEST, deleteDateOff);
  yield* takeLatest(deleteWeekDayActions.REQUEST, deleteWeekDay);
  yield* takeLatest(copyTimeRangeActions.REQUEST, copyTimeRange);
  yield* takeLatest(setRepeatTimeRangeActions.REQUEST, setRepeatTimeRange);
  yield* takeLatest(
    removeRepeatTimeRangeActions.REQUEST,
    removeRepeatTimeRange
  );
}
