import { Type } from 'class-transformer';
import {
  IsArray,
  IsInt,
  IsISO8601,
  IsObject,
  IsOptional,
  IsString,
  ValidateNested,
} from 'class-validator';

class ScopeDto {
  @IsString() orgId!: string;
  @IsString() appId!: string;
  @IsOptional() @IsString() buId?: string;
  @IsOptional() @IsString() tenantId?: string;
  @IsOptional() @IsString() workspaceId?: string;
  @IsOptional() @IsString() projectId?: string;
  @IsOptional() @IsString() userScopeId?: string;
}

class ChannelDto {
  @IsString() type!: string;
  @IsOptional() @IsString() externalChannelId?: string;
  @IsOptional() @IsObject() capabilityContract?: Record<string, unknown>;
}

class SourceDto {
  @IsString() handleKind!: string;
  @IsString() externalId!: string;
  @IsOptional() @IsString() displayName?: string;
}

class ThreadDto {
  @IsOptional() @IsString() externalThreadId?: string;
  @IsOptional() @IsString() subject?: string;
}

class PartDto {
  @IsString() kind!: string;
  @IsOptional() @IsString() bodyText?: string;
  @IsOptional() @IsString() contentRef?: string;
  @IsOptional() @IsString() mimeType?: string;
  @IsOptional() @IsInt() sizeBytes?: number;
}

/** Validates the POST /v1/interactions/ingest body (conforms to IngestInteractionRequest). */
export class IngestRequestDto {
  @ValidateNested() @Type(() => ScopeDto) scope!: ScopeDto;
  @ValidateNested() @Type(() => ChannelDto) channel!: ChannelDto;
  @ValidateNested() @Type(() => SourceDto) source!: SourceDto;
  @IsOptional() @IsString() kind?: string;
  @IsOptional() @ValidateNested() @Type(() => ThreadDto) thread?: ThreadDto;
  @IsArray() @ValidateNested({ each: true }) @Type(() => PartDto) parts!: PartDto[];
  @IsISO8601() occurredAt!: string;
  @IsOptional() @IsString() providerEventId?: string;
  @IsOptional() @IsObject() metadata?: Record<string, unknown>;
}
