import { IsInt, IsOptional } from 'class-validator';
import { getConnection } from 'typeorm';
import { RunnerTeamNotFoundError } from '../../../errors/RunnerTeamErrors';
import { Address } from '../../entities/Address';
import { Runner } from '../../entities/Runner';
import { RunnerGroup } from '../../entities/RunnerGroup';
import { RunnerTeam } from '../../entities/RunnerTeam';
import { CreateParticipant } from './CreateParticipant';

/**
 * This classed is used to create a new Runner entity from a json body (post request).
 */
export class CreateSelfServiceRunner extends CreateParticipant {

    /**
     * The new runner's team's id.
     * The team has to be a part of the runner's org.
     * The team property may get ignored.
     * If no team get's provided the runner's group will be their org.
     */
    @IsInt()
    @IsOptional()
    team?: number;

    /**
     * Creates a new Runner entity from this.
     */
    public async toEntity(group: RunnerGroup): Promise<Runner> {
        let newRunner: Runner = new Runner();

        newRunner.created_via = "selfservice";
        newRunner.firstname = this.firstname;
        newRunner.middlename = this.middlename;
        newRunner.lastname = this.lastname;
        newRunner.phone = this.phone;
        newRunner.email = this.email;
        newRunner.group = await this.getGroup(group);
        newRunner.address = this.address;
        Address.validate(newRunner.address);

        return newRunner;
    }

    /**
     * Gets the new runner's group by it's id.
     */
    public async getGroup(group: RunnerGroup): Promise<RunnerGroup> {
        if (!this.team) {
            return group;
        }
        const team = await getConnection().getRepository(RunnerTeam).findOne({ id: this.team }, { relations: ["parentGroup"] });
        if (!team) { throw new RunnerTeamNotFoundError(); }
        if (team.parentGroup.id != group.id) { throw new RunnerTeamNotFoundError(); }
        return team;
    }
}