import {
  BadRequestException,
  Body,
  Controller,
  Delete,
  Get,
  Param,
  ParseIntPipe,
  Post,
  Res,
  UploadedFile,
  UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { isNullOrUndefined } from 'ts-core-utils-is';
import { Attachment } from './attachment.entity';
import { RemoveAttachmentWorkflow } from './workflows/remove-attachment/remove-attachment.workflow';
import { StreamAttachmentUploadWorkflow } from './workflows/stream-attachment-upload/stream-attachment-upload.workflow';
import { StreamAttachmentWorkflow } from './workflows/stream-attachment/stream-attachment.workflow';

@Controller('attachment')
export class AttachmentController {
  constructor(
    private streamAttachmentWorkflow: StreamAttachmentWorkflow,
    private streamAttachmentUploadWorkflow: StreamAttachmentUploadWorkflow,
    private removeAttachmentWorkflow: RemoveAttachmentWorkflow
  ) {}

  @Post()
  @UseInterceptors(FileInterceptor('file'))
  async uploadAttachment(@Body() body: any, @UploadedFile() file) {
    if (isNullOrUndefined(body) || isNullOrUndefined(body.licenseeId)) {
      throw new BadRequestException('"licenseeId" missing in body');
    }

    if (isNullOrUndefined(file)) {
      throw new BadRequestException('"file" missing in body');
    }

    return (
      await this.streamAttachmentUploadWorkflow.stream(
        file,
        parseFloat(body.licenseeId)
      )
    ).id;
  }

  @Get(':id/file')
  async getFile(@Param('id', ParseIntPipe) id: number, @Res() res) {
    await this.streamAttachmentWorkflow.stream(id, res);
  }

  @Get(':id/thumbnail')
  async getThumbnail(@Param('id', ParseIntPipe) id: number, @Res() res) {
    await this.streamAttachmentWorkflow.stream(id, res, true);
  }

  @Delete(':id')
  async deleteAttachment(@Param('id', ParseIntPipe) id: number) {
    const attachment = await Attachment.findOne(id);

    if (attachment === undefined) {
      throw new BadRequestException('No Attachment found with provided id');
    }

    await this.removeAttachmentWorkflow.remove(attachment);
  }
}
