import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { IsBoolean, IsIn, IsObject, IsOptional, IsString, IsUUID, MaxLength } from 'class-validator';

export const TIPOS_CANAL = ['whatsapp', 'email', 'instagram', 'facebook', 'webchat'] as const;
export const PROVEEDORES = [
  'meta_cloud', 'evolution_cloud', 'evolution_baileys', 'imap_smtp', 'webchat_propio',
] as const;

/**
 * Las credenciales llegan en claro una sola vez y se guardan cifradas. Nunca se
 * devuelven: la lectura las enmascara.
 */
export class CredencialesDto {
  @ApiPropertyOptional({ description: 'Meta Cloud: token permanente de la app' })
  @IsString()
  @IsOptional()
  access_token?: string;

  @ApiPropertyOptional({ description: 'Meta Cloud: app secret, para validar la firma del webhook' })
  @IsString()
  @IsOptional()
  app_secret?: string;

  @ApiPropertyOptional({ description: 'Evolution: URL base de la instancia', example: 'https://evo.midominio.com' })
  @IsString()
  @IsOptional()
  base_url?: string;

  @ApiPropertyOptional({ description: 'Evolution: api key' })
  @IsString()
  @IsOptional()
  api_key?: string;

  @ApiPropertyOptional({ description: 'Evolution: nombre de la instancia' })
  @IsString()
  @IsOptional()
  instancia?: string;
}

export class CreateCanalDto {
  @ApiProperty({ enum: TIPOS_CANAL })
  @IsIn(TIPOS_CANAL as unknown as string[])
  tipo: string;

  @ApiProperty({
    enum: PROVEEDORES,
    description:
      'evolution_baileys usa un protocolo no oficial: sirve para demos y pruebas, pero los ' +
      'envíos automáticos quedan bloqueados para proteger el número.',
  })
  @IsIn(PROVEEDORES as unknown as string[])
  proveedor: string;

  @ApiProperty({ example: 'WhatsApp Ventas' })
  @IsString()
  @MaxLength(100)
  nombre: string;

  @ApiPropertyOptional({ description: 'Número en E.164 o casilla', example: '+595981123456' })
  @IsString()
  @MaxLength(60)
  @IsOptional()
  identificador?: string;

  @ApiPropertyOptional({
    description: 'Meta: phone_number_id · Evolution: nombre de instancia. Es por donde entran los webhooks.',
  })
  @IsString()
  @MaxLength(80)
  @IsOptional()
  identificador_externo?: string;

  @ApiPropertyOptional({ description: 'Meta: el que se configura en el panel de la app para el handshake' })
  @IsString()
  @MaxLength(100)
  @IsOptional()
  webhook_verify_token?: string;

  @ApiPropertyOptional({ type: CredencialesDto })
  @IsObject()
  @IsOptional()
  credenciales?: CredencialesDto;

  @ApiPropertyOptional({ description: 'Equipo al que caen las conversaciones sin dueño' })
  @IsUUID()
  @IsOptional()
  equipo_id?: string;
}

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

  @ApiPropertyOptional()
  @IsString()
  @MaxLength(60)
  @IsOptional()
  identificador?: string;

  @ApiPropertyOptional()
  @IsString()
  @MaxLength(80)
  @IsOptional()
  identificador_externo?: string;

  @ApiPropertyOptional()
  @IsString()
  @MaxLength(100)
  @IsOptional()
  webhook_verify_token?: string;

  @ApiPropertyOptional({
    type: CredencialesDto,
    description: 'Sólo lo que se envía se reemplaza: lo omitido conserva su valor guardado.',
  })
  @IsObject()
  @IsOptional()
  credenciales?: CredencialesDto;

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

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