import { BadRequestException, Body, Controller, Delete, Get, NotFoundException, Param, ParseIntPipe, Post, Put, UploadedFile, UseInterceptors } from '@nestjs/common';
import { RegisterDto } from './dto/register.dto';
import { ApiTags } from '@nestjs/swagger';
import { PrismaService } from './services/prisma.service';
import { FileInterceptor } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { extname } from 'path';
import { AppGetaway } from './app.getaway';

@ApiTags('App')
@Controller('app')
export class AppController {
  constructor(private prisma: PrismaService, private socketService: AppGetaway) { }


  @Get('candidates')
  getCandidateList() {
    return this.prisma.candidate.findMany({
      select: {
        id: true,
        fullName: true,
        age: true,
        cityOrRegion: true,
        profileImage: true,
      }
    })
  }

  @Get('candidate/:id')
  getCandidateDetails(@Param('id', ParseIntPipe) id: number) {
    return this.prisma.candidate.findFirst({ where: { id: id } });
  }


  @Post('register')
  @UseInterceptors(FileInterceptor('profileImage', {
    storage: diskStorage({
      destination: 'assets/uploads',
      filename: (req, file, cb) => {
        const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
        const ext = extname(file.originalname);
        cb(null, `${file.fieldname}-${uniqueSuffix}${ext}`);
      }
    })
  }))
  async register(
    @UploadedFile() file: Express.Multer.File,
    @Body() dto: RegisterDto
  ) {
    const imagePath = file ? file.filename : null;
    const savedCandidate = await this.prisma.candidate.create({
      data: {
        ...dto,
        profileImage: imagePath,
        createdAt: new Date(),
      },
    });
    this.socketService.onAddCandidate(savedCandidate);

    return savedCandidate;
  }

  @Put('candidate/:id')
  @UseInterceptors(FileInterceptor('profileImage', {
    storage: diskStorage({
      destination: 'assets/uploads',
      filename: (req, file, cb) => {
        const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
        const ext = extname(file.originalname);
        cb(null, `${file.fieldname}-${uniqueSuffix}${ext}`);
      }
    })
  }))
  async update(
    @Param('id', ParseIntPipe) id: number,
    @UploadedFile() file: Express.Multer.File,
    @Body() dto: RegisterDto
  ) {
    const candidate = await this.prisma.candidate.findFirst({ where: { id } });
    if (!candidate) throw new NotFoundException(`Candidate with id ${id} not found`);

    const dayMilliseconds = 86400000;
    const expirationDate = new Date(candidate.createdAt.valueOf() + 3 * dayMilliseconds);
    if (expirationDate < new Date()) throw new BadRequestException(`Cannot edit candidate form after 3 days`);

    const profileImagePath = file ? file.filename : candidate.profileImage;

    const updatedCandidate = await this.prisma.candidate.update({
      where: { id },
      data: {
        ...dto,
        profileImage: profileImagePath,
      },
    });
    this.socketService.onUpdateCandidate(updatedCandidate);

    return;
  }


  @Delete('candidate/:id')
  async deleteCandidate(@Param('id', ParseIntPipe) id: number) {
    const candidate = await this.prisma.candidate.findFirst({ where: { id } });
    if (!candidate) throw new NotFoundException(`Candidate with id ${id} not found`);

    await this.prisma.candidate.delete({ where: { id } });

    this.socketService.onDeleteCandidate(id);

    return candidate;
  }
}
