/**
 * 管理员操作日志控制器
 * 
 * 功能描述：
 * - 提供管理员操作日志的查询和管理接口
 * - 支持日志的分页查询和过滤
 * - 提供操作统计和分析功能
 * - 支持敏感操作日志的特殊查询
 * 
 * 职责分离：
 * - HTTP请求处理：接收和验证HTTP请求参数
 * - 权限控制：通过AdminGuard确保只有管理员可以访问
 * - 业务委托：将业务逻辑委托给AdminOperationLogService处理
 * - 响应格式化：返回统一格式的HTTP响应
 * 
 * API端点：
 * - GET  /admin/operation-logs              获取操作日志列表
 * - GET  /admin/operation-logs/:id          获取操作日志详情
 * - GET  /admin/operation-logs/statistics   获取操作统计
 * - GET  /admin/operation-logs/sensitive    获取敏感操作日志
 * - DELETE /admin/operation-logs/cleanup    清理过期日志
 * 
 * 最近修改：
 * - 2026-01-08: 功能新增 - 创建管理员操作日志控制器 (修改者: moyin)
 * 
 * @author moyin
 * @version 1.0.0
 * @since 2026-01-08
 * @lastModified 2026-01-08
 */

import {
  Controller,
  Get,
  Delete,
  Param,
  Query,
  UseGuards,
  UseFilters,
  UseInterceptors,
  ParseIntPipe,
  DefaultValuePipe,
  BadRequestException
} from '@nestjs/common';
import {
  ApiTags,
  ApiBearerAuth,
  ApiOperation,
  ApiParam,
  ApiQuery,
  ApiResponse
} from '@nestjs/swagger';
import { AdminGuard } from './admin.guard';
import { AdminDatabaseExceptionFilter } from './admin_database_exception.filter';
import { AdminOperationLogInterceptor } from './admin_operation_log.interceptor';
import { LogAdminOperation } from './log_admin_operation.decorator';
import { AdminOperationLogService, LogQueryParams } from './admin_operation_log.service';
import { PAGINATION_LIMITS, LOG_RETENTION, USER_QUERY_LIMITS } from './admin_constants';
import { safeLimitValue, safeOffsetValue, safeDaysToKeep, createSuccessResponse, createListResponse } from './admin_utils';

@ApiTags('admin-operation-logs')
@Controller('admin/operation-logs')
@UseGuards(AdminGuard)
@UseFilters(AdminDatabaseExceptionFilter)
@UseInterceptors(AdminOperationLogInterceptor)
@ApiBearerAuth('JWT-auth')
export class AdminOperationLogController {
  constructor(
    private readonly logService: AdminOperationLogService
  ) {}

