import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import {
  IsArray, IsBoolean, IsIn, IsInt, IsOptional, IsString, IsUUID, Matches, Max, MaxLength, Min,
  ValidateNested,
} from 'class-validator';

export const TIPOS_MOTIVO = ['perdida', 'descarte', 'churn'] as const;
export const PRIORIDADES_SLA = ['alta', 'media', 'baja'] as const;

// ── Orígenes ──────────────────────────────────────────────────────────────────

export class CreateOrigenDto {
  @ApiProperty({ example: 'TIKTOK', description: 'Identificador estable; es lo que agrupan los reportes por canal' })
  @IsString()
  @MaxLength(40)
  @Matches(/^[A-Z0-9_]+$/, { message: 'El código va en MAYÚSCULAS, sin espacios ni acentos (ej: META_ADS)' })
  codigo: string;

  @ApiProperty({ example: 'TikTok' })
  @IsString()
  @MaxLength(100)
  descripcion: string;

  @ApiPropertyOptional({ example: 11 })
  @IsInt()
  @Min(0)
  @IsOptional()
  orden?: number;
}

export class UpdateOrigenDto {
  @ApiPropertyOptional()
  @IsString()
  @MaxLength(100)
  @IsOptional()
  descripcion?: string;

  @ApiPropertyOptional()
  @IsInt()
  @Min(0)
  @IsOptional()
  orden?: number;

  @ApiPropertyOptional()
  @IsBoolean()
  @IsOptional()
  activo?: boolean;
}

// ── Motivos ───────────────────────────────────────────────────────────────────

export class CreateMotivoDto {
  @ApiProperty({ enum: TIPOS_MOTIVO, description: 'perdida = oportunidad · descarte = lead · churn = baja de contrato' })
  @IsIn(TIPOS_MOTIVO as unknown as string[])
  tipo: string;

  @ApiProperty({ example: 'Entrega muy lenta' })
  @IsString()
  @MaxLength(100)
  descripcion: string;

  @ApiPropertyOptional()
  @IsInt()
  @Min(0)
  @IsOptional()
  orden?: number;
}

export class UpdateMotivoDto {
  @ApiPropertyOptional()
  @IsString()
  @MaxLength(100)
  @IsOptional()
  descripcion?: string;

  @ApiPropertyOptional()
  @IsInt()
  @Min(0)
  @IsOptional()
  orden?: number;

  @ApiPropertyOptional()
  @IsBoolean()
  @IsOptional()
  activo?: boolean;
}

// ── Calendarios ───────────────────────────────────────────────────────────────

export class TramoHorarioDto {
  @ApiProperty({ example: 1, description: '0 = domingo' })
  @IsInt()
  @Min(0)
  @Max(6)
  dia: number;

  @ApiProperty({ example: '08:00' })
  @Matches(/^([01]\d|2[0-3]):[0-5]\d$/, { message: 'La hora va en formato HH:mm (ej: 08:00)' })
  desde: string;

  @ApiProperty({ example: '18:00' })
  @Matches(/^([01]\d|2[0-3]):[0-5]\d$/, { message: 'La hora va en formato HH:mm (ej: 18:00)' })
  hasta: string;
}

export class CreateCalendarioDto {
  @ApiProperty({ example: 'Horario de verano' })
  @IsString()
  @MaxLength(100)
  nombre: string;

  @ApiPropertyOptional({ example: 'America/Asuncion', default: 'America/Asuncion' })
  @IsString()
  @MaxLength(40)
  @IsOptional()
  zona_horaria?: string;

  @ApiProperty({ type: [TramoHorarioDto] })
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => TramoHorarioDto)
  horario: TramoHorarioDto[];

  @ApiPropertyOptional({ type: [String], example: ['2026-12-25', '2027-01-01'], description: 'Fechas ISO que no cuentan para el SLA' })
  @IsArray()
  @IsString({ each: true })
  @IsOptional()
  feriados?: string[];

  @ApiPropertyOptional({ description: 'Pasa a ser el calendario por defecto de la empresa' })
  @IsBoolean()
  @IsOptional()
  es_default?: boolean;
}

export class UpdateCalendarioDto {
  @ApiPropertyOptional()
  @IsString()
  @MaxLength(100)
  @IsOptional()
  nombre?: string;

  @ApiPropertyOptional()
  @IsString()
  @MaxLength(40)
  @IsOptional()
  zona_horaria?: string;

  @ApiPropertyOptional({ type: [TramoHorarioDto] })
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => TramoHorarioDto)
  @IsOptional()
  horario?: TramoHorarioDto[];

  @ApiPropertyOptional({ type: [String] })
  @IsArray()
  @IsString({ each: true })
  @IsOptional()
  feriados?: string[];

  @ApiPropertyOptional()
  @IsBoolean()
  @IsOptional()
  es_default?: boolean;

  @ApiPropertyOptional()
  @IsBoolean()
  @IsOptional()
  activo?: boolean;
}

// ── Políticas de SLA ──────────────────────────────────────────────────────────

export class CreateSlaDto {
  @ApiProperty({ example: 'Crítica mayoristas' })
  @IsString()
  @MaxLength(100)
  nombre: string;

  @ApiProperty({ enum: PRIORIDADES_SLA })
  @IsIn(PRIORIDADES_SLA as unknown as string[])
  prioridad: string;

  @ApiPropertyOptional({ description: 'NULL = aplica a cualquier cliente. Con valor, gana sobre la general.' })
  @IsString()
  @MaxLength(40)
  @IsOptional()
  tipo_cliente?: string;

  @ApiProperty({ example: 60, description: 'Minutos para la primera respuesta' })
  @IsInt()
  @Min(1)
  @Max(43_200)
  min_primera_respuesta: number;

  @ApiProperty({ example: 480, description: 'Minutos para resolver' })
  @IsInt()
  @Min(1)
  @Max(43_200)
  min_resolucion: number;

  @ApiPropertyOptional({ description: 'Calendario con el que corre el reloj. Sin esto usa el default de la empresa.' })
  @IsUUID()
  @IsOptional()
  calendario_id?: string;
}

export class UpdateSlaDto {
  @ApiPropertyOptional()
  @IsString()
  @MaxLength(100)
  @IsOptional()
  nombre?: string;

  @ApiPropertyOptional({ enum: PRIORIDADES_SLA })
  @IsIn(PRIORIDADES_SLA as unknown as string[])
  @IsOptional()
  prioridad?: string;

  @ApiPropertyOptional()
  @IsString()
  @MaxLength(40)
  @IsOptional()
  tipo_cliente?: string;

  @ApiPropertyOptional()
  @IsInt()
  @Min(1)
  @Max(43_200)
  @IsOptional()
  min_primera_respuesta?: number;

  @ApiPropertyOptional()
  @IsInt()
  @Min(1)
  @Max(43_200)
  @IsOptional()
  min_resolucion?: number;

  @ApiPropertyOptional()
  @IsUUID()
  @IsOptional()
  calendario_id?: string;

  @ApiPropertyOptional()
  @IsBoolean()
  @IsOptional()
  activo?: boolean;
}
