import {
  IsEmail,
  IsInt,
  IsNotEmpty,
  IsOptional,
  IsPhoneNumber,

  IsPositive,

  IsString
} from "class-validator";
import { BeforeInsert, BeforeUpdate, Column, Entity, Index, PrimaryGeneratedColumn, TableInheritance } from "typeorm";
import { config } from '../../config';
import { ResponseParticipant } from '../responses/ResponseParticipant';
import { Address } from "./Address";

/**
 * Defines the Participant entity.
 * Participans can donate and therefor be associated with donation entities.
 */
@Entity()
@TableInheritance({ column: { name: "type", type: "varchar" } })
@Index(['email'])
export abstract class Participant {
  /**
   * Autogenerated unique id (primary key).
   */
  @PrimaryGeneratedColumn()
  @IsInt()
  id: number;

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

  /**
   * The participant's middle name.
   */
  @Column({ nullable: true })
  @IsOptional()
  @IsString()
  middlename?: string;

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

  /**
   * The participant's address.
   * This is a address object to prevent any formatting differences.
   */
  @Column(type => Address)
  address?: Address;

  /**
   * The participant's phone number.
   * This will be validated against the configured country phone numer syntax (default: international).
   */
  @Column({ nullable: true })
  @IsOptional()
  @IsPhoneNumber(config.phone_validation_countrycode)
  phone?: string;

  /**
   * The participant's email address.
   * Can be used to contact the participant.
   */
  @Column({ nullable: true })
  @IsOptional()
  @IsEmail()
  email?: string;

  /**
   * how the participant got into the system
   */
  @Column({ nullable: true, default: "backend" })
  @IsOptional()
  @IsString()
  created_via?: string;

  @Column({ type: 'bigint', nullable: true, readonly: true })
  @IsInt()
  @IsPositive()
  created_at: number;

  @Column({ type: 'bigint', nullable: true })
  @IsInt()
  @IsPositive()
  updated_at: number;

  @BeforeInsert()
  public setCreatedAt() {
    this.created_at = Math.floor(Date.now() / 1000);
    this.updated_at = Math.floor(Date.now() / 1000);
  }

  @BeforeUpdate()
  public setUpdatedAt() {
    this.updated_at = Math.floor(Date.now() / 1000);
  }

  /**
   * Turns this entity into it's response class.
   */
  public abstract toResponse(): ResponseParticipant;
}