import {
  IsString,
  IsOptional,
  IsUUID,
  IsDateString,
  IsArray,
  IsNumber,
  IsIn,
  IsNotEmpty,
} from 'class-validator';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';

// ── Estados del nuevo dominio ──────────────────────────────────────────
// BORRADOR  → cobrador armando rendición (aún editable)
// PENDIENTE → enviada a tesorería, esperando verificación
// OBSERVADO → tesorería detectó diferencias, vuelve al cobrador
// APROBADO  → tesorería confirmó, contabilizada y comisiones liquidables
// RECHAZADO → tesorería rechaza definitivamente
// ANULADO   → cancelada (no contabiliza)
export const ESTADOS_RENDICION = [
  'BORRADOR',
  'PENDIENTE',
  'OBSERVADO',
  'APROBADO',
  'RECHAZADO',
  'ANULADO',
] as const;
export type EstadoRendicion = (typeof ESTADOS_RENDICION)[number];

export const VERIFICACION_ESTADOS = ['OK', 'DIFERENCIA', 'RECHAZADO'] as const;
export type VerificacionEstado = (typeof VERIFICACION_ESTADOS)[number];

// ── Crear rendición ────────────────────────────────────────────────────
export class CreateRendicionDto {
  @ApiProperty({ description: 'ID del cobrador que realizó la cobranza' })
  @IsUUID()
  cobrador_id: string;

  @ApiProperty({ description: 'Fecha de la cobranza (YYYY-MM-DD)' })
  @IsDateString()
  fecha_cobranza: string;

  @ApiPropertyOptional({ description: 'ID de la ruta de cobranza asociada (opcional)' })
  @IsOptional()
  @IsUUID()
  ruta_id?: string;

  @ApiProperty({ description: 'Moneda de la rendición (todos los recibos deben coincidir)' })
  @IsUUID()
  moneda_id: string;

  @ApiPropertyOptional({
    description: 'IDs de recibos de cobro a incluir en la rendición',
    type: [String],
  })
  @IsOptional()
  @IsArray()
  @IsUUID('4', { each: true })
  recibo_ids?: string[];

  @ApiPropertyOptional({ description: 'Monto esperado de cobranza (si se conoce)' })
  @IsOptional()
  @IsNumber()
  monto_esperado?: number;

  @ApiPropertyOptional({ description: 'Total declarado por el cobrador (efectivo + cheques + otros)' })
  @IsOptional()
  @IsNumber()
  total_declarado?: number;

  @ApiPropertyOptional({ description: 'Observaciones del cobrador' })
  @IsOptional()
  @IsString()
  observaciones_cobrador?: string;
}

// ── Enviar a tesorería (BORRADOR → PENDIENTE) ──────────────────────────
export class EnviarTesoreriaDto {
  @ApiPropertyOptional({ description: 'Total declarado por el cobrador al enviar' })
  @IsOptional()
  @IsNumber()
  total_declarado?: number;

  @ApiPropertyOptional({ description: 'Observaciones del cobrador al enviar' })
  @IsOptional()
  @IsString()
  observaciones_cobrador?: string;
}

// ── Verificar un medio de pago (Tesorería) ─────────────────────────────
export class VerificarMedioPagoDto {
  @ApiProperty({ description: 'Importe efectivamente verificado en caja/banco' })
  @IsNumber()
  importe_verificado: number;

  @ApiProperty({ description: 'Estado de verificación', enum: VERIFICACION_ESTADOS })
  @IsIn(VERIFICACION_ESTADOS as unknown as string[])
  verificacion_estado: VerificacionEstado;

  @ApiPropertyOptional({ description: 'Observación si hay diferencia o rechazo' })
  @IsOptional()
  @IsString()
  verificacion_observacion?: string;
}

// ── Aprobar rendición (PENDIENTE → APROBADO) ───────────────────────────
export class AprobarRendicionDto {
  @ApiPropertyOptional({ description: 'ID de caja destino para asiento contable' })
  @IsOptional()
  @IsUUID()
  caja_destino_id?: string;

  @ApiPropertyOptional({ description: 'Observaciones de tesorería' })
  @IsOptional()
  @IsString()
  observaciones_supervisor?: string;
}

// ── Rechazar / Observar rendición ──────────────────────────────────────
export class RechazarRendicionDto {
  @ApiProperty({
    description: 'OBSERVADO devuelve al cobrador; RECHAZADO la cierra como rechazada',
    enum: ['OBSERVADO', 'RECHAZADO'],
  })
  @IsIn(['OBSERVADO', 'RECHAZADO'])
  accion: 'OBSERVADO' | 'RECHAZADO';

  @ApiProperty({ description: 'Motivo del rechazo / observación (obligatorio)' })
  @IsString()
  @IsNotEmpty()
  motivo: string;
}

// ── Filtros de listado ─────────────────────────────────────────────────
export class FiltroRendicionesDto {
  @IsOptional() @IsUUID() cobrador_id?: string;
  @IsOptional() @IsDateString() fecha_desde?: string;
  @IsOptional() @IsDateString() fecha_hasta?: string;
  @IsOptional() @IsIn(ESTADOS_RENDICION as unknown as string[]) estado?: EstadoRendicion;
  @IsOptional() @IsNumber() page?: number;
  @IsOptional() @IsNumber() limit?: number;
}

// ── Legacy: Revisar rendición (deprecated, mantenido por compatibilidad) ─
export class RevisarRendicionDto {
  @ApiProperty({
    description: 'Acción legacy (usar AprobarRendicionDto / RechazarRendicionDto en su lugar)',
    enum: ['aprobada', 'rechazada', 'con_observacion'],
  })
  @IsString()
  accion: string;

  @ApiPropertyOptional({ description: 'Observaciones del supervisor' })
  @IsOptional()
  @IsString()
  observaciones_supervisor?: string;
}
