import { Body, Controller, Delete, Get, Param, ParseFilePipeBuilder, Post, Put, Query, UploadedFile, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { memoryStorage } from 'multer';
import { WheelProcessService } from './wheel-process.service';
import { ProcessImportCommitDto, ProcessListQuery } from '../process-shared/process-shared.dto';
import { ProcessRecordWriteDto } from '../process-shared/process-shared.types';

type UploadedMemoryFile = {
  originalname: string;
  buffer: Buffer;
};

@Controller('wheel-process')
export class WheelProcessController {
  constructor(private readonly wheelProcessService: WheelProcessService) {}

  @Get()
  list(@Query() query: ProcessListQuery) {
    return this.wheelProcessService.list(query);
  }

  @Get('options')
  options() {
    return this.wheelProcessService.options();
  }

  @Post('calculate')
  calculate(@Body() body: ProcessRecordWriteDto) {
    return this.wheelProcessService.calculate(body);
  }

  @Get('export')
  export(@Query() query: ProcessListQuery & { format?: string }) {
    return this.wheelProcessService.export(query);
  }

  @Get('sample')
  sample(@Query('format') format = 'xlsx') {
    return this.wheelProcessService.sample(format);
  }

  @Post('import/preview')
  @UseInterceptors(FileInterceptor('file', { storage: memoryStorage() }))
  previewImport(
    @UploadedFile(
      new ParseFilePipeBuilder()
        .addMaxSizeValidator({ maxSize: 10 * 1024 * 1024 })
        .build({ fileIsRequired: true }),
    )
    file: UploadedMemoryFile,
  ) {
    return this.wheelProcessService.previewImport(file.originalname, file.buffer);
  }

  @Post('import')
  @UseInterceptors(FileInterceptor('file', { storage: memoryStorage() }))
  importFile(
    @UploadedFile(
      new ParseFilePipeBuilder()
        .addMaxSizeValidator({ maxSize: 10 * 1024 * 1024 })
        .build({ fileIsRequired: true }),
    )
    file: UploadedMemoryFile,
    @Body('mode') mode?: 'validOnly' | 'allOrNothing',
  ) {
    return this.wheelProcessService.importFile(file.originalname, file.buffer, mode === 'allOrNothing' ? 'allOrNothing' : 'validOnly');
  }

  @Post('import/commit')
  commitImport(@Body() body: ProcessImportCommitDto) {
    return this.wheelProcessService.commitImport(body);
  }

  @Get(':id')
  detail(@Param('id') id: string) {
    return this.wheelProcessService.detail(id);
  }

  @Post()
  create(@Body() body: ProcessRecordWriteDto) {
    return this.wheelProcessService.create(body);
  }

  @Put(':id')
  update(@Param('id') id: string, @Body() body: ProcessRecordWriteDto) {
    return this.wheelProcessService.update(id, body);
  }

  @Delete(':id')
  delete(@Param('id') id: string) {
    return this.wheelProcessService.delete(id);
  }
}
