import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { IsString, IsOptional, IsInt, Min, IsBoolean, IsArray, ValidateNested, IsEnum } from 'class-validator';
import { Type } from 'class-transformer';

// Enums
export enum ResearchFieldDto {
  BOMBER = 'BOMBER',
  CHIRURGEON = 'CHIRURGEON',
  MUTAGENIST = 'MUTAGENIST',
  TOXICOLOGIST = 'TOXICOLOGIST',
}

// Request DTOs

export class UpdateVialsDto {
  @ApiProperty({ description: 'New current vial count' })
  @IsInt()
  @Min(0)
  current: number;
}

export class AddFormulaDto {
  @ApiProperty({ description: 'Equipment ID for the formula' })
  @IsString()
  equipmentId: string;

  @ApiPropertyOptional({ description: 'Level at which the formula was learned', default: 1 })
  @IsOptional()
  @IsInt()
  @Min(1)
  learnedAt?: number;

  @ApiPropertyOptional({ description: 'Source of the formula (e.g., "Purchased", "Found")' })
  @IsOptional()
  @IsString()
  formulaSource?: string;
}

export class PrepareItemDto {
  @ApiProperty({ description: 'Equipment ID of the item to prepare' })
  @IsString()
  equipmentId: string;

  @ApiProperty({ description: 'Number of items to prepare', minimum: 1 })
  @IsInt()
  @Min(1)
  quantity: number;
}

export class DailyPreparationDto {
  @ApiProperty({ description: 'Items to prepare during daily preparation', type: [PrepareItemDto] })
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => PrepareItemDto)
  items: PrepareItemDto[];
}

export class QuickAlchemyDto {
  @ApiProperty({ description: 'Equipment ID of the item to create' })
  @IsString()
  equipmentId: string;
}

export class CraftAlchemyDto {
  @ApiProperty({ description: 'Equipment ID of the item to craft' })
  @IsString()
  equipmentId: string;

  @ApiProperty({ description: 'Number of items to craft', minimum: 1 })
  @IsInt()
  @Min(1)
  quantity: number;
}

export class InitializeAlchemyDto {
  @ApiPropertyOptional({ description: 'Research field', enum: ResearchFieldDto })
  @IsOptional()
  @IsEnum(ResearchFieldDto)
  researchField?: ResearchFieldDto;

  @ApiProperty({ description: 'Maximum versatile vials' })
  @IsInt()
  @Min(0)
  versatileVialsMax: number;

  @ApiProperty({ description: 'Maximum advanced alchemy batch size' })
  @IsInt()
  @Min(0)
  advancedAlchemyMax: number;
}

// Response DTOs

export class FormulaResponseDto {
  @ApiProperty()
  id: string;

  @ApiProperty()
  equipmentId: string;

  @ApiProperty()
  name: string;

  @ApiPropertyOptional()
  nameGerman?: string;

  @ApiProperty()
  learnedAt: number;

  @ApiPropertyOptional()
  formulaSource?: string;

  @ApiPropertyOptional({ description: 'Equipment details if loaded' })
  equipment?: any;
}

export class PreparedItemResponseDto {
  @ApiProperty()
  id: string;

  @ApiProperty()
  equipmentId: string;

  @ApiProperty()
  name: string;

  @ApiPropertyOptional()
  nameGerman?: string;

  @ApiProperty()
  quantity: number;

  @ApiProperty()
  isQuickAlchemy: boolean;

  @ApiProperty({ description: 'Whether the item is infused (expires on rest) or permanent' })
  isInfused: boolean;

  @ApiProperty()
  createdAt: string;

  @ApiPropertyOptional({ description: 'Equipment details if loaded' })
  equipment?: any;
}

export class AlchemyStateResponseDto {
  @ApiProperty()
  id: string;

  @ApiProperty()
  characterId: string;

  @ApiPropertyOptional({ enum: ResearchFieldDto })
  researchField?: ResearchFieldDto;

  @ApiProperty()
  versatileVialsCurrent: number;

  @ApiProperty()
  versatileVialsMax: number;

  @ApiProperty()
  advancedAlchemyBatch: number;

  @ApiProperty()
  advancedAlchemyMax: number;

  @ApiPropertyOptional()
  lastRestAt?: string;
}

export class FullAlchemyResponseDto {
  @ApiPropertyOptional({ type: AlchemyStateResponseDto })
  state?: AlchemyStateResponseDto;

  @ApiProperty({ type: [FormulaResponseDto] })
  formulas: FormulaResponseDto[];

  @ApiProperty({ type: [PreparedItemResponseDto] })
  preparedItems: PreparedItemResponseDto[];
}
