import { createLogic, Done } from 'redux-logic';
import { AuthActions, UserActions } from '../actions';
import { Dispatch, Location, RootState } from '../models';
import { Firestore, LogicDeps, Storage } from './';

const updateProfileLogic = createLogic({
  type: UserActions.ActionKey.USER_PROFILE_EDIT_REQUEST,
  process({ action, getState }: LogicDeps & { action: UserActions.UserProfileEditRequest, getState: () => RootState },
    dispatch: Dispatch, done: Done) {
    const userRole = getState().user.role;
    Firestore
      .collection(userRole)
      .doc(action.userId)
      .set(action.data, { merge: true })
      .then(() => dispatch(UserActions.userProfileEditSuccess(action.data)))
      .catch((error) => {
        return dispatch(UserActions.userProfileEditFail('Failed to save user profile'));
      })
      .then(() => done());
  },
});

const updateLocationLogic = createLogic({
  type: UserActions.ActionKey.USER_LOCATION_UPDATE_REQUEST,
  process({ action, getState }: LogicDeps & {
    action: UserActions.UserLocationUpdateRequest,
    getState: () => RootState,
  },
    dispatch: Dispatch, done: Done) {
    const userRole = getState().user.role;
    Firestore
      .collection(userRole)
      .doc(action.userId)
      .set({ location: action.location }, { merge: true })
      .then(() => dispatch(UserActions.UserLocationUpdateSuccess(action.userId)))
      .catch((error) => console.error(error))
      .then(() => done());
  },
});

const updateProfilePhotoLogic = createLogic({
  type: UserActions.ActionKey.USER_PHOTO_UPLOAD_REQUEST,
  process({ action, getState }: LogicDeps & { action: UserActions.UserPhotoUploadRequested, getState: () => RootState },
    dispatch: Dispatch, done: Done) {
    (Storage
      .child('avatars')
      .child(action.userId) as any)
      .putFile(action.path)
      .then(({ downloadURL }) => {
        const userRole = getState().user.role;
        return Firestore
          .collection(userRole)
          .doc(action.userId)
          .set({ avatar: downloadURL }, { merge: true })
          .then(() => dispatch(UserActions.userPhotoUploadSuccess(downloadURL)));
      })
      .catch((e) => {
        dispatch(UserActions.userPhotoUploadFail(e));
      })
      .then(() => done());
  },
});

const getUserLocation = createLogic({
  type: AuthActions.ActionKey.INITIALIZE_USER_FLOW,
  warnTimeout: 0,
  process({ action }: LogicDeps & { action: AuthActions.InitializeUserFlow },
    dispatch: Dispatch) {
    navigator.geolocation.getCurrentPosition((position) => {
      const location: Location = {
        latitude: position.coords.latitude,
        longitude: position.coords.longitude,
      };
      dispatch(UserActions.UserLocationUpdateRequest(action.uid, location));
    }, (error) => console.error(error));
  },
});

export const userLogic = [
  updateProfileLogic,
  updateProfilePhotoLogic,
  getUserLocation,
  updateLocationLogic,
];
