import { ServiceType } from '../types'
import ApiUtil from 'utils/ApiUtil'

import OrgInfo from '../objects/OrgInfo'
import TeamInfo from '../objects/TeamInfo'
import ProjectInfo from '../objects/ProjectInfo'

export const REQUEST_PROJECT_INFO = 'REQUEST_PROJECT_INFO'
export const RECEIVE_PROJECT_INFO = 'RECEIVE_PROJECT_INFO'
export const RECEIVE_PROJECT_INFO_ERROR = 'RECEIVE_PROJECT_INFO_ERROR'
export const RECEIVE_PROJECT_INFO_EXISTING = 'RECEIVE_PROJECT_INFO_EXISTING'

export const REQUEST_TEAM_INFO = 'REQUEST_TEAM_INFO'
export const RECEIVE_TEAM_INFO = 'RECEIVE_TEAM_INFO'
export const RECEIVE_TEAM_INFO_ERROR = 'RECEIVE_TEAM_INFO_ERROR'
export const RECEIVE_TEAM_INFO_EXISTING = 'RECEIVE_TEAM_INFO_EXISTING'

export const REQUEST_ORG_INFO = 'REQUEST_ORG_INFO'
export const RECEIVE_ORG_INFO = 'RECEIVE_ORG_INFO'
export const RECEIVE_ORG_INFO_ERROR = 'RECEIVE_ORG_INFO_ERROR'
export const RECEIVE_ORG_INFO_EXISTING = 'RECEIVE_ORG_INFO_EXISTING'

export function fetchOrgInfo (serviceId) {
  return fetchServiceInfo(serviceId, ServiceType.ORG)
}

export function fetchTeamInfo (serviceId) {
  return fetchServiceInfo(serviceId, ServiceType.TEAM)
}

export function fetchProjectInfo (serviceId) {
  return fetchServiceInfo(serviceId, ServiceType.PROJECT)
}

export function fetchServiceInfo (serviceId, serviceType) {
  return function (dispatch, getState) {
    dispatch(requestServiceInfo(serviceId, serviceType))
    let existingInfo = getState().api_data.services[serviceId]
    if (existingInfo !== undefined) {
      existingInfo = existingInfo.info
    }
    if (existingInfo !== undefined) {
      dispatch(receiveServiceInfoExisting(serviceId, serviceType))
      return Promise.resolve()
    }
    return ApiUtil.getServiceInfo(serviceId, serviceType.name.toLowerCase() + 's').then(
      json => dispatch(receiveServiceInfo(serviceId, serviceType, json)),
      error => dispatch(receiveServiceInfoError(error, serviceType))
    )
  }
}

function requestServiceInfo (serviceId, serviceType) {
  return {
    type: getActionTypeFromServiceType(serviceType, 'request'),
    serviceId: serviceId
  }
}

function receiveServiceInfo (serviceId, serviceType, serviceInfo) {
  if (serviceType === ServiceType.ORG) {
    serviceInfo = new OrgInfo(serviceInfo)
  }
  if (serviceType === ServiceType.TEAM) {
    serviceInfo = new TeamInfo(serviceInfo)
  }
  if (serviceType === ServiceType.PROJECT) {
    serviceInfo = new ProjectInfo(serviceInfo.project)
  }
  return {
    type: getActionTypeFromServiceType(serviceType, 'receive'),
    serviceId: serviceId,
    serviceInfo: serviceInfo
  }
}

export function receiveServiceInfoError (error, serviceType) {
  return {
    type: getActionTypeFromServiceType(serviceType, 'error'),
    error: error
  }
}

function receiveServiceInfoExisting (serviceId, serviceType) {
  return {
    type: getActionTypeFromServiceType(serviceType, 'existing'),
    serviceId: serviceId
  }
}

function getActionTypeFromServiceType (serviceType, actionStr) {
  switch (actionStr) {
    case 'request':
      if (serviceType === ServiceType.ORG) {
        return REQUEST_ORG_INFO
      } else if (serviceType === ServiceType.TEAM) {
        return REQUEST_TEAM_INFO
      } else {
        return REQUEST_PROJECT_INFO
      }
    case 'receive':
      if (serviceType === ServiceType.ORG) {
        return RECEIVE_ORG_INFO
      } else if (serviceType === ServiceType.TEAM) {
        return RECEIVE_TEAM_INFO
      } else {
        return RECEIVE_PROJECT_INFO
      }
    case 'existing':
      if (serviceType === ServiceType.ORG) {
        return RECEIVE_ORG_INFO_EXISTING
      } else if (serviceType === ServiceType.TEAM) {
        return RECEIVE_TEAM_INFO_EXISTING
      } else {
        return RECEIVE_PROJECT_INFO_EXISTING
      }
    default:
      if (serviceType === ServiceType.ORG) {
        return RECEIVE_ORG_INFO_ERROR
      } else if (serviceType === ServiceType.TEAM) {
        return RECEIVE_TEAM_INFO_ERROR
      } else {
        return RECEIVE_PROJECT_INFO_ERROR
      }
  }
}
