/**
 * Ticket DTOs - Data Transfer Objects para Tickets de No Conformidad
 *
 * Representa no conformidades detectadas en inspecciones de calidad.
 *
 * @module Quality (MAI-009)
 */

import {
  IsString,
  IsUUID,
  IsOptional,
  IsEnum,
  IsNumber,
  IsDateString,
  MaxLength,
  MinLength,
  Min,
} from 'class-validator';

/**
 * Severidad de la no conformidad
 */
export enum NCSeverity {
  MINOR = 'minor',
  MAJOR = 'major',
  CRITICAL = 'critical',
}

/**
 * Estado de la no conformidad
 */
export enum NCStatus {
  OPEN = 'open',
  IN_PROGRESS = 'in_progress',
  CLOSED = 'closed',
  VERIFIED = 'verified',
}

/**
 * Prioridad del ticket postventa
 */
export enum TicketPriority {
  URGENT = 'urgent',
  HIGH = 'high',
  MEDIUM = 'medium',
  LOW = 'low',
}

/**
 * Estado del ticket postventa
 */
export enum TicketStatus {
  CREATED = 'created',
  ASSIGNED = 'assigned',
  IN_PROGRESS = 'in_progress',
  RESOLVED = 'resolved',
  CLOSED = 'closed',
  CANCELLED = 'cancelled',
}

/**
 * Categoria del ticket postventa
 */
export enum TicketCategory {
  PLUMBING = 'plumbing',
  ELECTRICAL = 'electrical',
  FINISHES = 'finishes',
  CARPENTRY = 'carpentry',
  STRUCTURAL = 'structural',
  OTHER = 'other',
}

// ============================================================================
// NON-CONFORMITY DTOs (Internal Quality Issues)
// ============================================================================

/**
 * DTO para crear una nueva no conformidad
 */
export class CreateNonConformityDto {
  @IsOptional()
  @IsUUID()
  inspectionId?: string;

  @IsUUID()
  loteId: string;

  @IsDateString()
  detectionDate: string;

  @IsString()
  @MaxLength(100)
  category: string;

  @IsEnum(NCSeverity)
  severity: NCSeverity;

  @IsString()
  @MinLength(10)
  @MaxLength(2000)
  description: string;

  @IsOptional()
  @IsString()
  @MaxLength(2000)
  rootCause?: string;

  @IsOptional()
  @IsString()
  @MaxLength(500)
  photoUrl?: string;

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

  @IsOptional()
  @IsDateString()
  dueDate?: string;
}

/**
 * DTO para actualizar una no conformidad existente
 */
export class UpdateNonConformityDto {
  @IsOptional()
  @IsUUID()
  loteId?: string;

  @IsOptional()
  @IsDateString()
  detectionDate?: string;

  @IsOptional()
  @IsString()
  @MaxLength(100)
  category?: string;

  @IsOptional()
  @IsEnum(NCSeverity)
  severity?: NCSeverity;

  @IsOptional()
  @IsString()
  @MinLength(10)
  @MaxLength(2000)
  description?: string;

  @IsOptional()
  @IsString()
  @MaxLength(2000)
  rootCause?: string;

  @IsOptional()
  @IsString()
  @MaxLength(500)
  photoUrl?: string;

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

  @IsOptional()
  @IsEnum(NCStatus)
  status?: NCStatus;

  @IsOptional()
  @IsDateString()
  dueDate?: string;
}

/**
 * DTO para cerrar una no conformidad
 */
export class CloseNonConformityDto {
  @IsOptional()
  @IsString()
  @MaxLength(500)
  closurePhotoUrl?: string;

  @IsOptional()
  @IsString()
  @MaxLength(2000)
  closureNotes?: string;
}

/**
 * DTO para verificar cierre de una no conformidad
 */
export class VerifyNonConformityDto {
  @IsOptional()
  @IsString()
  @MaxLength(2000)
  verificationNotes?: string;
}

/**
 * DTO para filtrar no conformidades en listados
 */
export class NonConformityFiltersDto {
  @IsOptional()
  @IsUUID()
  inspectionId?: string;

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

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

  @IsOptional()
  @IsEnum(NCSeverity)
  severity?: NCSeverity;

  @IsOptional()
  @IsEnum(NCStatus)
  status?: NCStatus;

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

  @IsOptional()
  @IsDateString()
  detectionDateFrom?: string;

  @IsOptional()
  @IsDateString()
  detectionDateTo?: string;

  @IsOptional()
  @IsDateString()
  dueDateFrom?: string;

  @IsOptional()
  @IsDateString()
  dueDateTo?: string;

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

  @IsOptional()
  @IsNumber()
  @Min(1)
  page?: number;

  @IsOptional()
  @IsNumber()
  @Min(1)
  limit?: number;

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

  @IsOptional()
  @IsEnum(['ASC', 'DESC'])
  sortOrder?: 'ASC' | 'DESC';
}

/**
 * DTO de respuesta para una no conformidad
 */
