import { IsInt, IsOptional, IsString } from "class-validator";
import { DistanceDonation } from '../entities/DistanceDonation';
import { Runner } from '../entities/Runner';
import { RunnerGroup } from '../entities/RunnerGroup';
import { RunnerTeam } from '../entities/RunnerTeam';
import { ResponseObjectType } from '../enums/ResponseObjectType';
import { IResponse } from './IResponse';
import { ResponseParticipant } from './ResponseParticipant';
import { ResponseSelfServiceDonation } from './ResponseSelfServiceDonation';

/**
 * Defines the runner selfservice response.
 * Why? B/C runner's are not allowed to view all information available to admin users.
*/
export class ResponseSelfServiceRunner extends ResponseParticipant implements IResponse {
    /**
    * The responseType.
    * This contains the type of class/entity this response contains.
    */
    responseType: ResponseObjectType = ResponseObjectType.SELFSERVICERUNNER;

    /**
     * The runner's currently ran distance in meters.
     */
    @IsInt()
    distance: number;

    /**
     * The runner's currently collected donations.
     */
    @IsInt()
    donationAmount: number;

    /**
     * The runner's group as a string (mix of org and team).
     */
    @IsString()
    group: string;

    /**
     * The runner's associated distance donations.
     */
    @IsString()
    distanceDonations: ResponseSelfServiceDonation[]

    /**
     * The runner's self-service jwt for auth.
     * Will only get delivered on registration/via email.
     */
    @IsString()
    @IsOptional()
    token: string;

    /**
     * Creates a ResponseRunner object from a runner.
     * @param runner The user the response shall be build for.
     */
    public constructor(runner: Runner) {
        super(runner);
        this.distance = runner.distance;
        this.donationAmount = runner.distanceDonationAmount;
        this.group = this.getTeamString(runner.group);
        this.distanceDonations = this.getDonations(runner.distanceDonations);
    }

    /**
     * Parses a runner's group into a string.
     * If the runner's group is a team: `org name/team name`
     * If the runner's group is an org: `org name`
     * @param group The group that shall get parsed to a string.
     */
    private getTeamString(group: RunnerGroup): string {
        if (group instanceof RunnerTeam) {
            return group.parentGroup.name + "/" + group.name;
        }
        return group.name;
    }

    /**
     * Converts all of the runner's donations to ResponseSelfServiceDonations.
     * @param donations The donations that shall be converted to ResponseSelfServiceDonations.
     */
    private getDonations(donations: DistanceDonation[]): ResponseSelfServiceDonation[] {
        let responseDonations = new Array<ResponseSelfServiceDonation>();
        for (let donation of donations) {
            responseDonations.push(new ResponseSelfServiceDonation(donation));
        }
        return responseDonations;
    }
}
