/**
 * WebSocket响应数据传输对象
 * 
 * 功能描述：
 * - 定义WebSocket服务端响应的消息格式
 * - 提供统一的响应结构和错误处理格式
 * - 支持位置广播系统的实时响应需求
 * - 实现响应类型的标准化管理
 * 
 * 职责分离：
 * - 响应格式：定义服务端响应的标准结构
 * - 错误处理：统一的错误响应格式
 * - 类型安全：提供TypeScript类型约束
 * - 数据完整性：确保响应数据的完整性
 * 
 * 最近修改：
 * - 2026-01-08: 功能新增 - 创建WebSocket响应DTO，支持位置广播系统
 * 
 * @author moyin
 * @version 1.0.0
 * @since 2026-01-08
 * @lastModified 2026-01-08
 */

import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';

/**
 * 会话加入成功响应DTO
 * 
 * 职责：
 * - 定义用户成功加入会话后的响应数据
 * - 包含会话信息和其他用户的位置数据
 * - 提供完整的会话状态视图
 */
export class SessionJoinedResponse {
  /**
   * 响应类型标识
   */
  @ApiProperty({
    description: '响应类型',
    example: 'session_joined',
    enum: ['session_joined']
  })
  type: 'session_joined' = 'session_joined';

  /**
   * 会话ID
   */
  @ApiProperty({
    description: '会话ID',
    example: 'session_12345'
  })
  sessionId: string;

  /**
   * 会话中的用户列表
   */
  @ApiProperty({
    description: '会话中的用户列表',
    example: [
      {
        userId: 'user1',
        socketId: 'socket1',
        joinedAt: 1641024000000,
        lastSeen: 1641024000000,
        status: 'online'
      }
    ]
  })
  users: Array<{
    userId: string;
    socketId: string;
    joinedAt: number;
    lastSeen: number;
    status: string;
    position?: {
      x: number;
      y: number;
      mapId: string;
      timestamp: number;
    };
  }>;

  /**
   * 其他用户的位置信息
   */
  @ApiProperty({
    description: '其他用户的位置信息',
    example: [
      {
        userId: 'user2',
        x: 150,
        y: 250,
        mapId: 'plaza',
        timestamp: 1641024000000
      }
    ]
  })
  positions: Array<{
    userId: string;
    x: number;
    y: number;
    mapId: string;
    timestamp: number;
    metadata?: Record<string, any>;
  }>;

  /**
   * 会话配置信息
   */
  @ApiPropertyOptional({
    description: '会话配置信息',
    example: {
      maxUsers: 100,
      allowObservers: true,
      broadcastRange: 1000
    }
  })
  config?: {
    maxUsers: number;
    allowObservers: boolean;
    broadcastRange?: number;
    mapRestriction?: string[];
  };

  /**
   * 响应时间戳
   */
  @ApiProperty({
    description: '响应时间戳',
    example: 1641024000000
  })
  timestamp: number;
}

/**
 * 用户加入通知响应DTO
 * 
 * 职责：
 * - 通知会话中其他用户有新用户加入
 * - 包含新用户的基本信息和位置
 * - 支持实时用户状态更新
 */
export class UserJoinedNotification {
  /**
   * 响应类型标识
   */
  @ApiProperty({
    description: '响应类型',
    example: 'user_joined',
    enum: ['user_joined']
  })
  type: 'user_joined' = 'user_joined';

  /**
   * 加入的用户信息
   */
  @ApiProperty({
    description: '加入的用户信息',
    example: {
      userId: 'user3',
      socketId: 'socket3',
      joinedAt: 1641024000000,
      status: 'online'
    }
  })
  user: {
    userId: string;
    socketId: string;
    joinedAt: number;
    status: string;
    metadata?: Record<string, any>;
  };

  /**
   * 用户位置信息（如果有）
   */
  @ApiPropertyOptional({
    description: '用户位置信息',
    example: {
      x: 100,
      y: 200,
      mapId: 'plaza',
      timestamp: 1641024000000
    }
  })
  position?: {
    x: number;
    y: number;
    mapId: string;
    timestamp: number;
    metadata?: Record<string, any>;
  };

  /**
   * 会话ID
   */
  @ApiProperty({
    description: '会话ID',
    example: 'session_12345'
  })
  sessionId: string;

  /**
   * 响应时间戳
   */
  @ApiProperty({
    description: '响应时间戳',
    example: 1641024000000
  })
  timestamp: number;
}

/**
 * 用户离开通知响应DTO
 * 
 * 职责：
 * - 通知会话中其他用户有用户离开
 * - 包含离开用户的ID和离开原因
 * - 支持会话状态的实时更新
 */
export class UserLeftNotification {
  /**
   * 响应类型标识
   */
  @ApiProperty({
    description: '响应类型',
    example: 'user_left',
    enum: ['user_left']
  })
  type: 'user_left' = 'user_left';

  /**
   * 离开的用户ID
   */
  @ApiProperty({
    description: '离开的用户ID',
    example: 'user3'
  })
  userId: string;

  /**
   * 离开原因
   */
  @ApiProperty({
    description: '离开原因',
    example: 'user_left',
    enum: ['user_left', 'connection_lost', 'kicked', 'timeout', 'error']
  })
  reason: string;

