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

import { ObjectivePointEntity } from './game.entity';
import { FactionDTO } from '../faction/faction.dto';
import { Type } from 'class-transformer';

export class NodeCoreSettingsDTO {
  @IsNumber()
  capture_time: number;
  @IsNumber()
  confirmation_time: number;
  @IsNumber()
  owner: number;
  @IsNumber()
  capture: number;
  @IsNumber()
  buttons_available: number;
  @IsNumber()
  heartbeat_interval: number;
}

export class CenterDTO {
  @IsNumber()
  lat: number;
  @IsNumber()
  lng: number;
}

export class NodeSettingsDTO {
  @ValidateNested()
  @Type(() => NodeCoreSettingsDTO)
  node_settings: NodeCoreSettingsDTO;
}

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;
  @ValidateNested()
  @Type(() => CenterDTO)
  center: CenterDTO;
  @IsDateString()
  @IsNotEmpty()
  startdate: string;
  @IsDateString()
  @IsNotEmpty()
  enddate: string;
  @Length(0, 65)
  image: string;
  @Allow()
  map?: JSON;
}

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

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

export class FlagboxEventDTO {
  @IsString()
  @IsNotEmpty()
  @Length(7, 7)
  node_id: string;
  @IsNumber()
  @Min(0)
  @Max(3)
  owner: number; // owner = 0, => no owner, owner = 1, => first entry in faction db
  @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?: number;
  objective_point?: ObjectivePointEntity;
}