import {
  IsString,
  IsOptional,
  IsEnum,
  IsUUID,
  IsInt,
  Min,
  Max,
  IsArray,
  IsISO8601,
  IsObject,
  Matches,
} from 'class-validator';
import { Type } from 'class-transformer';
import {
  DevItemType,
  DevItemStatus,
  DevItemPriority,
  DevItemSeverity,
} from '@prisma/client';

export class QueryDevItemDto {
  @IsOptional()
  @Type(() => Number)
  @IsInt()
  @Min(1)
  page?: number = 1;

  @IsOptional()
  @Type(() => Number)
  @IsInt()
  @Min(1)
  @Max(100)
  pageSize?: number = 20;

  @IsOptional()
  @IsEnum(DevItemType)
  itemType?: DevItemType;

  @IsOptional()
  @IsEnum(DevItemStatus)
  status?: DevItemStatus;

  @IsOptional()
  @IsUUID()
  ownerId?: string;

  @IsOptional()
  @IsUUID()
  parentId?: string;

  @IsOptional()
  @IsEnum(DevItemPriority)
  priority?: DevItemPriority;

  @IsOptional()
  @IsString()
  keyword?: string;
}

export class CreateDevItemDto {
  @IsString()
  title: string;

  @IsOptional()
  @IsString()
  description?: string;

  @IsEnum(DevItemType)
  itemType: DevItemType;

  @IsEnum(DevItemPriority)
  priority: DevItemPriority;

  @IsOptional()
  @IsEnum(DevItemSeverity)
  severity?: DevItemSeverity;

  @IsOptional()
  @IsString()
  @Matches(/^[A-Za-z0-9 _-]+$/)
  moduleKey?: string;

  @IsOptional()
  @IsUUID()
  parentId?: string;

  @IsUUID()
  ownerId: string;

  @IsOptional()
  @IsISO8601()
  startAt?: string;

  @IsOptional()
  @IsISO8601()
  devEtaAt?: string;

  @IsOptional()
  @IsISO8601()
  testEtaAt?: string;

  @IsOptional()
  @IsISO8601()
  etaAt?: string;

  @IsOptional()
  @IsObject()
  content?: Record<string, unknown>;

  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  labels?: string[];
}

export class UpdateDevItemDto {
  @IsOptional()
  @IsString()
  title?: string;

  @IsOptional()
  @IsString()
  description?: string;

  @IsOptional()
  @IsEnum(DevItemPriority)
  priority?: DevItemPriority;

  @IsOptional()
  @IsEnum(DevItemSeverity)
  severity?: DevItemSeverity;

  @IsOptional()
  @IsUUID()
  ownerId?: string;

  @IsOptional()
  @IsISO8601()
  startAt?: string;

  @IsOptional()
  @IsISO8601()
  devEtaAt?: string;

  @IsOptional()
  @IsISO8601()
  testEtaAt?: string;

  @IsOptional()
  @IsISO8601()
  etaAt?: string;

  @IsOptional()
  @IsObject()
  content?: Record<string, unknown>;

  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  labels?: string[];
}

export class UpdateDevItemStatusDto {
  @IsEnum(DevItemStatus)
  status: DevItemStatus;
}