  /**
   * 会话ID
   */
  @ApiProperty({
    description: '会话ID',
    example: 'session_12345'
  })
  sessionId: string;

  /**
   * 响应时间戳
   */
  @ApiProperty({
    description: '响应时间戳',
    example: 1641024000000
  })
  timestamp: number;
}

/**
 * 位置广播响应DTO
 * 
 * 职责：
 * - 广播用户位置更新给会话中的其他用户
 * - 包含完整的位置信息和时间戳
 * - 支持位置数据的实时同步
 */
export class PositionBroadcast {
  /**
   * 响应类型标识
   */
  @ApiProperty({
    description: '响应类型',
    example: 'position_broadcast',
    enum: ['position_broadcast']
  })
  type: 'position_broadcast' = 'position_broadcast';

  /**
   * 更新位置的用户ID
   */
  @ApiProperty({
    description: '更新位置的用户ID',
    example: 'user1'
  })
  userId: string;

  /**
   * 位置信息
   */
  @ApiProperty({
    description: '位置信息',
    example: {
      x: 150,
      y: 250,
      mapId: 'forest',
      timestamp: 1641024000000
    }
  })
  position: {
    x: number;
    y: number;
    mapId: string;
    timestamp: number;
    metadata?: Record<string, any>;
  };

  /**
   * 会话ID
   */
  @ApiProperty({
    description: '会话ID',
    example: 'session_12345'
  })
  sessionId: string;

  /**
   * 响应时间戳
   */
  @ApiProperty({
    description: '响应时间戳',
    example: 1641024000000
  })
  timestamp: number;
}

/**
 * 心跳响应DTO
 * 
 * 职责：
 * - 响应客户端的心跳检测请求
 * - 提供服务端时间戳用于延迟计算
 * - 维持WebSocket连接的活跃状态
 */
export class HeartbeatResponse {
  /**
   * 响应类型标识
   */
  @ApiProperty({
    description: '响应类型',
    example: 'heartbeat_response',
    enum: ['heartbeat_response']
  })
  type: 'heartbeat_response' = 'heartbeat_response';

  /**
   * 客户端时间戳（回显）
   */
  @ApiProperty({
    description: '客户端时间戳',
    example: 1641024000000
  })
  clientTimestamp: number;

  /**
   * 服务端时间戳
   */
  @ApiProperty({
    description: '服务端时间戳',
    example: 1641024000100
  })
  serverTimestamp: number;

  /**
   * 序列号（回显）
   */
  @ApiPropertyOptional({
    description: '心跳序列号',
    example: 1
  })
  sequence?: number;
}

/**
 * 错误响应DTO
 * 
 * 职责：
 * - 定义WebSocket通信中的错误响应格式
 * - 提供详细的错误信息和错误代码
 * - 支持客户端的错误处理和用户提示
 */
export class ErrorResponse {
  /**
   * 响应类型标识
   */
  @ApiProperty({
    description: '响应类型',
    example: 'error',
    enum: ['error']
  })
  type: 'error' = 'error';

  /**
   * 错误代码
   */
  @ApiProperty({
    description: '错误代码',
    example: 'INVALID_TOKEN',
    enum: [
      'INVALID_TOKEN',
      'SESSION_NOT_FOUND',
      'SESSION_FULL',
      'INVALID_POSITION',
      'RATE_LIMIT_EXCEEDED',
      'INTERNAL_ERROR',
      'VALIDATION_ERROR',
      'PERMISSION_DENIED'
    ]
  })
  code: string;

  /**
   * 错误消息
   */
  @ApiProperty({
    description: '错误消息',
    example: '无效的认证令牌'
  })
  message: string;

  /**
   * 错误详情（可选）
   */
  @ApiPropertyOptional({
    description: '错误详情',
    example: {
      field: 'token',
      reason: 'expired'
    }
  })
  details?: Record<string, any>;

  /**
   * 原始消息（可选，用于错误追踪）
   */
  @ApiPropertyOptional({
    description: '引起错误的原始消息',
    example: {
      type: 'join_session',
      sessionId: 'invalid_session'
    }
  })
  originalMessage?: any;

  /**
   * 响应时间戳
   */
  @ApiProperty({
    description: '响应时间戳',
    example: 1641024000000
  })
  timestamp: number;
}

/**
 * 成功响应DTO
 * 
 * 职责：
 * - 定义通用的成功响应格式
 * - 用于确认操作成功完成
 * - 提供操作结果的反馈
 */
export class SuccessResponse {
  /**
   * 响应类型标识
   */
  @ApiProperty({
    description: '响应类型',
    example: 'success',
    enum: ['success']
  })
  type: 'success' = 'success';

  /**
   * 成功消息
   */
  @ApiProperty({
    description: '成功消息',
    example: '操作成功完成'
  })
  message: string;

  /**
   * 操作类型
   */
  @ApiProperty({
    description: '操作类型',
    example: 'position_update',
    enum: ['join_session', 'leave_session', 'position_update', 'heartbeat']
  })
  operation: string;

  /**
   * 结果数据（可选）
   */
  @ApiPropertyOptional({
    description: '操作结果数据',
    example: {
      affected: 1,
      duration: 50
    }
  })
  data?: Record<string, any>;

  /**
   * 响应时间戳
   */
  @ApiProperty({
    description: '响应时间戳',
    example: 1641024000000
  })
  timestamp: number;
}