import { ApiProperty, ApiPropertyOptional, PartialType } from '@nestjs/swagger';
import { Transform, Type } from 'class-transformer';
import {
  IsBoolean,
  IsEnum,
  IsInt,
  IsOptional,
  IsString,
  IsUUID,
  IsUrl,
  Length,
  Max,
  Min,
} from 'class-validator';

export enum RelojTipoConexion {
  API = 'API',
  PLANILLA = 'PLANILLA',
}

export enum RelojTipoAuth {
  NONE = 'NONE',
  BASIC = 'BASIC',
  BEARER = 'BEARER',
  API_KEY = 'API_KEY',
  DIGEST = 'DIGEST',
}

export enum RelojProtocoloApi {
  GENERICO = 'GENERICO',
  HIKVISION_ISAPI = 'HIKVISION_ISAPI',
}

export enum RelojFormatoRespuesta {
  JSON = 'JSON',
  XML = 'XML',
}

export class CreateRelojDto {
  @ApiProperty({ example: 'Planta Norte' })
  @IsString()
  @Length(1, 100)
  nombre!: string;

  @ApiProperty({ enum: RelojTipoConexion, example: RelojTipoConexion.PLANILLA })
  @IsEnum(RelojTipoConexion)
  tipo_conexion!: RelojTipoConexion;

  @ApiPropertyOptional({ example: 'https://reloj.demo/api' })
  @IsOptional()
  @IsUrl({ require_tld: false })
  @Length(1, 255)
  url_base?: string;

  @ApiPropertyOptional({ description: 'Credencial en claro — se almacena cifrada' })
  @IsOptional()
  @IsString()
  @Length(1, 500)
  api_key?: string;

  @ApiPropertyOptional({ enum: RelojTipoAuth })
  @IsOptional()
  @IsEnum(RelojTipoAuth)
  tipo_auth?: RelojTipoAuth;

  @ApiPropertyOptional({
    enum: RelojProtocoloApi,
    default: RelojProtocoloApi.GENERICO,
    description: 'Protocolo del reloj API. HIKVISION_ISAPI usa AcsEvent (POST paginado) + Digest Auth.',
  })
  @IsOptional()
  @IsEnum(RelojProtocoloApi)
  protocolo_api?: RelojProtocoloApi;

  @ApiPropertyOptional({ enum: RelojFormatoRespuesta })
  @IsOptional()
  @IsEnum(RelojFormatoRespuesta)
  formato_respuesta?: RelojFormatoRespuesta;

  @ApiPropertyOptional({ example: 'documento' })
  @IsOptional()
  @IsString()
  @Length(1, 50)
  campo_documento?: string;

  @ApiPropertyOptional({ example: 'timestamp' })
  @IsOptional()
  @IsString()
  @Length(1, 50)
  campo_timestamp?: string;

  @ApiPropertyOptional({ minimum: 5, description: 'Minutos entre consultas (NULL = manual)' })
  @IsOptional()
  @Type(() => Number)
  @IsInt()
  @Min(5)
  @Max(1440)
  intervalo_polling_min?: number;

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

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

export class UpdateRelojDto extends PartialType(CreateRelojDto) {}

export class QueryRelojesDto {
  @ApiPropertyOptional({ default: 1 })
  @IsOptional()
  @Transform(({ value }) => parseInt(String(value), 10) || 1)
  @IsInt()
  @Min(1)
  page?: number = 1;

  @ApiPropertyOptional({ default: 20 })
  @IsOptional()
  @Transform(({ value }) => parseInt(String(value), 10) || 20)
  @IsInt()
  @Min(1)
  @Max(200)
  limit?: number = 20;

  @ApiPropertyOptional({ enum: RelojTipoConexion })
  @IsOptional()
  @IsEnum(RelojTipoConexion)
  tipo_conexion?: RelojTipoConexion;

  @ApiPropertyOptional({ enum: RelojProtocoloApi })
  @IsOptional()
  @IsEnum(RelojProtocoloApi)
  protocolo_api?: RelojProtocoloApi;

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

  @ApiPropertyOptional()
  @IsOptional()
  @Transform(({ value }) =>
    value === 'true' || value === true ? true : value === 'false' || value === false ? false : undefined,
  )
  @IsBoolean()
  activo?: boolean;
}
