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

class GiteaLabelDto {
  @IsString()
  @MinLength(1)
  @MaxLength(255)
  name!: string;
}

class GiteaRepoDto {
  @IsString()
  @MinLength(1)
  @MaxLength(512)
  full_name!: string;
}

class GiteaBranchRefDto {
  @IsString()
  @MinLength(1)
  @MaxLength(255)
  ref!: string;
}

class GiteaHeadDto {
  @IsString()
  @MinLength(7)
  @MaxLength(128)
  sha!: string;
}

class GiteaPullRequestDto {
  @IsInt()
  @Min(1)
  number!: number;

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

  @ValidateNested()
  @Type(() => GiteaBranchRefDto)
  base!: GiteaBranchRefDto;

  @ValidateNested()
  @Type(() => GiteaHeadDto)
  head!: GiteaHeadDto;

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

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

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

class GiteaSenderDto {
  @IsString()
  @MinLength(1)
  @MaxLength(255)
  login!: string;
}

export class GiteaPrWebhookDto {
  @IsString()
  @IsIn(["pull_request"])
  @MaxLength(64)
  type!: string;

  @IsString()
  @IsIn(["opened", "labeled", "synchronize"])
  @MaxLength(64)
  action!: "opened" | "labeled" | "synchronize";

  @ValidateNested()
  @Type(() => GiteaRepoDto)
  repository!: GiteaRepoDto;

  @ValidateNested()
  @Type(() => GiteaPullRequestDto)
  pull_request!: GiteaPullRequestDto;

  @IsOptional()
  @ValidateNested()
  @Type(() => GiteaLabelDto)
  label?: GiteaLabelDto;

  @IsOptional()
  @ValidateNested()
  @Type(() => GiteaSenderDto)
  sender?: GiteaSenderDto;

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