import { Controller, Post, Get, Delete, Patch, Body, Param, Query, UseGuards, Req, ParseIntPipe, Res } from '@nestjs/common';
import { ApiTags, ApiBearerAuth, ApiBody } from '@nestjs/swagger';
import { AuthGuard } from '@nestjs/passport';
import { SandboxService } from './sandbox.service';
import { ChatOptions } from '../ai/ai-gateway.service';
import { Response } from 'express';

@ApiTags('AI沙箱')
@Controller('sandbox')
export class SandboxController {
  constructor(private sandboxService: SandboxService) {}

  @Get('models')
  async getModels() {
    return { items: this.sandboxService.getAvailableModels() };
  }

  @Post('chat')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiBody({ schema: { example: { conversationId: 'uuid', model: 'deepseek-v4-flash', messages: [{ role: 'user', content: 'hi' }], images: ['https://example.com/img.png'], temperature: 0.7, top_p: 1, max_tokens: 2000, stream: false } } })
  async chat(@Req() req: any, @Body() body: { conversationId?: string; model: string; messages: { role: string; content: string }[]; images?: string[]; stream?: boolean } & ChatOptions, @Res() res: Response) {
    if (body.stream) {
      res.setHeader('Content-Type', 'text/event-stream');
      res.setHeader('Cache-Control', 'no-cache');
      res.setHeader('Connection', 'keep-alive');
      res.setHeader('X-Accel-Buffering', 'no');

      try {
        for await (const chunk of this.sandboxService.chatStream(req.user.userId, body.conversationId, body.model, body.messages, body, body.images)) {
          res.write(`data: ${chunk}\n\n`);
        }
      } catch (err: any) {
        res.write(`data: ${JSON.stringify({ type: 'error', message: err.message })}\n\n`);
      }
      res.end();
    } else {
      const result = await this.sandboxService.chat(req.user.userId, body.conversationId, body.model, body.messages, body, body.images);
      res.json(result);
    }
  }

  @Get('sessions')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  async sessions(@Req() req: any, @Query() query: { page?: number; pageSize?: number; search?: string }) {
    return this.sandboxService.getSessions(req.user.userId, query);
  }

  @Get('sessions/:id')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  async getSession(@Req() req: any, @Param('id', ParseIntPipe) id: number) {
    return this.sandboxService.getSession(req.user.userId, id);
  }

  @Patch('sessions/:id/feedback')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  async setFeedback(@Req() req: any, @Param('id', ParseIntPipe) id: number, @Body() body: { feedback: 'LIKE' | 'DISLIKE' | null }) {
    return this.sandboxService.setFeedback(req.user.userId, id, body.feedback);
  }

  @Delete('sessions/:id')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  async deleteSession(@Req() req: any, @Param('id', ParseIntPipe) id: number) {
    return this.sandboxService.deleteSession(req.user.userId, id);
  }

  @Get('quota')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  async quota(@Req() req: any) {
    return this.sandboxService.getQuota(req.user.userId);
  }

  @Post('sessions/:id/share')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  async share(@Req() req: any, @Param('id', ParseIntPipe) id: number) {
    return this.sandboxService.generateShareToken(req.user.userId, id);
  }

  @Patch('sessions/:id/rename')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  async rename(@Req() req: any, @Param('id', ParseIntPipe) id: number, @Body() body: { title: string }) {
    return this.sandboxService.renameSession(req.user.userId, id, body.title);
  }
}
