import {
  IsString,
  IsOptional,
  IsUUID,
  IsInt,
  IsNumber,
  IsBoolean,
  Min,
  Max,
  ValidateNested,
  IsArray,
  IsIn,
} from 'class-validator';
import { Type } from 'class-transformer';

// ==================== Result DTOs ====================

export class QueryResultDto {
  @IsUUID()
  cycleId: string;

  @IsOptional()
  @IsUUID()
  employeeId?: string;

  @IsOptional()
  @IsUUID()
  departmentId?: string;

  @IsOptional()
  @IsBoolean()
  @Type(() => Boolean)
  isPublished?: boolean;

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

  @IsOptional()
  @Type(() => Number)
  @IsInt()
  @Min(1)
  page?: number = 1;

  @IsOptional()
  @Type(() => Number)
  @IsInt()
  @Min(1)
  @Max(100)
  pageSize?: number = 20;
}

export class QueryMyResultsDto {
  @IsOptional()
  @Type(() => Number)
  @IsInt()
  @Min(1)
  page?: number = 1;

  @IsOptional()
  @Type(() => Number)
  @IsInt()
  @Min(1)
  @Max(100)
  pageSize?: number = 20;
}

export class ResultWeightsDto {
  @IsNumber()
  @Min(0)
  @Max(100)
  kpi: number;

  @IsNumber()
  @Min(0)
  @Max(100)
  e360: number;
}

export class CalculateResultsDto {
  @IsUUID()
  cycleId: string;

  @ValidateNested()
  @Type(() => ResultWeightsDto)
  weights: ResultWeightsDto;

  @IsOptional()
  @IsArray()
  @IsUUID('4', { each: true })
  employeeIds?: string[];
}

export class AssignGradeDto {
  @IsString()
  gradeCode: string;

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

export class PublishResultsDto {
  @IsOptional()
  @IsArray()
  @IsUUID('4', { each: true })
  employeeIds?: string[];

  @IsOptional()
  @IsBoolean()
  @Type(() => Boolean)
  notifyEmployees?: boolean;
}

export class ExportResultsDto {
  @IsUUID()
  cycleId: string;

  @IsOptional()
  @IsIn(['xlsx', 'csv'])
  format?: 'xlsx' | 'csv' = 'xlsx';

  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  fields?: string[];
}

export class UpdateResultRemarksDto {
  @IsOptional()
  @IsString()
  remarks?: string;
}

export class AppealResultDto {
  @IsString()
  reason: string;
}

export class SaveOverallCommentDto {
  @IsUUID()
  cycleId: string;

  @IsUUID()
  employeeId: string;

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

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

export class ResolveAppealDto {
  @IsString()
  response: string;

  @IsIn(['MAINTAIN', 'ADJUST'])
  action: 'MAINTAIN' | 'ADJUST';

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

  @IsOptional()
  @IsNumber()
  adjustedScore?: number;
}

// ==================== Response DTOs ====================

export class ResultResponseDto {
  id: string;
  cycleId: string;
  employeeId: string;
  organizationId?: string;
  kpiScore?: number;
  kpiWeight?: number;
  e360Score?: number;
  e360Weight?: number;
  totalScore?: number;
  proposedGradeCode?: string;
  proposedGradeName?: string;
  gradeCode?: string;
  gradeName?: string;
  confirmStatus?: string;
  appealReason?: string;
  appealResponse?: string;
  appealResolvedAt?: Date;
  selfOverallComment?: string;
  managerOverallComment?: string;
  isPublished: boolean;
  publishedAt?: Date;
  viewedByEmployee: boolean;
  viewedAt?: Date;
  remarks?: string;
  adjustmentLogs?: any[];
  createdAt: Date;
  updatedAt: Date;
}

export class ResultStatisticsDto {
  cycleId: string;
  totalEmployees: number;
  calculated: number;
  published: number;
  viewed: number;
  avgScore: number;
  gradeDistribution: {
    gradeCode: string;
    gradeName: string;
    count: number;
    percentage: number;
  }[];
  departmentComparison?: {
    departmentId: string;
    departmentName: string;
    avgScore: number;
    employeeCount: number;
  }[];
}
