import { Type } from 'class-transformer';
import {
  IsArray,
  IsIn,
  IsInt,
  IsNotEmpty,
  IsObject,
  IsOptional,
  IsString,
  MaxLength,
  Min,
  ValidateNested,
} from 'class-validator';

export const NODE_TYPES = ['START', 'QUESTION', 'RESULT', 'INFO'] as const;

export class DecisionTreeNodeDto {
  /** Client-side identifier used to wire up edges before ids exist. */
  @IsString()
  @IsNotEmpty()
  key!: string;

  @IsIn(NODE_TYPES as unknown as string[])
  nodeType!: string;

  /** title, question, description, explanation, imagePath, reference. */
  @IsOptional()
  @IsObject()
  payload?: Record<string, any>;

  @IsOptional()
  @IsInt()
  @Min(0)
  orderIndex?: number;
}

export class DecisionTreeEdgeDto {
  @IsString()
  @IsNotEmpty()
  fromKey!: string;

  @IsString()
  @IsNotEmpty()
  toKey!: string;

  /** Option text the learner taps to follow this branch. */
  @IsOptional()
  @IsString()
  @MaxLength(255)
  label?: string;

  @IsOptional()
  @IsString()
  @MaxLength(512)
  condition?: string;

  @IsOptional()
  @IsInt()
  @Min(0)
  orderIndex?: number;
}

/** Replaces a tree's whole graph in one atomic call. */
export class SaveGraphDto {
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => DecisionTreeNodeDto)
  nodes!: DecisionTreeNodeDto[];

  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => DecisionTreeEdgeDto)
  edges!: DecisionTreeEdgeDto[];
}
