import { IsInt, IsObject } from 'class-validator';
import { getConnectionManager } from 'typeorm';
import { RunnerGroupNotFoundError } from '../../errors/RunnerGroupErrors';
import { RunnerOrganisationWrongTypeError } from '../../errors/RunnerOrganisationErrors';
import { RunnerTeamNeedsParentError } from '../../errors/RunnerTeamErrors';
import { Runner } from '../entities/Runner';
import { RunnerGroup } from '../entities/RunnerGroup';
import { CreateParticipant } from './CreateParticipant';

/**
 * This class is used to update a Runner entity (via put request).
 */
export class UpdateRunner extends CreateParticipant {

    /**
     * The updated runner's id.
     * This shouldn't have changed but it is here in case anyone ever wants to enable id changes (whyever they would want to).
     */
    @IsInt()
    id: number;

    /**
     * The updated runner's new team/org.
     * Just has to contain the group's id -everything else won't be checked or changed.
     */
    @IsObject()
    group: RunnerGroup;

    /**
     * Updates a provided Runner entity based on this.
     */
    public async updateRunner(runner: Runner): Promise<Runner> {
        runner.firstname = this.firstname;
        runner.middlename = this.middlename;
        runner.lastname = this.lastname;
        runner.phone = this.phone;
        runner.email = this.email;
        runner.group = await this.getGroup();
        runner.address = await this.getAddress();

        return runner;
    }

    /**
     * Loads the updated runner's group based on it's id.
     */
    public async getGroup(): Promise<RunnerGroup> {
        if (this.group === undefined || this.group === null) {
            throw new RunnerTeamNeedsParentError();
        }
        if (!isNaN(this.group.id)) {
            let group = await getConnectionManager().get().getRepository(RunnerGroup).findOne({ id: this.group.id });
            if (!group) { throw new RunnerGroupNotFoundError; }
            return group;
        }

        throw new RunnerOrganisationWrongTypeError;
    }
}