Skip to content
Snippets Groups Projects
challengeDataMapperService.ts 6.66 KiB
import { DateTime, Duration } from 'luxon'
import {
  UserChallenge,
  ChallengeType,
  EcogestureType,
  ChallengeState,
  BadgeState,
  TypeChallenge,
} from 'services/dataChallengeContracts'
import { FluidType } from 'enum/fluid.enum'
import { CHALLENGETYPE_DOCTYPE, ECOGESTURE_DOCTYPE } from 'doctypes'

export class UserChallengeEntity {
  _id?: string
  startingDate: string
  endingDate: string
  state: ChallengeState
  maxEnergy: number
  currentEnergy: number
  badge: BadgeState
  relationships: any

  constructor(
    startingDate: string,
    endingDate: string,
    state: ChallengeState,
    maxEnergy: number,
    currentEnergy: number,
    badge: BadgeState,
    relationships: any,
    _id?: string
  ) {
    this.startingDate = startingDate
    this.endingDate = endingDate
    this.state = state
    this.maxEnergy = maxEnergy
    this.currentEnergy = currentEnergy
    this.badge = badge
    this._id = _id
    this.relationships = relationships
  }
}

export class ChallengeTypeEntity {
  _id: string
  type: TypeChallenge
  title: string
  description: string
  level: number
  duration: Duration
  fluidTypes: FluidType[]
  relationships: any

  constructor(
    _id: string,
    type: TypeChallenge,
    title: string,
    description: string,
    level: number,
    duration: Duration,
    fluidTypes: FluidType[],
    relationships: any
  ) {
    this._id = _id
    this.type = type
    this.title = title
    this.description = description
    this.level = level
    this.duration = duration
    this.fluidTypes = fluidTypes
    this.relationships = relationships
  }
}

export default class ChallengeDataMapper {
  public mapFromUserChallenge(
    userChallenge: UserChallenge
  ): UserChallengeEntity {
    const mappedEcogestures = userChallenge.selectedEcogestures.map(
      ecogesture => ({
        _id: ecogesture.id,
        _type: ECOGESTURE_DOCTYPE,
      })
    )

    const mappedUserChallenge: UserChallengeEntity = {
      startingDate: userChallenge.startingDate.toISO(),
      endingDate: userChallenge.endingDate.toISO(),
      state: userChallenge.state,
      maxEnergy: userChallenge.maxEnergy,
      currentEnergy: userChallenge.currentEnergy,
      relationships: {
        selectedEcogestures: {
          data: mappedEcogestures,
        },
        challengeType: {
          data: {
            _id: userChallenge.challengeType
              ? userChallenge.challengeType.id
              : '',
            _type: CHALLENGETYPE_DOCTYPE,
          },
        },
      },
    }
    return mappedUserChallenge
  }

  public mapToUserChallenge(
    userChallengeEntity: UserChallengeEntity,
    userChallengeEntityRelationships?: any | null
  ): UserChallenge {
    let selectedEcogestures: EcogestureType[] = []
    let challengeType: ChallengeType | null = null

    if (userChallengeEntityRelationships) {
      const idOfEcogestures = userChallengeEntity.relationships.selectedEcogestures.data.map(
        eg => eg._id
      )
      const challengeTypes = userChallengeEntityRelationships.filter(
        challengeType =>
          challengeType._type === CHALLENGETYPE_DOCTYPE &&
          challengeType._id ===
            userChallengeEntity.relationships.challengeType.data._id
      )
      const EcogesturesRelationships = userChallengeEntityRelationships.filter(
        eg => idOfEcogestures.includes(eg._id)
      )
      selectedEcogestures = EcogesturesRelationships.filter(
        relationship => relationship._type === ECOGESTURE_DOCTYPE
      )
      challengeType = challengeTypes ? challengeTypes[0] : null
    }

    const mappedUserChallenge: UserChallenge = new UserChallenge(
      DateTime.fromISO(userChallengeEntity.startingDate).startOf('day'),
      DateTime.fromISO(userChallengeEntity.endingDate).startOf('day'),
      userChallengeEntity.state,
      selectedEcogestures,
      challengeType,
      userChallengeEntity.maxEnergy,
      userChallengeEntity.currentEnergy,
      userChallengeEntity.badge,
      userChallengeEntity._id
    )
    return mappedUserChallenge
  }

  public mapToChallengeType(
    challengeEntity: ChallengeTypeEntity,
    challengeTypeEntityRelationships?: any | null,
    unlockedEcogestures?: string[],
    fluidTypes?: FluidType[]
  ): ChallengeType {
    const completeAvailableEcogestures: any[] = []

    if (challengeTypeEntityRelationships) {
      for (const ecogestureType of challengeEntity.relationships
        .availableEcogestures.data) {
        const unfilteredEcogestures = challengeTypeEntityRelationships.filter(
          relationship =>
            relationship._type === ECOGESTURE_DOCTYPE &&
            relationship._id === ecogestureType._id
        )
        if (unfilteredEcogestures && unfilteredEcogestures.length === 1)
          completeAvailableEcogestures.push(unfilteredEcogestures[0])
      }
    }
    // --> fluid dependancy for challenge

    // let filteredAvailableEcogestures = completeAvailableEcogestures.filter(
    //   eg =>
    //     fluidTypes &&
    //     (fluidTypes.includes(eg.fluidTypes[0]) ||
    //       fluidTypes.includes(eg.fluidTypes[1]) ||
    //       fluidTypes.includes(eg.fluidTypes[2]))
    // )

    let filteredAvailableEcogestures = completeAvailableEcogestures

    const fluidFilteredEcogestures = [...new Set(filteredAvailableEcogestures)]

    fluidFilteredEcogestures.forEach(eg => {
      if (unlockedEcogestures && !unlockedEcogestures.includes(eg._id)) {
        filteredAvailableEcogestures.push(eg)
      }
    })

    filteredAvailableEcogestures = [...new Set(filteredAvailableEcogestures)]

    if (filteredAvailableEcogestures.length < 2) {
      filteredAvailableEcogestures = completeAvailableEcogestures
    }

    const randomEcogesture =
      filteredAvailableEcogestures[
        Math.floor(Math.random() * filteredAvailableEcogestures.length)
      ]
    const randomEcogestures = filteredAvailableEcogestures.filter(
      eg => eg.pack === randomEcogesture.pack && eg.id !== randomEcogesture.id
    )

    randomEcogestures.push(randomEcogesture)

    const mappedChallengeType = new ChallengeType(
      challengeEntity._id,
      challengeEntity.type,
      challengeEntity.title,
      challengeEntity.description,
      challengeEntity.level,
      challengeEntity.duration,
      challengeEntity.fluidTypes,
      randomEcogestures
    )

    return mappedChallengeType
  }

  public mapToChallengeTypes(
    challengeEntities: ChallengeTypeEntity[],
    challengeTypeEntityRelationships?: any | null,
    unlockedEcogestures?: any,
    fluidTypes?: FluidType[]
  ): ChallengeType[] {
    return challengeEntities.map(challengeEntity =>
      this.mapToChallengeType(
        challengeEntity,
        challengeTypeEntityRelationships,
        unlockedEcogestures,
        fluidTypes
      )
    )
  }
}