/**
 * 位置广播HTTP API控制器
 *
 * 功能描述：
 * - 提供位置广播系统的REST API接口
 * - 处理HTTP请求和响应格式化
 * - 集成JWT认证和权限验证
 * - 提供完整的API文档和错误处理
 *
 * 职责分离：
 * - HTTP处理：专注于HTTP请求和响应的处理
 * - 数据转换：请求参数和响应数据的格式转换
 * - 权限验证：API访问权限的验证和控制
 * - 文档生成：Swagger API文档的自动生成
 *
 * 技术实现：
 * - NestJS控制器：使用装饰器定义API端点
 * - Swagger集成：自动生成API文档
 * - 数据验证：使用DTO进行请求数据验证
 * - 异常处理：统一的HTTP异常处理机制
 *
 * 最近修改：
 * - 2026-01-08: 功能新增 - 创建位置广播HTTP API控制器
 *
 * @author moyin
 * @version 1.0.0
 * @since 2026-01-08
 * @lastModified 2026-01-08
 */

import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Body,
  Param,
  Query,
  UseGuards,
  HttpStatus,
  HttpException,
  Logger,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiParam,
  ApiQuery,
  ApiBearerAuth,
  ApiBody,
} from '@nestjs/swagger';
import { JwtAuthGuard } from '../../../gateway/auth/jwt_auth.guard';
import { CurrentUser } from '../../../gateway/auth/current_user.decorator';
import { JwtPayload } from '../../../core/login_core/login_core.service';

// 导入业务服务
import {
  LocationBroadcastService,
  LocationSessionService,
  LocationPositionService,
} from '../services';

// 导入DTO
import {
  CreateSessionDto,
  SessionQueryDto,
  PositionQueryDto,
  UpdateSessionConfigDto,
} from '../dto/api.dto';

/**
 * 位置广播API控制器
 *
 * 提供以下API端点：
 * - 会话管理：创建、查询、配置会话
 * - 位置管理：查询位置、获取统计信息
 * - 用户管理：获取用户状态、清理数据
 */
@ApiTags('位置广播')
@Controller('location-broadcast')
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
export class LocationBroadcastController {
  private readonly logger = new Logger(LocationBroadcastController.name);

  constructor(
    private readonly locationBroadcastService: LocationBroadcastService,
    private readonly locationSessionService: LocationSessionService,
    private readonly locationPositionService: LocationPositionService,
  ) {}

