import { all, takeLatest, call, put, select } from "@redux-saga/core/effects";
import {
  attemptCreateNewChat,
  attemptFetchChats,
  attemptFetchHeaderChats,
  attemptFetchOneChat,
  attemptSendMessage,
} from "../../request/chatRequest";
import { attemptFetchOneOffer } from "../../request/offersRequest";
import {
  CHAT_FETCH,
  CHAT_HEADER_FETCH,
  CHAT_NEW_FETCH,
  CHAT_ONE_FETCH,
  CHAT_SEND_FETCH,
} from "../actions/chat/chatActionConstants";
import { fetchChatsError, fetchChatsSuccess, fetchHeaderChatsError, fetchHeaderChatsSuccess, fetchOneChatError, fetchOneChatSuccess, sendMessageError, sendMessageSuccess, setChats, setOneChat, startNewChatError, startNewChatSuccess } from "../actions/chat/chatActions";
import { validateExchange } from "../actions/exchange/exchangeActions";
import { selectSelectedChat } from "../selectors/chatSelectors";
import { selectExchange } from "../selectors/exchangeSelector";
import { selectUserId } from "../selectors/loginSelectors";

function* fetchChats() {
  try {
    const userId = yield select(selectUserId);
    const data = yield call(attemptFetchChats, userId);
    yield put(setChats([...data.data]));
    yield put(fetchChatsSuccess());
  } catch (e) {
    yield put(fetchChatsError());
    console.log(e);
  }
}

function* fetchHeaderChats() {
  try {
    const userId = yield select(selectUserId);
    const data = yield call(attemptFetchHeaderChats, userId);
    yield put(setChats([...data.data]));
    yield put(fetchHeaderChatsSuccess());
  } catch (e) {
    yield put(fetchHeaderChatsError());
    console.log(e);
  }
}
function* fetchOneChat(payload) {
  try {
    const chatData = yield call(attemptFetchOneChat, payload.payload);
    const offerData = yield call(
      attemptFetchOneOffer,
      chatData.data.chat.offerId
    );
    const chat = {
      chat: chatData.data.chat,
      offer: offerData.data,
      interlocutor: chatData.data.interlocutorData,
    };
    yield put(setOneChat(chat));
    yield put(fetchOneChatSuccess());
  } catch (e) {
    yield put(fetchOneChatError());
    console.log(e);
  }
}

function* sendMessage(payload) {
  try {
    const messageObject = {
      text: payload.payload.message,
    };
    const chat = yield select(selectSelectedChat);
    const exchange = yield select(selectExchange);
    const userId = yield select(selectUserId);
    yield call(attemptSendMessage, payload.payload.chatId, messageObject);
    if (chat?.offer?.offer?.userId === userId && exchange.valid === false) {
      yield put(validateExchange(exchange._id));
    }
    yield call(fetchChats);
    yield put(sendMessageSuccess());
    if (payload.payload.handleApiResponseSuccess) {
      yield call(payload.payload.handleApiResponseSuccess);
    }
  } catch (e) {
    yield put(sendMessageError());
    console.log(e);
  }
}
function* startNewChat(payload) {
  try {
    const newChatData = yield call(
      attemptCreateNewChat,
      payload.payload.offerId
    );
    const newChatId = newChatData.data.chatId;
    const messageObject = {
      text: payload.payload.message,
    };
    yield call(attemptSendMessage, newChatId, messageObject);
    yield put(startNewChatSuccess());
    if (payload.payload.handleMessageSendSuccess) {
      yield call(payload.payload.handleMessageSendSuccess, newChatId);
    }
  } catch (e) {
    yield put(startNewChatError());
    console.log(e);
  }
}

export default function* chatSaga() {
  yield all([
    takeLatest(CHAT_FETCH, fetchChats),
    takeLatest(CHAT_ONE_FETCH, fetchOneChat),
    takeLatest(CHAT_HEADER_FETCH, fetchHeaderChats),
    takeLatest(CHAT_SEND_FETCH, sendMessage),
    takeLatest(CHAT_NEW_FETCH, startNewChat),
  ]);
}
