import {
  IsInt,
  IsNotEmpty,
  IsOptional,
  IsString
} from "class-validator";
import { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn, TableInheritance } from "typeorm";
import { GroupContact } from "./GroupContact";
import { Runner } from "./Runner";

/**
 * Defines the RunnerGroup entity.
 * This is used to group runners together (as the name suggests).
*/
@Entity()
@TableInheritance({ column: { name: "type", type: "varchar" } })
export abstract class RunnerGroup {
  /**
   * Autogenerated unique id (primary key).
   */
  @PrimaryGeneratedColumn()
  @IsInt()
  id: number;

  /**
   * The group's name.
   */
  @Column()
  @IsNotEmpty()
  @IsString()
  name: string;

  /**
   * The group's contact.
   * This is mostly a feature for the group managers and public relations.
   */
  @IsOptional()
  @ManyToOne(() => GroupContact, contact => contact.groups, { nullable: true })
  contact?: GroupContact;

  /**
   * The group's associated runners.
   * Used to link runners to a runner group.
   */
  @OneToMany(() => Runner, runner => runner.group, { nullable: true })
  runners: Runner[];

  /**
   * Returns the total distance ran by this group's runners based on all their valid scans.
  */
  @IsInt()
  public get distance(): number {
    return this.runners.reduce((sum, current) => sum + current.distance, 0);
  }

  /**
   * Returns the total donations a runner has collected based on his linked donations and distance ran.
  */
  @IsInt()
  public get distanceDonationAmount(): number {
    return this.runners.reduce((sum, current) => sum + current.distanceDonationAmount, 0);
  }
}