import { call, put, takeEvery } from 'redux-saga/effects';
import { Alert, Platform } from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';
import * as types from '../actions/types';
import * as UserService from '../services/UserService';
import * as UserAction from '../actions/UserAction';
import * as GeneralAction from '../actions/GeneralAction';
import SplashScreen from 'react-native-splash-screen';

import Api from './../services/Api';
import { Toast } from './../components';

function* login(action: any) {
  const params = action.payload || {};
  try {
    const res = yield call(UserService.login, params);
    if (res.success) {
      yield put(UserAction.loginSuccess(res.data));
      let token = res.data.token;
      let user = res.data;
      Api.setHeaderAuthorization(token);
      yield AsyncStorage.setItem('user', JSON.stringify(user));
      let creds = {
        password: params.password
      };
      yield AsyncStorage.setItem('creds', JSON.stringify(creds));
      yield put(UserAction.getProfileRequest());
    } else {
      yield put(UserAction.loginFail(res.message));
      Toast.errorBottom(res.message);
    }
  } catch (error) {
    yield put(UserAction.loginFail('Something went wrong'));
    yield put(UserAction.logoutRequest())
    Toast.errorBottom('Token expired!');
  }
}

function* register(action: any) {
  const { params } = action.payload || {};
  try {
    const res = yield call(UserService.register, params);
    if (res.success) {
      yield put(UserAction.registerSuccess(res.data));
      yield put(UserAction.getProfileRequest());
      let token = res.data.token;
      let user = res.data;
      Api.setHeaderAuthorization(token);
      yield AsyncStorage.setItem('user', JSON.stringify(user));

      let creds = {
        password: params.password
      };
      yield AsyncStorage.setItem('creds', JSON.stringify(creds));
      yield put(GeneralAction.requestNavigateToHome(user));

      //getProfile()
      //Same call as login
      //Same call as init
    } else {
      yield put(UserAction.registerFail(res.message));
      Toast.errorBottom(res.message);
    }
  } catch (error) {
    yield put(UserAction.registerFail('Something went wrong'));
    yield put(UserAction.logoutRequest())
    Toast.errorBottom('Token expired!');
  }
}

function* initApp() {
  try {
    let user = yield AsyncStorage.getItem('user');
    let profile = yield AsyncStorage.getItem('profile');
    if (user) {
      let userObj = JSON.parse(user);
      let token = userObj.token;
      Api.setHeaderAuthorization(token);
      yield put(GeneralAction.requestNavigateToHome(userObj));
      if (Platform.OS === 'android') {
        SplashScreen.hide();
      }
      if (profile) {
        let profileObj = JSON.parse(profile);
        yield put(UserAction.getProfileSuccess(profileObj));
      }
    } else {
      if (Platform.OS === 'android') {
        SplashScreen.hide();
      }
      yield put(UserAction.logoutSuccess());
    }
  } catch (e) {
    if (Platform.OS === 'android') {
      SplashScreen.hide();
    }
    yield put(UserAction.logoutRequest())
    yield put(UserAction.loginFail('Something went wrong'));
  }
}

function* getProfile() {
  try {
    const res = yield call(UserService.getProfile);
    if (res.success) {
      yield put(UserAction.getProfileSuccess(res.data));
      AsyncStorage.setItem('profile', JSON.stringify(res.data));
    } else {
      yield put(UserAction.getProfileFail(res.message));
    }
  } catch (error) {
    yield put(UserAction.logoutRequest())
    yield put(UserAction.getProfileFail('Something went wrong'));
  }
}

function* updateProfile(action: any) {
  const { params } = action.payload || {};
  try {
    const res = yield call(UserService.updateProfile, params);
    if (res.success) {
      Toast.successBottom(res.message);
      yield put(UserAction.updateProfileSuccess());
      yield put(UserAction.getProfileSuccess(res.data));
      AsyncStorage.setItem('profile', JSON.stringify(res.data));
    } else {
      yield put(UserAction.updateProfileFail(res.message));
      Toast.errorBottom(res.message);
    }
  } catch (error) {
    yield put(UserAction.updateProfileFail('Something went wrong'));
    yield put(UserAction.logoutRequest())
    Toast.errorBottom('Token expired!');
  }
}

function* forgotPassword(action: any) {
  const { params } = action.payload || {};
  try {
    const res = yield call(UserService.forgotPassword, params);
    if (res.success) {
      yield put(UserAction.forgotPasswordSuccess());
      Toast.successBottom(res.message);
    } else {
      yield put(UserAction.forgotPasswordFail(res.message));
      Toast.errorBottom(res.message);
    }
  } catch (error) {
    yield put(UserAction.forgotPasswordFail('Something went wrong'));
    yield put(UserAction.logoutRequest())
    Toast.errorBottom('Token expired!');
  }
}

function* resetPassword(action: any) {
  const { params } = action.payload || {};
  try {
    const res = yield call(UserService.resetPassword, params);
    if (res.success) {
      yield put(UserAction.resetPasswordSuccess());
      Toast.successBottom(res.message);
    } else {
      yield put(UserAction.resetPasswordFail(res.message));
      Toast.errorBottom(res.message);
    }
  } catch (error) {
    yield put(UserAction.resetPasswordFail('Something went wrong'));
    yield put(UserAction.logoutRequest())
    Toast.errorBottom('Token expired!');
  }
}

function* changePassword(action: any) {
  const { params } = action.payload || {};
  try {
    const res = yield call(UserService.changePassword, params);
    if (res.success) {
      yield put(UserAction.changePasswordSuccess());
      let creds = {
        password: params.password
      };
      yield AsyncStorage.setItem('creds', JSON.stringify(creds));
      Toast.successBottom(res.message);
    } else {
      yield put(UserAction.changePasswordFail(res.message));
      Toast.errorBottom(res.message);
    }
  } catch (error) {
    yield put(UserAction.changePasswordFail('Something went wrong'));
    yield put(UserAction.logoutRequest())
    Toast.errorBottom('Token expired!');
  }
}

function* logout() {
  try {
    const res = yield call(UserService.logout);
    AsyncStorage.removeItem('user');
    AsyncStorage.removeItem('creds');
    AsyncStorage.removeItem('profile');
    Api.setHeaderAuthorization(null);
    yield put(UserAction.logoutSuccess());
    yield put(GeneralAction.loadingStopRequest());
  } catch (error) {
    AsyncStorage.removeItem('user');
    Api.setHeaderAuthorization(null);
    yield put(UserAction.logoutSuccess());
    yield put(GeneralAction.loadingStopRequest());
  }
}

export default function* watchAuthRequests() {
  yield takeEvery(types.LOGIN_REQUEST, login);
  yield takeEvery(types.REGISTER_REQUEST, register);
  yield takeEvery(types.UPDATE_PROFILE_DETAILS_REQUEST, updateProfile);
  yield takeEvery(types.LOGOUT_REQUEST, logout);
  yield takeEvery(types.INIT_REQUEST, initApp);
  yield takeEvery(types.FORGOT_PASSWORD_REQUEST, forgotPassword);
  yield takeEvery(types.RESET_PASSWORD_REQUEST, resetPassword);
  yield takeEvery(types.CHANGE_PASSWORD_REQUEST, changePassword);
  yield takeEvery(types.GET_PROFILE_DETAILS_REQUEST, getProfile);
}