  /**
   * 获取操作日志列表
   * 
   * 功能描述：
   * 分页获取管理员操作日志，支持多种过滤条件
   * 
   * 业务逻辑：
   * 1. 验证查询参数
   * 2. 构建查询条件
   * 3. 调用日志服务查询
   * 4. 返回分页结果
   * 
   * @param limit 返回数量，默认50，最大200
   * @param offset 偏移量，默认0
   * @param adminUserId 管理员用户ID过滤，可选
   * @param operationType 操作类型过滤，可选
   * @param targetType 目标类型过滤，可选
   * @param operationResult 操作结果过滤，可选
   * @param startDate 开始日期过滤，可选
   * @param endDate 结束日期过滤，可选
   * @param isSensitive 是否敏感操作过滤，可选
   * @returns 操作日志列表和分页信息
   * 
   * @example
   * ```typescript
   * // 获取最近50条操作日志
   * GET /admin/operation-logs?limit=50&offset=0
   * 
   * // 获取特定管理员的操作日志
   * GET /admin/operation-logs?adminUserId=123&limit=20
   * 
   * // 获取敏感操作日志
   * GET /admin/operation-logs?isSensitive=true
   * ```
   */
  @ApiOperation({ 
    summary: '获取操作日志列表', 
    description: '分页获取管理员操作日志，支持多种过滤条件' 
  })
  @ApiQuery({ name: 'limit', required: false, description: '返回数量（默认50，最大200）', example: 50 })
  @ApiQuery({ name: 'offset', required: false, description: '偏移量（默认0）', example: 0 })
  @ApiQuery({ name: 'adminUserId', required: false, description: '管理员用户ID过滤', example: '123' })
  @ApiQuery({ name: 'operationType', required: false, description: '操作类型过滤', example: 'CREATE' })
  @ApiQuery({ name: 'targetType', required: false, description: '目标类型过滤', example: 'users' })
  @ApiQuery({ name: 'operationResult', required: false, description: '操作结果过滤', example: 'SUCCESS' })
  @ApiQuery({ name: 'startDate', required: false, description: '开始日期（ISO格式）', example: '2026-01-01T00:00:00.000Z' })
  @ApiQuery({ name: 'endDate', required: false, description: '结束日期（ISO格式）', example: '2026-01-08T23:59:59.999Z' })
  @ApiQuery({ name: 'isSensitive', required: false, description: '是否敏感操作', example: true })
  @ApiResponse({ status: 200, description: '获取成功' })
  @ApiResponse({ status: 401, description: '未授权访问' })
  @ApiResponse({ status: 403, description: '权限不足' })
  @LogAdminOperation({
    operationType: 'QUERY',
    targetType: 'admin_logs',
    description: '获取操作日志列表',
    isSensitive: false
  })
  @Get()
  async getOperationLogs(
    @Query('limit', new DefaultValuePipe(PAGINATION_LIMITS.DEFAULT_LIMIT), ParseIntPipe) limit: number,
    @Query('offset', new DefaultValuePipe(PAGINATION_LIMITS.DEFAULT_OFFSET), ParseIntPipe) offset: number,
    @Query('adminUserId') adminUserId?: string,
    @Query('operationType') operationType?: string,
    @Query('targetType') targetType?: string,
    @Query('operationResult') operationResult?: string,
    @Query('startDate') startDate?: string,
    @Query('endDate') endDate?: string,
    @Query('isSensitive') isSensitive?: string
  ) {
    const safeLimit = safeLimitValue(limit, PAGINATION_LIMITS.LOG_LIST_MAX_LIMIT);
    const safeOffset = safeOffsetValue(offset);

    const queryParams: LogQueryParams = {
      limit: safeLimit,
      offset: safeOffset
    };

    if (adminUserId) queryParams.adminUserId = adminUserId;
    if (operationType) queryParams.operationType = operationType;
    if (targetType) queryParams.targetType = targetType;
    if (operationResult) queryParams.operationResult = operationResult;
    if (isSensitive !== undefined) queryParams.isSensitive = isSensitive === 'true';

    if (startDate && endDate) {
      queryParams.startDate = new Date(startDate);
      queryParams.endDate = new Date(endDate);
      
      if (isNaN(queryParams.startDate.getTime()) || isNaN(queryParams.endDate.getTime())) {
        throw new BadRequestException('日期格式无效，请使用ISO格式');
      }
    }

    const { logs, total } = await this.logService.queryLogs(queryParams);

    return createListResponse(
      logs,
      total,
      safeLimit,
      safeOffset,
      '操作日志列表获取成功'
    );
  }

  /**
   * 获取操作日志详情
   * 
   * 功能描述：
   * 根据日志ID获取操作日志的详细信息
   * 
   * 业务逻辑：
   * 1. 验证日志ID格式
   * 2. 查询日志详细信息
   * 3. 返回日志详情
   * 
   * @param id 日志ID
   * @returns 操作日志详细信息
   * 
   * @throws NotFoundException 当日志不存在时
   * 
   * @example
   * ```typescript
   * const result = await controller.getOperationLogById('uuid-123');
   * ```
   */
  @ApiOperation({ 
    summary: '获取操作日志详情', 
    description: '根据日志ID获取操作日志的详细信息' 
  })
  @ApiParam({ name: 'id', description: '日志ID', example: 'uuid-123' })
  @ApiResponse({ status: 200, description: '获取成功' })
  @ApiResponse({ status: 404, description: '日志不存在' })
  @Get(':id')
  async getOperationLogById(@Param('id') id: string) {
    const log = await this.logService.getLogById(id);
    
    if (!log) {
      throw new BadRequestException('操作日志不存在');
    }

    return createSuccessResponse(log, '操作日志详情获取成功');
  }

  /**
   * 获取操作统计信息
   * 
   * 功能描述：
   * 获取管理员操作的统计信息，包括操作数量、类型分布等
   * 
   * 业务逻辑：
   * 1. 解析时间范围参数
   * 2. 调用统计服务
   * 3. 返回统计结果
   * 
   * @param startDate 开始日期，可选
   * @param endDate 结束日期，可选
   * @returns 操作统计信息
   * 
   * @example
   * ```typescript
   * // 获取全部统计
   * GET /admin/operation-logs/statistics
   * 
   * // 获取指定时间范围的统计
   * GET /admin/operation-logs/statistics?startDate=2026-01-01&endDate=2026-01-08
   * ```
   */
  @ApiOperation({ 
    summary: '获取操作统计信息', 
    description: '获取管理员操作的统计信息，包括操作数量、类型分布等' 
  })
  @ApiQuery({ name: 'startDate', required: false, description: '开始日期（ISO格式）', example: '2026-01-01T00:00:00.000Z' })
  @ApiQuery({ name: 'endDate', required: false, description: '结束日期（ISO格式）', example: '2026-01-08T23:59:59.999Z' })
  @ApiResponse({ status: 200, description: '获取成功' })
  @Get('statistics')
  async getOperationStatistics(
    @Query('startDate') startDate?: string,
    @Query('endDate') endDate?: string
  ) {
    let parsedStartDate: Date | undefined;
    let parsedEndDate: Date | undefined;

    if (startDate && endDate) {
      parsedStartDate = new Date(startDate);
      parsedEndDate = new Date(endDate);
      
      if (isNaN(parsedStartDate.getTime()) || isNaN(parsedEndDate.getTime())) {
        throw new BadRequestException('日期格式无效，请使用ISO格式');
      }
    }

    const statistics = await this.logService.getStatistics(parsedStartDate, parsedEndDate);

    return createSuccessResponse(statistics, '操作统计信息获取成功');
  }

