import { Body, Controller, Get, HttpCode, HttpStatus, Post, Req, Res, UploadedFile, UseInterceptors } from '@nestjs/common';
import { Roles } from 'src/roles/roles.decorator';
import { ERole } from 'src/roles/roles.service';
import { UploadService } from './upload.service';
import { GetDocumentCategories } from './dto/get-document-categories.dto';
import { FileInterceptor } from '@nestjs/platform-express';
import RequestWithUser from 'src/common/interfaces/requestWithUser.interface';
import { DocumentUpload } from './dto/document-upload.dto';
import { GetDocuments } from './dto/get-documents.dto';
import { FileDownload } from './dto/file-download.dto';
import { Response } from 'express';

@Controller('upload')
export class UploadController {
  constructor(
    private uploadService: UploadService,
  ) {}

  // Get categories for upload
  @Post('categories')
  @HttpCode(HttpStatus.OK)
  @Roles(
    ERole.IPWAdministrator,
    ERole.IPWAuditor,
    ERole.IPWLeadAuditor,
    ERole.MemberAdministrator,
    ERole.DocumentUploads
  )
  async categories(
    @Body() body: GetDocumentCategories
  ) {
    const data = await this.uploadService.getCategories(body.category_type);
    return { data };
  }

  // List previously uploaded documents
  @Post('documents')
  @HttpCode(HttpStatus.OK)
  @Roles(
    ERole.MemberAdministrator,
    ERole.DocumentUploads
  )
  async documentUploads(
    @Req() req: RequestWithUser,
    @Body() body: GetDocuments
  ) {
    if (body.user_group_id === null) return { data: { documents: [], categories: [], groups: [] } };
    const data = await this.uploadService.getDocuments(body.user_group_id, req.user.user_id);
    return { data };
  }

  // Upload a document
  @HttpCode(HttpStatus.NO_CONTENT)
  @Post('document')
  @UseInterceptors(FileInterceptor('file'))
  @Roles(
    ERole.IPWAdministrator,
    ERole.IPWAuditor,
    ERole.IPWLeadAuditor,
    ERole.MemberAdministrator,
    ERole.DocumentUploads
  )
  async document(
    @Req() req: RequestWithUser,
    @Body() body: DocumentUpload,
    @UploadedFile() file: Express.Multer.File
  ) {
    await this.uploadService.saveDocumentUpload(
      parseInt(body.user_group_id),
      req.user.user_id,
      parseInt(body.document_category_id),
      file
    );
    return;
  }
  // List all available user profiles for selection
  @Get('all-profiles')
  @HttpCode(HttpStatus.OK)
  @Roles(
    ERole.IPWAdministrator,
    ERole.IPWAuditor,
    ERole.IPWLeadAuditor
  )
  async getAllGroups() {
    const data = await this.uploadService.getAllProfiles();
    return { data };
  }

  // List previously uploaded documents by all users
  @Post('all-documents')
  @HttpCode(HttpStatus.OK)
  @Roles(
    ERole.IPWAdministrator,
    ERole.IPWAuditor,
    ERole.IPWLeadAuditor
  )
  async allDocumentUploads(
    @Body() body: GetDocuments
  ) {
    if (body.user_group_id === null) return { data: { documents: [], categories: [], groups: [], users: [] } };
    const data = await this.uploadService.getAllDocuments(body.user_group_id);
    return { data };
  }

  @Get('download-document')
  @Roles(
    ERole.IPWAdministrator,
    ERole.IPWAuditor,
    ERole.IPWLeadAuditor,
    ERole.MemberAdministrator,
    ERole.DocumentUploads
  )
  async downloadDocument(
    @Res() res: Response,
    @Body() body: FileDownload
  ) {

    // https://notiz.dev/blog/type-safe-file-downloads#preview-or-download-file
    // https://c2fo.github.io/fast-csv/docs/formatting/methods/#write
    // res.contentType('text/csv')
    // This never reaches the front-end for some reason, also tried res.set (http://expressjs.com/en/api.html#res.set)
    // and @Header (https://docs.nestjs.com/techniques/streaming-files) but there is no effect
    // res.attachment(`ipw_member_report_${(new Date().toJSON().slice(0,10))}.csv`);
    // const file = write(rows);
    // res.send(file);
    const { mimetype, file } = await this.uploadService.getDocumentPath(body.document_upload_id);
    // res.contentType(mimetype)
    // res.sendFile(file, {
    //   headers: {
    //     'Content-Type': mimetype
    //   }
    // });
    // res.status(200).contentType(mimetype).send(file);
    res.contentType(mimetype);
    res.download(file);
  }
}
