import { Transform, Type } from 'class-transformer';
import {
  IsArray,
  IsDateString,
  IsInt,
  IsNotEmpty,
  IsOptional,
  IsString,
  IsUUID,
  Max,
  MaxLength,
  Matches,
  Min,
  ValidateIf,
  ValidateNested,
} from 'class-validator';

const toReportNumber = ({ value }: { value: unknown }) => {
  if (value === undefined || value === null) {
    return value;
  }

  if (typeof value === 'string' && value.trim() === '') {
    return value;
  }

  return typeof value === 'string' ? Number(value) : value;
};

export class ReportKeywordRankInputDto {
  @IsUUID()
  keywordId!: string;

  @Transform(toReportNumber)
  @IsInt()
  @Min(0, { message: 'Position must be 0 or higher' })
  @Max(100, { message: 'Position cannot exceed 100' })
  position!: number;
}

export class CreateReportDto {
  @IsUUID()
  clientId!: string;

  @Transform(({ value }) => (typeof value === 'string' ? value.trim() : value))
  @Matches(/^\d{4}-\d{2}-\d{2}$/)
  @IsDateString({ strict: true })
  reportStartDate!: string;

  @Transform(toReportNumber)
  @IsNotEmpty()
  @IsInt()
  @Min(0)
  businessMetricValue!: number;

  @Transform(toReportNumber)
  @IsNotEmpty()
  @IsInt()
  businessMetricGrowth!: number;

  @Transform(toReportNumber)
  @IsNotEmpty()
  @IsInt()
  @Min(0)
  traffic!: number;

  @Transform(toReportNumber)
  @IsNotEmpty()
  @IsInt()
  trafficGrowth!: number;

  @Transform(toReportNumber)
  @IsNotEmpty()
  @IsInt()
  @Min(0)
  backlinks!: number;

  @Transform(toReportNumber)
  @IsNotEmpty()
  @IsInt()
  @Min(0)
  newBacklinks!: number;

  @ValidateIf((_object, value) => value !== undefined)
  @IsString()
  @MaxLength(2000)
  notes?: string;

  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => ReportKeywordRankInputDto)
  keywordRanks?: ReportKeywordRankInputDto[];
}
