text: const { Model } = require('flitter-orm')
  
  /**
   * Team Model
   * -------------------------------------------------------------
   * A model representing a single team in the game.
   *
   * @extends Model
   */
  class Team extends Model {
      static get services() {
          return [...super.services, 'output', 'models']
      }
  
      /**
       * Define the flitter-orm schema of the model.
       */
      static get schema() {
          return {
              user_id: String,
              team_name: String,
              team_num: Number,
              player_ids: [String],
          }
      }
  
      /**
       * Look up or create a team for the given user.
       * @param {User} user
       * @return {Promise<Team>}
       */
      static async getForUser(user) {
          // try to find an existing team first
          const existing_team = await this.findOne({ user_id: user.id })
          if ( existing_team ) return existing_team
  
          // otherwise create a team for the user
          const new_team = new this({
              user_id: user.id,
              team_name: `${user.uid}'s team`,
              player_ids: [],
          })
  
          // Generate the next team number
          const highest_num_team = await this.sort('-team_num').findOne()
          if ( highest_num_team ) {
              new_team.team_num = highest_num_team.team_num + 1
          } else {
              new_team.team_num = 1
          }
  
          await new_team.save()
          return new_team
      }
  
      /**
       * returns the lineup
       * @return Promise<Lineup>
       */
      async lineup() {
          const Lineup = this.models.get('Lineup')
          return Lineup.get_and_update_for_team(this)
      }
  
      /**
       * Returns the players associated with the team.
       * @return Promise<Array<Player>>
       */
      async players() {
          const Player = this.models.get('Player')
          return Player.find({
              _id: {
                  $in: this.player_ids.map(x => Player.to_object_id(x))
              }
          })
      }
  
      /**
       * Get the cumulative data for the team (total wins, losses, points scored & allowed)
       * @return object
       */
      async cumulative_data() {
          const Matchup = this.models.get('Matchup')
          const home_matchups = await Matchup.find({ home_team_id: this.id })
          const visitor_matchups = await Matchup.find({ visitor_team_id: this.id })
  
          const data = {
              wins: 0,
              losses: 0,
              points_scored: 0,
              points_allowed: 0,
          }
  
          for ( const matchup of home_matchups ) {
              if ( !matchup.complete ) continue
  
              data.points_scored += matchup.home_team_score
              data.points_allowed += matchup.visitor_team_score
  
              if ( matchup.home_team_score > matchup.visitor_team_score ) {
                  data.wins += 1
              } else {
                  data.losses += 0
              }
          }
  
          for ( const matchup of visitor_matchups ) {
              if ( !matchup.complete ) continue
  
              data.points_scored += matchup.visitor_team_score
              data.points_allowed += matchup.home_team_score
  
              if ( matchup.visitor_team_score > matchup.home_team_score ) {
                  data.wins += 1
              } else {
                  data.losses += 0
              }
          }
  
          return data
      }
  
      /**
       * Cast the team to the format expected for the API.
       * @return Promise<object>
       */
      async to_api() {
          let user
          try {
              const User = this.models.get('auth:User')
              user = await User.findById(this.user_id)
          } catch(e) {}
  
          return {
              user_id: this.user_id,
              user_display: user?.uid || 'Unknown User',
              team_name: this.team_name,
              team_num: this.team_num,
          }
      }
  }
  
  module.exports = exports = Team
  