import {
  IsNotEmpty,
  IsString,
  Length,
  IsDateString,
  IsNumber,
  Validate,
  Min,
  Max,
  ValidateNested,
  Allow,
  IsUUID,
  IsIn,
  IsOptional,
} from 'class-validator';

import { ObjectivePointEntity } from './game.entity';
import { CenterJSON } from '../shared/custom-validation';
import { FactionDTO } from '../faction/faction.dto';
import { CenterDTO, NodeSettingsDTO } from './game.json.dto';
import { Type } from 'class-transformer';

export class GameDTO {
  @IsOptional()
  id: string;
  @IsString()
  @IsNotEmpty()
  @Length(3, 30)
  name: string;
  @IsNotEmpty()
  @Length(1, 255)
  desc: string;
  @ValidateNested()
  @Type(() => CenterDTO)
  center: CenterDTO;
  @Allow()
  @ValidateNested()
  @Type(() => NodeSettingsDTO)
  nodesettings?: NodeSettingsDTO;
  @Allow()
  map?: JSON;
  @IsDateString()
  @IsNotEmpty()
  startdate: string;
  @IsDateString()
  @IsNotEmpty()
  enddate: string;
  @ValidateNested()
  @Type(() => FactionDTO)
  factions?: FactionDTO[];
  @ValidateNested()
  @Type(() => FlagboxDTO)
  objective_points?: FlagboxDTO[];
}

export class newGameDTO {
  @IsString()
  @IsNotEmpty()
  @Length(3, 30)
  name: string;
  @IsString()
  @IsNotEmpty()
  @Length(1, 255)
  desc: string;
  @IsNotEmpty()
  @Validate(CenterJSON)
  center: JSON;
  @IsDateString()
  @IsNotEmpty()
  startdate: string;
  @IsDateString()
  @IsNotEmpty()
  enddate: string;
}

export class GameStateDTO {
  @IsUUID('4')
  id: string;
  @IsIn(['CREATED', 'STARTED', 'PAUSED', 'ENDED'])
  state: string;
}

export class FlagboxDTO {
  @IsOptional()
  @IsUUID('4')
  objectivePointId: string;
  @IsString()
  @IsNotEmpty()
  @Length(7)
  objectivePointDescription: string;
  @IsNumber()
  objectivePointMultiplier: number;
}

export class FlagboxEventDTO {
  @IsString()
  @IsNotEmpty()
  @Length(7)
  node_id: string;
  @IsNumber()
  @Min(0)
  @Max(3)
  owner: number; // owner = 0, => first entry in faction db, owner = 1, => second entry etc
  @IsNumber()
  @Min(0)
  @Max(3)
  action: number; // 0=no capture ongoing, 1=captured, 2=capture ongoing
  @IsNumber()
  @Min(0)
  @Max(3)
  capture: number; // which faction is capturing, same logic as in owner with numbers
  oP_HistoryTimestamp?: string;
  objective_point?: ObjectivePointEntity;
}