  /**
   * 创建新会话
   */
  @Post('sessions')
  @ApiOperation({
    summary: '创建新游戏会话',
    description: '创建一个新的位置广播会话，支持自定义配置',
  })
  @ApiResponse({
    status: 201,
    description: '会话创建成功',
    schema: {
      type: 'object',
      properties: {
        success: { type: 'boolean', example: true },
        sessionId: { type: 'string', example: 'session_12345' },
        message: { type: 'string', example: '会话创建成功' },
      },
    },
  })
  @ApiResponse({ status: 400, description: '请求参数错误' })
  @ApiResponse({ status: 409, description: '会话ID已存在' })
  async createSession(
    @Body() createSessionDto: CreateSessionDto,
    @CurrentUser() user: JwtPayload,
  ) {
    try {
      const result = await this.locationSessionService.createSession({
        ...createSessionDto,
        creatorId: user.sub,
      });

      return {
        success: true,
        session: result,
        message: '会话创建成功',
      };
    } catch (error: any) {
      this.logger.error('创建会话失败', error);
      throw new HttpException(
        error.message || '创建会话失败',
        error.status || HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  /**
   * 查询会话列表
   */
  @Get('sessions')
  @ApiOperation({
    summary: '查询会话列表',
    description: '根据条件查询游戏会话列表，支持分页和过滤',
  })
  @ApiQuery({ name: 'status', required: false, description: '会话状态' })
  @ApiQuery({ name: 'limit', required: false, description: '分页大小' })
  @ApiQuery({ name: 'offset', required: false, description: '分页偏移' })
  @ApiResponse({
    status: 200,
    description: '查询成功',
    schema: {
      type: 'object',
      properties: {
        success: { type: 'boolean', example: true },
        sessions: { type: 'array', items: { type: 'object' } },
        total: { type: 'number', example: 10 },
        message: { type: 'string', example: '查询成功' },
      },
    },
  })
  async querySessions(
    @Query() query: SessionQueryDto,
    @CurrentUser() user: JwtPayload,
  ) {
    try {
      const result = await this.locationSessionService.querySessions(query as any);
      return {
        success: true,
        ...result,
        message: '查询成功',
      };
    } catch (error: any) {
      this.logger.error('查询会话失败', error);
      throw new HttpException(
        error.message || '查询会话失败',
        error.status || HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  /**
   * 获取会话详情
   */
  @Get('sessions/:sessionId')
  @ApiOperation({
    summary: '获取会话详情',
    description: '获取指定会话的详细信息，包括用户列表和位置信息',
  })
  @ApiParam({ name: 'sessionId', description: '会话ID' })
  @ApiResponse({
    status: 200,
    description: '获取成功',
    schema: {
      type: 'object',
      properties: {
        success: { type: 'boolean', example: true },
        session: { type: 'object' },
        users: { type: 'array', items: { type: 'object' } },
        message: { type: 'string', example: '获取成功' },
      },
    },
  })
  @ApiResponse({ status: 404, description: '会话不存在' })
  async getSessionDetail(
    @Param('sessionId') sessionId: string,
    @CurrentUser() user: JwtPayload,
  ) {
    try {
      const result = await this.locationSessionService.getSessionDetail(sessionId);
      return {
        success: true,
        ...result,
        message: '获取成功',
      };
    } catch (error: any) {
      this.logger.error('获取会话详情失败', error);
      throw new HttpException(
        error.message || '获取会话详情失败',
        error.status || HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  /**
   * 查询位置信息
   */
  @Get('positions')
  @ApiOperation({
    summary: '查询位置信息',
    description: '根据条件查询用户位置信息，支持范围查询和地图过滤',
  })
  @ApiQuery({ name: 'mapId', required: false, description: '地图ID' })
  @ApiQuery({ name: 'sessionId', required: false, description: '会话ID' })
  @ApiQuery({ name: 'limit', required: false, description: '分页大小' })
  @ApiResponse({
    status: 200,
    description: '查询成功',
    schema: {
      type: 'object',
      properties: {
        success: { type: 'boolean', example: true },
        positions: { type: 'array', items: { type: 'object' } },
        total: { type: 'number', example: 5 },
        message: { type: 'string', example: '查询成功' },
      },
    },
  })
  async queryPositions(
    @Query() query: PositionQueryDto,
    @CurrentUser() user: JwtPayload,
  ) {
    try {
      const result = await this.locationPositionService.queryPositions(query as any);
      return {
        success: true,
        ...result,
        message: '查询成功',
      };
    } catch (error: any) {
      this.logger.error('查询位置失败', error);
      throw new HttpException(
        error.message || '查询位置失败',
        error.status || HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  /**
   * 获取位置统计信息
   */
  @Get('positions/stats')
  @ApiOperation({
    summary: '获取位置统计信息',
    description: '获取系统位置数据的统计信息，包括用户分布和活跃度',
  })
  @ApiResponse({
    status: 200,
    description: '获取成功',
    schema: {
      type: 'object',
      properties: {
        success: { type: 'boolean', example: true },
        stats: { type: 'object' },
        message: { type: 'string', example: '获取成功' },
      },
    },
  })
  async getPositionStats(@CurrentUser() user: JwtPayload) {
    try {
      const stats = await this.locationPositionService.getPositionStats({});
      return {
        success: true,
        stats,
        message: '获取成功',
      };
    } catch (error: any) {
      this.logger.error('获取位置统计失败', error);
      throw new HttpException(
        error.message || '获取位置统计失败',
        error.status || HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  /**
   * 清理用户数据
   */
  @Delete('users/:userId/data')
  @ApiOperation({
    summary: '清理用户数据',
    description: '清理指定用户的位置数据和会话信息',
  })
  @ApiParam({ name: 'userId', description: '用户ID' })
  @ApiResponse({
    status: 200,
    description: '清理成功',
    schema: {
      type: 'object',
      properties: {
        success: { type: 'boolean', example: true },
        message: { type: 'string', example: '清理成功' },
      },
    },
  })
  async cleanupUserData(
    @Param('userId') userId: string,
    @CurrentUser() user: JwtPayload,
  ) {
    try {
      // 只允许用户清理自己的数据，或管理员清理任意用户数据
      if (user.sub !== userId && user.role !== 2) {
        throw new HttpException('权限不足', HttpStatus.FORBIDDEN);
      }

      await this.locationBroadcastService.cleanupUserData(userId);
      return {
        success: true,
        message: '清理成功',
      };
    } catch (error: any) {
      this.logger.error('清理用户数据失败', error);
      throw new HttpException(
        error.message || '清理用户数据失败',
        error.status || HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }
}