/**
 * 聊天相关的 REST API 控制器
 * 
 * 功能描述：
 * - 提供聊天消息的 REST API 接口
 * - 获取聊天历史记录
 * - 查看系统状态和统计信息
 * - 管理 WebSocket 连接状态
 * 
 * 职责分离：
 * - REST接口：提供HTTP方式的聊天功能访问
 * - 状态查询：提供系统运行状态和统计信息
 * - 文档支持：提供WebSocket API的使用文档
 * - 监控支持：提供连接数和性能监控接口
 * 
 * 最近修改：
 * - 2026-01-07: 代码规范优化 - 完善文件头注释和修改记录 (修改者: moyin)
 * 
 * @author angjustinl
 * @version 1.0.1
 * @since 2025-01-07
 * @lastModified 2026-01-07
 */

import {
  Controller,
  Post,
  Get,
  Body,
  Query,
  UseGuards,
  HttpStatus,
  HttpException,
  Logger,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiBearerAuth,
  ApiQuery,
} from '@nestjs/swagger';
import { JwtAuthGuard } from '../auth/jwt_auth.guard';
import { ZulipService } from './zulip.service';
import { CleanWebSocketGateway } from './clean_websocket.gateway';
import {
  SendChatMessageDto,
  ChatMessageResponseDto,
  GetChatHistoryDto,
  ChatHistoryResponseDto,
  SystemStatusResponseDto,
} from './chat.dto';

@ApiTags('chat')
@Controller('chat')
export class ChatController {
  private readonly logger = new Logger(ChatController.name);

  constructor(
    private readonly zulipService: ZulipService,
    private readonly websocketGateway: CleanWebSocketGateway,
  ) {}

