import {
  IsOptional,
  IsString,
  IsEnum,
  IsBoolean,
  IsInt,
  IsUUID,
  Min,
  Max,
  IsDateString,
  IsIn,
  IsArray,
  ValidateNested,
} from 'class-validator';
import { Type, Transform } from 'class-transformer';
import { AuditAction, AuditStatus, RiskLevel, ComplianceLevel } from '@prisma/client';

/**
 * 审计日志查询 DTO
 * GET /api/v1/audit/logs
 */
export class QueryAuditLogDto {
  // 时间范围（跨度最大 90 天）
  @IsOptional()
  @IsDateString()
  startDate?: string;

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

  // 过滤条件
  @IsOptional()
  @IsString()
  userId?: string;

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

  @IsOptional()
  @IsEnum(AuditAction)
  action?: AuditAction;

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

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

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

  @IsOptional()
  @IsBoolean()
  @Transform(({ value }) => value === 'true' || value === true)
  isFinancial?: boolean;

  @IsOptional()
  @IsBoolean()
  @Transform(({ value }) => value === 'true' || value === true)
  isSensitive?: boolean;

  @IsOptional()
  @IsEnum(RiskLevel)
  riskLevel?: RiskLevel;

  @IsOptional()
  @IsEnum(ComplianceLevel)
  complianceLevel?: ComplianceLevel;

  // 关键词搜索（在 what、why、user.username 中模糊搜索）
  @IsOptional()
  @IsString()
  keyword?: string;

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

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

  // 排序
  @IsOptional()
  @IsIn(['when', 'module', 'action', 'userId'])
  sortBy?: 'when' | 'module' | 'action' | 'userId' = 'when';

  @IsOptional()
  @IsIn(['asc', 'desc'])
  sortOrder?: 'asc' | 'desc' = 'desc';

  // 分页
  @IsOptional()
  @IsInt()
  @Min(1)
  @Type(() => Number)
  page?: number = 1;

  @IsOptional()
  @IsInt()
  @Min(1)
  @Max(200)
  @Type(() => Number)
  limit?: number = 50;
}

/**
 * 实体审计查询 DTO
 * GET /api/v1/audit/entity/:type/:id
 */
export class EntityAuditQueryDto {
  @IsOptional()
  @IsInt()
  @Min(1)
  @Type(() => Number)
  page?: number = 1;

  @IsOptional()
  @IsInt()
  @Min(1)
  @Max(200)
  @Type(() => Number)
  limit?: number = 50;

  @IsOptional()
  @IsBoolean()
  @Transform(({ value }) => value === 'true' || value === true)
  includeDiff?: boolean = true;
}

/**
 * 用户审计查询 DTO
 * GET /api/v1/audit/user/:userId
 */
export class UserAuditQueryDto {
  @IsOptional()
  @IsDateString()
  startDate?: string;

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

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

  @IsOptional()
  @IsEnum(AuditAction)
  action?: AuditAction;

  @IsOptional()
  @IsBoolean()
  @Transform(({ value }) => value === 'true' || value === true)
  isSensitive?: boolean;

  @IsOptional()
  @IsBoolean()
  @Transform(({ value }) => value === 'true' || value === true)
  isFinancial?: boolean;

  @IsOptional()
  @IsEnum(RiskLevel)
  riskLevel?: RiskLevel;

  @IsOptional()
  @IsInt()
  @Min(1)
  @Type(() => Number)
  page?: number = 1;

  @IsOptional()
  @IsInt()
  @Min(1)
  @Max(200)
  @Type(() => Number)
  limit?: number = 50;
}

/**
 * 财务审计查询 DTO
 * GET /api/v1/audit/financial
 */
export class FinancialAuditQueryDto {
  @IsDateString()
  startDate: string; // 必填

  @IsDateString()
  endDate: string; // 必填（跨度最大 1 年）

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

  @IsOptional()
  @IsEnum(AuditAction)
  action?: AuditAction;

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

  @IsOptional()
  @IsIn(['when', 'module', 'action', 'userId'])
  sortBy?: 'when' | 'module' | 'action' | 'userId' = 'when';

  @IsOptional()
  @IsIn(['asc', 'desc'])
  sortOrder?: 'asc' | 'desc' = 'desc';

