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]) } } let filteredAvailableEcogestures = completeAvailableEcogestures.filter( eg => fluidTypes && (fluidTypes.includes(eg.fluidTypes[0]) || fluidTypes.includes(eg.fluidTypes[1]) || fluidTypes.includes(eg.fluidTypes[2])) ) 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 randomEcogestures = filteredAvailableEcogestures .sort(() => Math.random() - 0.5) .splice(0, 2) 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 ) ) } }