import { IsInt, IsOptional, IsPositive } from 'class-validator';
import { getConnection } from 'typeorm';
import { RunnerNotFoundError } from '../../../errors/RunnerErrors';
import { DistanceDonation } from '../../entities/DistanceDonation';
import { Runner } from '../../entities/Runner';
import { CreateDonation } from './CreateDonation';

/**
 * This class is used to create a new FixedDonation entity from a json body (post request).
 */
export class CreateDistanceDonation extends CreateDonation {

    /**
     * The donation's associated donor's id.
     * This is important to link donations to donors.
     */
    @IsInt()
    @IsPositive()
    donor: number;

    /**
     * The donation's paid amount in the smalles unit of your currency (default: euro cent).
     */
    @IsInt()
    @IsOptional()
    paidAmount?: number;

    /**
     * The donation's associated runner's id.
     * This is important to link the runner's distance ran to the donation.
     */
    @IsInt()
    @IsPositive()
    runner: number;

    /**
     * The donation's amount per distance (full kilometer aka 1000 meters).
     * The unit is your currency's smallest unit (default: euro cent).
     */
    @IsInt()
    @IsPositive()
    amountPerDistance: number;

    /**
     * Creates a new FixedDonation entity from this.
     */
    public async toEntity(): Promise<DistanceDonation> {
        let newDonation = new DistanceDonation;

        newDonation.amountPerDistance = this.amountPerDistance;
        newDonation.paidAmount = this.paidAmount;
        newDonation.donor = await this.getDonor();
        newDonation.runner = await this.getRunner();

        return newDonation;
    }

    /**
     * Gets a runner based on the runner id provided via this.runner.
     */
    public async getRunner(): Promise<Runner> {
        const runner = await getConnection().getRepository(Runner).findOne({ id: this.runner });
        if (!runner) {
            throw new RunnerNotFoundError();
        }
        return runner;
    }
}