import {
  USER_LOGGED_IN,
  USER_LOGGED_OUT,
  USER_NOT_LOGGED_IN,
  RECEIVE_SESSION,
  LOG_IN_USER,
  LOG_OUT_USER,
  REGISTER_USER,
  UPDATE_USER,
  REQUEST_SESSION,
  LOGIN_ERROR,
  REGISTER_ERROR,
  UPDATE_ERROR,
  CANCEL_UPDATE
} from 'actions/session';
import Immutable from 'immutable';

const User = new Immutable.Record({
  id: null,
  username: null,
  email: null,
  lastname: null,
  firstname: null,
  facebook: null,
  twitter: null,
  picture: null,
  phone: null
});

const Session = new Immutable.Record({
  isLoading: false,
  isLoggedIn: null,
  error: null,
  authKey: '',
  user: new User(),
  permissions: []
});

Session.prototype.hasPerm = function(perm) {
  return this.permissions.indexOf(perm) !== -1;
};

export default function sessionReducer(state = new Session(), action) {
  let info;
  let key;

  switch (action.type) {
  case USER_NOT_LOGGED_IN:
  case USER_LOGGED_OUT:
    return new Session({
      isLoggedIn: false
    });
  case USER_LOGGED_IN:
  case RECEIVE_SESSION:
    info = action.user;
    key = action.key;

    return new Session({
      isLoggedIn: true,
      authKey: key,
      user: new User({
        id: info.uid,
        username: info.username,
        email: info.email,
        lastname: info.lastname,
        firstname: info.firstname,
        facebook: info.facebook,
        twitter: info.twitter,
        picture: info.picture,
        phone: info.phone
      }),
      permissions: action.permissions
    });
  case LOG_IN_USER:
  case LOG_OUT_USER:
  case REGISTER_USER:
    return new Session({
      isLoading: true
    });
  case UPDATE_USER:
  case REQUEST_SESSION:
    return state.set('isLoading', true);
  case LOGIN_ERROR:
  case REGISTER_ERROR:
    return new Session({
      isLoggedIn: false,
      error: action.error
    });
  case UPDATE_ERROR:
    return state.set('error', action.error)
      .set('isLoading', false)
      .setIn(['user', 'firstname'], '')
      .setIn(['user', 'lastname'], '');
  case CANCEL_UPDATE:
    return state.delete('error');
  default:
    return state;
  }
}
