import {
  Controller,
  Post,
  Get,
  Delete,
  Param,
  UseGuards,
  UseInterceptors,
  UploadedFile,
  Res,
  Query,
  StreamableFile,
  Header,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { Response } from 'express';
import { FilesService } from './files.service';
import { JwtAuthGuard } from '../../common/guards/jwt.guard';
import { CurrentUser } from '../../common/decorators/current-user.decorator';
import { Workspace } from '../../common/decorators/workspace.decorator';

@Controller('files')
@UseGuards(JwtAuthGuard)
export class FilesController {
  constructor(private readonly filesService: FilesService) {}

  @Post('upload')
  @UseInterceptors(FileInterceptor('file', {
    limits: { fileSize: 100 * 1024 * 1024 }, // 100MB max
  }))
  async upload(
    @UploadedFile() file: Express.Multer.File,
    @CurrentUser('userId') userId: string,
    @Workspace('id') wsId: string,
  ) {
    if (!file) {
      return { error: 'No file provided' };
    }
    return this.filesService.uploadFile(file, userId, wsId);
  }

  @Get()
  async list(
    @Workspace('id') wsId: string,
    @Query('channel_id') channelId?: string,
    @Query('page') page?: string,
    @Query('limit') limit?: string,
  ) {
    return this.filesService.listByWorkspace(
      wsId,
      page ? parseInt(page, 10) : 1,
      limit ? parseInt(limit, 10) : 20,
      channelId,
    );
  }

  @Get(':id')
  async get(@Param('id') id: string, @Workspace('id') wsId: string) {
    return this.filesService.findById(id, wsId);
  }

  @Get(':id/download')
  @Header('Content-Disposition', 'attachment')
  async download(
    @Param('id') id: string,
    @Workspace('id') wsId: string,
    @Res({ passthrough: true }) res: Response,
  ) {
    const { stream, filename, mimeType } = await this.filesService.getDownloadStream(id, wsId);
    const readable = await stream;
    res.setHeader('Content-Type', mimeType);
    res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
    return new StreamableFile(readable);
  }

  @Get(':id/url')
  async getSignedUrl(@Param('id') id: string, @Workspace('id') wsId: string) {
    return this.filesService.getSignedUrl(id, wsId);
  }

  @Delete(':id')
  async delete(
    @Param('id') id: string,
    @CurrentUser('userId') userId: string,
    @Workspace('id') wsId: string,
  ) {
    return this.filesService.delete(id, userId, wsId);
  }
}