  @IsOptional()
  @IsInt()
  @Min(1)
  @Type(() => Number)
  page?: number = 1;

  @IsOptional()
  @IsInt()
  @Min(1)
  @Max(200)
  @Type(() => Number)
  limit?: number = 50;
}

/**
 * 敏感操作查询 DTO
 * GET /api/v1/audit/sensitive
 */
export class SensitiveAuditQueryDto {
  @IsOptional()
  @IsDateString()
  startDate?: string;

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

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

  @IsOptional()
  @IsEnum(AuditAction)
  action?: AuditAction;

  @IsOptional()
  @IsEnum(RiskLevel)
  riskLevel?: RiskLevel;

  @IsOptional()
  @IsInt()
  @Min(1)
  @Type(() => Number)
  page?: number = 1;

  @IsOptional()
  @IsInt()
  @Min(1)
  @Max(200)
  @Type(() => Number)
  limit?: number = 50;
}

/**
 * 统计请求 DTO
 * POST /api/v1/audit/statistics
 */
export class AuditStatisticsDto {
  @IsDateString()
  startDate: string;

  @IsDateString()
  endDate: string;

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

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

  // 预留字段（当前忽略，返回所有维度）
  @IsOptional()
  @IsIn(['day', 'module', 'action', 'user'])
  groupBy?: 'day' | 'module' | 'action' | 'user';
}

/**
 * 完整性验证请求 DTO
 * POST /api/v1/audit/verify-integrity
 */
export class VerifyIntegrityDto {
  @IsOptional()
  @IsDateString()
  startDate?: string;

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

/**
 * 异步完整性检查请求 DTO
 * POST /api/v1/audit/integrity-check
 */
export class IntegrityCheckDto {
  @IsOptional()
  @IsDateString()
  startDate?: string;

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

  @IsOptional()
  @IsIn(['ALL', 'FINANCIAL_ONLY', 'SENSITIVE_ONLY', 'HIGH_RISK_ONLY'])
  scope?: 'ALL' | 'FINANCIAL_ONLY' | 'SENSITIVE_ONLY' | 'HIGH_RISK_ONLY' = 'ALL';
}

/**
 * 导出过滤器 DTO
 */
export class AuditExportFiltersDto {
  @IsOptional()
  @IsString()
  userId?: string;

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

  @IsOptional()
  @IsEnum(AuditAction)
  action?: AuditAction;

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

  @IsOptional()
  @IsBoolean()
  isFinancial?: boolean;

  @IsOptional()
  @IsBoolean()
  isSensitive?: boolean;

  @IsOptional()
  @IsEnum(RiskLevel)
  riskLevel?: RiskLevel;

  @IsOptional()
  @IsEnum(AuditStatus)
  status?: AuditStatus;
}

/**
 * 导出请求 DTO
 * POST /api/v1/audit/export
 */
export class AuditExportDto {
  @IsDateString()
  startDate: string;

  @IsDateString()
  endDate: string;

  @IsIn(['csv', 'excel', 'json'])
  format: 'csv' | 'excel' | 'json';

  @IsOptional()
  @ValidateNested()
  @Type(() => AuditExportFiltersDto)
  filters?: AuditExportFiltersDto;

  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  fields?: string[];
}

// 保留旧的别名以保持向后兼容
export { AuditStatisticsDto as GetStatisticsDto };

/**
 * 检测连续失败 DTO
 * POST /api/v1/audit/alerts/detect-failures
 */
export class DetectFailuresDto {
  @IsUUID()
  userId: string;

  @IsString()
  action: string;

  @IsOptional()
  @IsInt()
  timeWindow?: number;
}

/**
 * 检测异常模式 DTO
 * POST /api/v1/audit/alerts/detect-anomaly
 */
export class DetectAnomalyDto {
  @IsUUID()
  userId: string;

  @IsOptional()
  @IsInt()
  days?: number;
}

/**
 * 批量检查告警 DTO
 * POST /api/v1/audit/alerts/batch-check
 */
export class BatchCheckAlertsDto {
  @IsOptional()
  @IsDateString()
  since?: string;
}

/**
 * 时间区间报表 DTO（SOX / Anomaly）
 */
export class DateRangeReportDto {
  @IsDateString()
  startDate: string;

  @IsDateString()
  endDate: string;
}
