import {
  Body,
  Controller,
  Get,
  Param,
  Post,
  Put,
  Query,
  Res,
  UploadedFile,
  UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { SetCreatorService } from './set-creator.service';

@Controller('set-creator')
export class SetCreatorController {
  constructor(private readonly setCreatorService: SetCreatorService) {}

  @Get()
  list(@Query() query: Record<string, string>) {
    return this.setCreatorService.list(query);
  }

  @Get('options/inches')
  inches() {
    return this.setCreatorService.getInchOptions();
  }

  @Get('options/finishes')
  finishes() {
    return this.setCreatorService.getFinishOptions();
  }

  @Get('options/holders')
  holders(@Query('inch') inch?: string) {
    return this.setCreatorService.getHolderOptions(inch);
  }

  @Get('options/plates')
  plates(@Query('holderCode') holderCode?: string) {
    return this.setCreatorService.getPlateOptions(holderCode);
  }

  @Get('options/wheels')
  wheels(@Query('inch') inch?: string) {
    return this.setCreatorService.getWheelOptions(inch);
  }

  @Get('code-generator')
  codeGeneratorList(@Query() query: Record<string, string>) {
    return this.setCreatorService.listCodeGeneratorProducts(query);
  }

  @Get('code-generator/sets')
  codeGeneratorSets(@Query() query: Record<string, string>) {
    return this.setCreatorService.getCodeGeneratorSetOptions(query);
  }

  @Get('code-generator/delete-settings')
  codeGeneratorDeleteSettings() {
    return this.setCreatorService.getCodeGeneratorDeleteEmailSettings();
  }

  @Put('code-generator/delete-settings')
  updateCodeGeneratorDeleteSettings(@Body() body: any) {
    return this.setCreatorService.updateCodeGeneratorDeleteEmailSettings(body);
  }

  @Post('code-generator/delete/request-otp')
  requestCodeGeneratorDeleteOtp(@Body() body: any) {
    return this.setCreatorService.requestCodeGeneratorDeleteOtp(body);
  }

  @Post('code-generator/delete/confirm')
  confirmCodeGeneratorDelete(@Body() body: any) {
    return this.setCreatorService.confirmCodeGeneratorDelete(body);
  }

  @Get('code-generator/export')
  async codeGeneratorExportSelected(
    @Query('ids') ids: string | string[] | undefined,
    @Res() response: any,
  ) {
    const normalizedIds = this.normalizeCodeGeneratorSetIds(ids);
    const file = await this.setCreatorService.exportProducts(normalizedIds);

    response.setHeader('Content-Type', file.mime);
    response.setHeader(
      'Content-Disposition',
      `attachment; filename="Exports Data ${normalizedIds.length} Sets.csv"`,
    );
    response.send(Buffer.from(file.base64, 'base64'));
  }

  @Get('code-generator/export/:id')
  async codeGeneratorExport(@Param('id') id: string, @Res() response: any) {
    const [set, file] = await Promise.all([
      this.setCreatorService.detail(id),
      this.setCreatorService.exportProducts(id),
    ]);
    response.setHeader('Content-Type', file.mime);
    response.setHeader(
      'Content-Disposition',
      `attachment; filename="Exports Data SET ${set.setNumber}.csv"`,
    );
    response.send(Buffer.from(file.base64, 'base64'));
  }

  @Post('code-generator/import')
  @UseInterceptors(FileInterceptor('file'))
  codeGeneratorImport(@Body() body: any, @UploadedFile() file?: any) {
    return this.setCreatorService.importCodeGeneratorProducts(body, file);
  }

  @Get(':id/export')
  async export(@Param('id') id: string, @Res() response: any) {
    const [set, file] = await Promise.all([
      this.setCreatorService.detail(id),
      this.setCreatorService.exportProducts(id),
    ]);
    response.setHeader('Content-Type', file.mime);
    response.setHeader(
      'Content-Disposition',
      `attachment; filename="Exports Data SET ${set.setNumber}.csv"`,
    );
    response.send(Buffer.from(file.base64, 'base64'));
  }

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

  @Post()
  create(@Body() body: any) {
    return this.setCreatorService.create(body);
  }

  private normalizeCodeGeneratorSetIds(ids: string | string[] | undefined) {
    const values = Array.isArray(ids) ? ids : [ids || ''];
    return [...new Set(
      values
        .flatMap((value) => String(value || '').split(','))
        .map((value) => value.trim())
        .filter(Boolean),
    )];
  }
}
