/* eslint-disable @typescript-eslint/no-unused-vars */
import { <%_ if (authenticationType === 'jwt') { _%> Body, Param, Post, Res, UseGuards, <%_ } _%> Controller, Get, HttpCode, Logger, Req, UseInterceptors, ClassSerializerInterceptor, InternalServerErrorException } from '@nestjs/common';
<%_ if (authenticationType === 'jwt') { _%>
import { Response, Request } from 'express';
import { AuthGuard, Roles, RoleType, RolesGuard } from '../../security';
import { PasswordChangeDTO } from '../../service/dto/password-change.dto';
<%_ } _%>
import { <%= user.dtoClass%> } from '../../service/dto/user.dto';
import { LoggingInterceptor } from '../../client/interceptors/logging.interceptor';
import {<%_ if (authenticationType === 'jwt') { _%> ApiBearerAuth, <%_ } _%> ApiTags, ApiResponse, ApiOperation } from '@nestjs/swagger';
import { AuthService } from '../../service/auth.service';

@Controller('api')
@UseInterceptors(LoggingInterceptor, ClassSerializerInterceptor)
@ApiTags('account-resource')
export class AccountController {
  logger = new Logger('AccountController');

  constructor(private readonly authService: AuthService) { }
  <%_ if (!skipUserManagement && authenticationType !=='oauth2') { _%>

  @Post('/register')
  @ApiOperation({ summary: 'Register user' })
  @ApiResponse({
    status: 201,
    description: 'Registered user',
    type: <%= user.dtoClass%>,
  })
  async registerAccount(@Req() req: Request, @Body() userDTO: <%= user.dtoClass%> & { password: string }): Promise <any> {
    return await this.authService.registerNewUser(userDTO);
  }

  @Get('/activate')
  @ApiBearerAuth()
  @UseGuards(AuthGuard, RolesGuard)
  @Roles(RoleType.ADMIN)
  @ApiOperation({ summary: 'Activate an account' })
  @ApiResponse({
    status: 200,
    description: 'activated',
  })
  activateAccount(@Param() key: string, @Res() res: Response): any {
    throw new InternalServerErrorException();
  }

  @Get('/authenticate')
  @ApiBearerAuth()
  @UseGuards(AuthGuard)
  @ApiOperation({ summary: 'Check if the user is authenticated' })
  @ApiResponse({
    status: 200,
    description: 'login authenticated',
  })
  isAuthenticated(@Req() req: Request): any {
    const user: any = req.user;
    return user.login;
  }

  @Get('/account')
  @ApiBearerAuth()
  @UseGuards(AuthGuard)
  @ApiOperation({ summary: 'Get the current user.' })
  @ApiResponse({
    status: 200,
    description: 'user retrieved',
  })
  async getAccount(@Req() req: Request): Promise<any> {
    const user: any = req.user;
    const userProfileFound = await this.authService.getAccount(user.id);
    <%_ if (databaseType === 'mongodb') { _%>
    if (userProfileFound && !userProfileFound.firstName) {
        userProfileFound.firstName ='';
    }
    if (userProfileFound && !userProfileFound.lastName) {
        userProfileFound.lastName ='';
    }
    <%_ } _%>
    return userProfileFound;
  }

  @Post('/account')
  @HttpCode(200)
  @ApiBearerAuth()
  @UseGuards(AuthGuard)
  @ApiOperation({ summary: 'Update the current user information' })
  @ApiResponse({
    status: 200,
    description: 'user info updated',
    type: <%= user.dtoClass%>,
  })
  async saveAccount(@Req() req: Request, @Body() newUserInfo: <%= user.dtoClass%>): Promise<any> {
    const user: any = req.user;
    return await this.authService.updateUserSettings(user.login, newUserInfo);
  }

  @Post('/account/change-password')
  @HttpCode(200)
  @ApiBearerAuth()
  @UseGuards(AuthGuard)
  @ApiOperation({ summary: 'Change current password' })
  @ApiResponse({
    status: 200,
    description: 'user password changed',
    type: PasswordChangeDTO,
  })
  async changePassword(@Req() req: Request, @Body() passwordChange: PasswordChangeDTO): Promise<any> {
    const user: any = req.user;
    return await this.authService.changePassword(user.login, passwordChange.currentPassword, passwordChange.newPassword);
  }

  @Post('/account/reset-password/init')
  @ApiBearerAuth()
  @UseGuards(AuthGuard)
  @ApiOperation({ summary: 'Send an email to reset the password of the user' })
  @ApiResponse({
    status: 201,
    description: 'mail to reset password sent',
    type: 'string',
  })
  requestPasswordReset(@Req() req: Request, @Body() email: string, @Res() res: Response): any {
    throw new InternalServerErrorException();
  }

  @Post('/account/reset-password/finish')
  @ApiBearerAuth()
  @UseGuards(AuthGuard)
  @ApiOperation({ summary: 'Finish to reset the password of the user' })
  @ApiResponse({
    status: 201,
    description: 'password reset',
    type: 'string',
  })
  finishPasswordReset(@Req() req: Request, @Body() keyAndPassword: string, @Res() res: Response): any {
    throw new InternalServerErrorException();
  }

  <%_ } else if (authenticationType === 'oauth2') { _%>

  @Get('/account')
  @ApiOperation({ summary: 'Get the current user if logged' })
  @ApiResponse({
    status: 200,
    description: 'User retrieved',
    type: <%= user.dtoClass%>,
  })
  getAccount(@Req() req: any): any {
    if(!req.session) {
       return;
    }
    const userDTO: <%= user.dtoClass%> = req.session.user;
    return this.authService.getAccount(userDTO);
  }

  <%_ } else {_%>

  @Get('/account')
  @ApiBearerAuth()
  @UseGuards(AuthGuard)
  @ApiOperation({ summary: 'Get the current user.' })
  @ApiResponse({
    status: 200,
    description: 'user retrieved',
  })
  async getAccount(@Req() req: Request): Promise<any> {
    const user: any = req.user;
    return await this.authService.getAccount(user.id);
  }
  <%_ } _%>

}