  /**
   * 发送聊天消息（REST API 方式）
   * 
   * 注意：这是 WebSocket 消息发送的 REST API 替代方案
   * 推荐使用 WebSocket 接口以获得更好的实时性
   */
  @Post('send')
  @UseGuards(JwtAuthGuard)
  @ApiBearerAuth('JWT-auth')
  @ApiOperation({
    summary: '发送聊天消息',
    description: '通过 REST API 发送聊天消息到 Zulip。注意：推荐使用 WebSocket 接口以获得更好的实时性。'
  })
  @ApiResponse({
    status: 200,
    description: '消息发送成功',
    type: ChatMessageResponseDto,
  })
  @ApiResponse({
    status: 400,
    description: '请求参数错误',
  })
  @ApiResponse({
    status: 401,
    description: '未授权访问',
  })
  @ApiResponse({
    status: 500,
    description: '服务器内部错误',
  })
  async sendMessage(
    @Body() sendMessageDto: SendChatMessageDto,
  ): Promise<ChatMessageResponseDto> {
    this.logger.log('收到REST API聊天消息发送请求', {
      operation: 'sendMessage',
      content: sendMessageDto.content.substring(0, 50),
      scope: sendMessageDto.scope,
      timestamp: new Date().toISOString(),
    });

    try {
      // 注意：这里需要一个有效的 socketId，但 REST API 没有 WebSocket 连接
      // 这是一个限制，实际使用中应该通过 WebSocket 发送消息
      throw new HttpException(
        '聊天消息发送需要通过 WebSocket 连接。请使用 WebSocket 接口：wss://whaletownend.xinghangee.icu',
        HttpStatus.BAD_REQUEST,
      );

    } catch (error) {
      const err = error as Error;
      this.logger.error('REST API消息发送失败', {
        operation: 'sendMessage',
        error: err.message,
        timestamp: new Date().toISOString(),
      });

      if (error instanceof HttpException) {
        throw error;
      }

      throw new HttpException(
        '消息发送失败，请稍后重试',
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  /**
   * 获取聊天历史记录
   */
  @Get('history')
  @UseGuards(JwtAuthGuard)
  @ApiBearerAuth('JWT-auth')
  @ApiOperation({
    summary: '获取聊天历史记录',
    description: '获取指定地图或全局的聊天历史记录'
  })
  @ApiQuery({
    name: 'mapId',
    required: false,
    description: '地图ID，不指定则获取全局消息',
    example: 'whale_port'
  })
  @ApiQuery({
    name: 'limit',
    required: false,
    description: '消息数量限制',
    example: 50
  })
  @ApiQuery({
    name: 'offset',
    required: false,
    description: '偏移量（分页用）',
    example: 0
  })
  @ApiResponse({
    status: 200,
    description: '获取聊天历史成功',
    type: ChatHistoryResponseDto,
  })
  @ApiResponse({
    status: 401,
    description: '未授权访问',
  })
  @ApiResponse({
    status: 500,
    description: '服务器内部错误',
  })
  async getChatHistory(
    @Query() query: GetChatHistoryDto,
  ): Promise<ChatHistoryResponseDto> {
    this.logger.log('获取聊天历史记录', {
      operation: 'getChatHistory',
      mapId: query.mapId,
      limit: query.limit,
      offset: query.offset,
      timestamp: new Date().toISOString(),
    });

    try {
      // 注意：这里需要实现从 Zulip 获取消息历史的逻辑
      // 目前返回模拟数据
      const mockMessages = [
        {
          id: 1,
          sender: 'Player_123',
          content: '大家好！我刚进入游戏',
          scope: 'local',
          mapId: query.mapId || 'whale_port',
          timestamp: new Date(Date.now() - 3600000).toISOString(),
          streamName: 'Whale Port',
          topicName: 'Game Chat',
        },
        {
          id: 2,
          sender: 'Player_456',
          content: '欢迎新玩家！',
          scope: 'local',
          mapId: query.mapId || 'whale_port',
          timestamp: new Date(Date.now() - 1800000).toISOString(),
          streamName: 'Whale Port',
          topicName: 'Game Chat',
        },
      ];

      return {
        success: true,
        messages: mockMessages.slice(query.offset || 0, (query.offset || 0) + (query.limit || 50)),
        total: mockMessages.length,
        count: Math.min(mockMessages.length - (query.offset || 0), query.limit || 50),
      };

    } catch (error) {
      const err = error as Error;
      this.logger.error('获取聊天历史失败', {
        operation: 'getChatHistory',
        error: err.message,
        timestamp: new Date().toISOString(),
      });

      throw new HttpException(
        '获取聊天历史失败，请稍后重试',
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  /**
   * 获取系统状态
   */
  @Get('status')
  @ApiOperation({
    summary: '获取聊天系统状态',
    description: '获取 WebSocket 连接状态、Zulip 集成状态等系统信息'
  })
  @ApiResponse({
    status: 200,
    description: '获取系统状态成功',
    type: SystemStatusResponseDto,
  })
  @ApiResponse({
    status: 500,
    description: '服务器内部错误',
  })
  async getSystemStatus(): Promise<SystemStatusResponseDto> {
    this.logger.log('获取系统状态', {
      operation: 'getSystemStatus',
      timestamp: new Date().toISOString(),
    });

    try {
      // 获取 WebSocket 连接状态
      const totalConnections = await this.websocketGateway.getConnectionCount();
      const authenticatedConnections = await this.websocketGateway.getAuthenticatedConnectionCount();
      const mapPlayerCounts = await this.websocketGateway.getMapPlayerCounts();

      // 获取内存使用情况
      const memoryUsage = process.memoryUsage();
      const memoryUsedMB = (memoryUsage.heapUsed / 1024 / 1024).toFixed(1);
      const memoryTotalMB = (memoryUsage.heapTotal / 1024 / 1024).toFixed(1);
      const memoryPercentage = ((memoryUsage.heapUsed / memoryUsage.heapTotal) * 100);

      return {
        websocket: {
          totalConnections,
          authenticatedConnections,
          activeSessions: authenticatedConnections, // 简化处理
          mapPlayerCounts: mapPlayerCounts,
        },
        zulip: {
          serverConnected: true, // 需要实际检查
          serverVersion: '11.4',
          botAccountActive: true,
          availableStreams: 12,
          gameStreams: ['Whale Port', 'Pumpkin Valley', 'Novice Village'],
          recentMessageCount: 156, // 需要从实际数据获取
        },
        uptime: Math.floor(process.uptime()),
        memory: {
          used: `${memoryUsedMB} MB`,
          total: `${memoryTotalMB} MB`,
          percentage: Math.round(memoryPercentage * 100) / 100,
        },
      };

    } catch (error) {
      const err = error as Error;
      this.logger.error('获取系统状态失败', {
        operation: 'getSystemStatus',
        error: err.message,
        timestamp: new Date().toISOString(),
      });

      throw new HttpException(
        '获取系统状态失败，请稍后重试',
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  /**
   * 获取 WebSocket 连接信息
   */
  @Get('websocket/info')
  @ApiOperation({
    summary: '获取 WebSocket 连接信息',
    description: '获取 WebSocket 连接的详细信息，包括连接地址、协议等'
  })
  @ApiResponse({
    status: 200,
    description: '获取连接信息成功',
    schema: {
      type: 'object',
      properties: {
        websocketUrl: {
          type: 'string',
          example: 'wss://whaletownend.xinghangee.icu/game',
          description: 'WebSocket 连接地址'
        },
        namespace: {
          type: 'string',
          example: '/game',
          description: 'WebSocket 命名空间'
        },
        supportedEvents: {
          type: 'array',
          items: { type: 'string' },
          example: ['login', 'chat', 'position_update'],
          description: '支持的事件类型'
        },
        authRequired: {
          type: 'boolean',
          example: true,
          description: '是否需要认证'
        },
        documentation: {
          type: 'string',
          example: 'https://docs.example.com/websocket',
          description: '文档链接'
        }
      }
    }
  })
  async getWebSocketInfo() {
    return {
      websocketUrl: 'wss://whaletownend.xinghangee.icu/game',
      protocol: 'native-websocket',
      path: '/game',
      namespace: '/',
      supportedEvents: [
        'login',      // 用户登录
        'chat',       // 发送聊天消息
        'position',   // 位置更新
      ],
      supportedResponses: [
        'connected',      // 连接确认
        'login_success',  // 登录成功
        'login_error',    // 登录失败
        'chat_sent',      // 消息发送成功
        'chat_error',     // 消息发送失败
        'chat_render',    // 接收到聊天消息
        'error',          // 通用错误
      ],
      authRequired: true,
      tokenType: 'JWT',
      tokenFormat: {
        issuer: 'whale-town',
        audience: 'whale-town-users',
        type: 'access',
        requiredFields: ['sub', 'username', 'email', 'role']
      },
      documentation: '/api-docs',
    };
  }
}