  /**
   * 获取敏感操作日志
   * 
   * 功能描述：
   * 获取标记为敏感的操作日志，用于安全审计
   * 
   * 业务逻辑：
   * 1. 验证查询参数
   * 2. 查询敏感操作日志
   * 3. 返回分页结果
   * 
   * @param limit 返回数量，默认50，最大200
   * @param offset 偏移量，默认0
   * @returns 敏感操作日志列表
   * 
   * @example
   * ```typescript
   * // 获取最近50条敏感操作日志
   * GET /admin/operation-logs/sensitive?limit=50
   * ```
   */
  @ApiOperation({ 
    summary: '获取敏感操作日志', 
    description: '获取标记为敏感的操作日志，用于安全审计' 
  })
  @ApiQuery({ name: 'limit', required: false, description: '返回数量（默认50，最大200）', example: 50 })
  @ApiQuery({ name: 'offset', required: false, description: '偏移量（默认0）', example: 0 })
  @ApiResponse({ status: 200, description: '获取成功' })
  @LogAdminOperation({
    operationType: 'QUERY',
    targetType: 'admin_logs',
    description: '获取敏感操作日志',
    isSensitive: true
  })
  @Get('sensitive')
  async getSensitiveOperations(
    @Query('limit', new DefaultValuePipe(PAGINATION_LIMITS.DEFAULT_LIMIT), ParseIntPipe) limit: number,
    @Query('offset', new DefaultValuePipe(PAGINATION_LIMITS.DEFAULT_OFFSET), ParseIntPipe) offset: number
  ) {
    const safeLimit = safeLimitValue(limit, PAGINATION_LIMITS.LOG_LIST_MAX_LIMIT);
    const safeOffset = safeOffsetValue(offset);

    const { logs, total } = await this.logService.getSensitiveOperations(safeLimit, safeOffset);

    return createListResponse(
      logs,
      total,
      safeLimit,
      safeOffset,
      '敏感操作日志获取成功'
    );
  }

  /**
   * 清理过期日志
   * 
   * 功能描述：
   * 清理超过指定天数的操作日志，释放存储空间
   * 
   * 业务逻辑：
   * 1. 验证保留天数参数
   * 2. 调用清理服务
   * 3. 返回清理结果
   * 
   * @param daysToKeep 保留天数，默认90天，最少7天，最多365天
   * @returns 清理结果，包含删除的记录数
   * 
   * @throws BadRequestException 当保留天数超出范围时
   * 
   * @example
   * ```typescript
   * // 清理90天前的日志
   * DELETE /admin/operation-logs/cleanup?daysToKeep=90
   * ```
   */
  @ApiOperation({ 
    summary: '清理过期日志', 
    description: '清理超过指定天数的操作日志，释放存储空间' 
  })
  @ApiQuery({ name: 'daysToKeep', required: false, description: '保留天数（默认90，最少7，最多365）', example: 90 })
  @ApiResponse({ status: 200, description: '清理成功' })
  @ApiResponse({ status: 400, description: '参数错误' })
  @LogAdminOperation({
    operationType: 'DELETE',
    targetType: 'admin_logs',
    description: '清理过期操作日志',
    isSensitive: true
  })
  @Delete('cleanup')
  async cleanupExpiredLogs(
    @Query('daysToKeep', new DefaultValuePipe(LOG_RETENTION.DEFAULT_DAYS), ParseIntPipe) daysToKeep: number
  ) {
    const safeDays = safeDaysToKeep(daysToKeep, LOG_RETENTION.MIN_DAYS, LOG_RETENTION.MAX_DAYS);
    
    if (safeDays !== daysToKeep) {
      throw new BadRequestException(`保留天数必须在${LOG_RETENTION.MIN_DAYS}-${LOG_RETENTION.MAX_DAYS}天之间`);
    }

    const deletedCount = await this.logService.cleanupExpiredLogs(safeDays);

    return createSuccessResponse({
      deleted_count: deletedCount,
      days_to_keep: safeDays,
      cleanup_date: new Date().toISOString()
    }, `过期日志清理完成，删除了${deletedCount}条记录`);
  }
}