export class NonConformityResponseDto {
  id: string;
  tenantId: string;
  inspectionId?: string;
  inspection?: {
    id: string;
    inspectionNumber: string;
    inspectionDate: Date;
  };
  loteId: string;
  ncNumber: string;
  detectionDate: Date;
  category: string;
  severity: NCSeverity;
  description: string;
  rootCause?: string;
  photoUrl?: string;
  contractorId?: string;
  status: NCStatus;
  dueDate?: Date;
  closedAt?: Date;
  closedById?: string;
  closedBy?: {
    id: string;
    firstName: string;
    lastName: string;
  };
  verifiedAt?: Date;
  verifiedById?: string;
  verifiedBy?: {
    id: string;
    firstName: string;
    lastName: string;
  };
  closurePhotoUrl?: string;
  closureNotes?: string;
  correctiveActionsCount?: number;
  createdAt: Date;
  createdById?: string;
  createdBy?: {
    id: string;
    firstName: string;
    lastName: string;
  };
  updatedAt: Date;
  updatedById?: string;
}

// ============================================================================
// POST-SALE TICKET DTOs (External Customer Issues)
// ============================================================================

/**
 * DTO para crear un nuevo ticket postventa
 */
export class CreateTicketDto {
  @IsUUID()
  loteId: string;

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

  @IsEnum(TicketCategory)
  category: TicketCategory;

  @IsEnum(TicketPriority)
  priority: TicketPriority;

  @IsString()
  @MinLength(5)
  @MaxLength(255)
  title: string;

  @IsString()
  @MinLength(10)
  @MaxLength(2000)
  description: string;

  @IsOptional()
  @IsString()
  @MaxLength(500)
  photoUrl?: string;

  @IsNumber()
  @Min(1)
  slaHours: number;

  @IsOptional()
  @IsString()
  @MaxLength(200)
  contactName?: string;

  @IsOptional()
  @IsString()
  @MaxLength(20)
  contactPhone?: string;
}

/**
 * DTO para actualizar un ticket postventa existente
 */
export class UpdateTicketDto {
  @IsOptional()
  @IsEnum(TicketCategory)
  category?: TicketCategory;

  @IsOptional()
  @IsEnum(TicketPriority)
  priority?: TicketPriority;

  @IsOptional()
  @IsString()
  @MinLength(5)
  @MaxLength(255)
  title?: string;

  @IsOptional()
  @IsString()
  @MinLength(10)
  @MaxLength(2000)
  description?: string;

  @IsOptional()
  @IsString()
  @MaxLength(500)
  photoUrl?: string;

  @IsOptional()
  @IsEnum(TicketStatus)
  status?: TicketStatus;

  @IsOptional()
  @IsString()
  @MaxLength(200)
  contactName?: string;

  @IsOptional()
  @IsString()
  @MaxLength(20)
  contactPhone?: string;
}

/**
 * DTO para resolver un ticket postventa
 */
export class ResolveTicketDto {
  @IsString()
  @MinLength(10)
  @MaxLength(2000)
  resolutionNotes: string;

  @IsOptional()
  @IsString()
  @MaxLength(500)
  resolutionPhotoUrl?: string;
}

/**
 * DTO para registrar satisfaccion del cliente
 */
export class RecordSatisfactionDto {
  @IsNumber()
  @Min(1)
  satisfactionRating: number;

  @IsOptional()
  @IsString()
  @MaxLength(2000)
  satisfactionComment?: string;
}

/**
 * DTO para filtrar tickets postventa en listados
 */
export class TicketFiltersDto {
  @IsOptional()
  @IsUUID()
  loteId?: string;

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

  @IsOptional()
  @IsEnum(TicketCategory)
  category?: TicketCategory;

  @IsOptional()
  @IsEnum(TicketPriority)
  priority?: TicketPriority;

  @IsOptional()
  @IsEnum(TicketStatus)
  status?: TicketStatus;

  @IsOptional()
  @IsDateString()
  createdFrom?: string;

  @IsOptional()
  @IsDateString()
  createdTo?: string;

  @IsOptional()
  @IsDateString()
  slaDueFrom?: string;

  @IsOptional()
  @IsDateString()
  slaDueTo?: string;

  @IsOptional()
  slaBreached?: boolean;

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

  @IsOptional()
  @IsNumber()
  @Min(1)
  page?: number;

  @IsOptional()
  @IsNumber()
  @Min(1)
  limit?: number;

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

  @IsOptional()
  @IsEnum(['ASC', 'DESC'])
  sortOrder?: 'ASC' | 'DESC';
}

/**
 * DTO de respuesta para un ticket postventa
 */
export class TicketResponseDto {
  id: string;
  tenantId: string;
  loteId: string;
  derechohabienteId?: string;
  ticketNumber: string;
  category: TicketCategory;
  priority: TicketPriority;
  title: string;
  description: string;
  photoUrl?: string;
  status: TicketStatus;
  slaHours: number;
  slaDueAt: Date;
  slaBreached: boolean;
  assignedAt?: Date;
  resolvedAt?: Date;
  closedAt?: Date;
  resolutionNotes?: string;
  resolutionPhotoUrl?: string;
  satisfactionRating?: number;
  satisfactionComment?: string;
  contactName?: string;
  contactPhone?: string;
  assignmentsCount?: number;
  createdAt: Date;
  createdById?: string;
  createdBy?: {
    id: string;
    firstName: string;
    lastName: string;
  };
  updatedAt: Date;
  updatedById?: string;
}
