import { Body, Controller, Patch, Post, Req, UseGuards } from '@nestjs/common';
import { ApiBearerAuth, ApiBody, ApiCreatedResponse, ApiTags, ApiUnauthorizedResponse } from '@nestjs/swagger';
import { AuthUserService } from './authUserservice';
import { CreateUserDto } from 'src/user/dto/create-user.dto';
import { LoginUserDto } from './dto/login-user.dto';
import { UserSigninResDto } from './dto/user-signin-res.dto';
import { AuthUserGuard } from './authUser.guard';
import { CustomUserRequest } from './interface/customUserReq';
import { UpdatePwdDto } from './dto/update-pwd.dto';
import {
  UserConfirmEmailBody,
  UserRequestCodeBody,
  UserResetPasswordBody,
  UserResetPasswordDto,
} from './dto/user-reset-password.dto';
import { GetResetCode } from './dto/get-reset-code.dto';
import { EmailService } from 'src/email/email.service';

@Controller('')
@ApiTags('Create user account and sign in as user')
export class AuthUserController {
  constructor(
    private readonly authUserService: AuthUserService,
    private readonly mailService: EmailService,
  ) {}

  @ApiBody({ type: CreateUserDto })
  @ApiCreatedResponse({
    type: UserSigninResDto,
  })
  @Post('user/signup')
  async signUp(@Body() createAdminDto: CreateUserDto) {
    try {
      const adminSigninResDto = await this.authUserService.signUp(createAdminDto);
      return { user: adminSigninResDto };
    } catch (e) {
      throw e;
    }
  }
  @ApiBody({ type: LoginUserDto })
  @ApiCreatedResponse({
    type: UserSigninResDto,
  })
  @ApiUnauthorizedResponse()
  @Post('user/signin')
  async signIn(@Body() loginAdminDto: LoginUserDto) {
    try {
      const userSigninResDto = await this.authUserService.signIn(loginAdminDto);
      return { user: userSigninResDto };
    } catch (e) {
      throw e;
    }
  }

  @UseGuards(AuthUserGuard)
  @ApiBearerAuth('jwt')
  @Patch('user/change-password')
  async changePassword(@Req() req: CustomUserRequest, @Body() updatePwdDto: UpdatePwdDto) {
    return this.authUserService.changePassword(req.user.email, updatePwdDto);
  }

  @ApiBody({ type: UserResetPasswordBody })
  @Post('user/reset-password')
  async resetPassword(@Body() resetPasswordDto: UserResetPasswordDto) {
    return this.authUserService.resetPassword(resetPasswordDto);
  }

  @ApiBody({ type: UserRequestCodeBody })
  @Post('user/get-reset-code')
  async getResetCode(@Body() resetPasswordInfo: GetResetCode) {
    try {
      const code = await this.authUserService.getResetPasswordCode(resetPasswordInfo.email);
      await this.mailService.sendResetPasswordEmail(resetPasswordInfo.email, code);
    } catch (e) {
      throw e;
    }
  }

  @ApiBearerAuth('jwt')
  @UseGuards(AuthUserGuard)
  @Post('user/resend-confirmation-code')
  async resendConfirmationCode(@Req() req: CustomUserRequest) {
    try {
      const email = req.user.email;
      await this.authUserService.sendConfirmationCode(email);
      return { message: 'Confirmation code sent' };
    } catch (e) {
      throw e;
    }
  }

  @ApiBody({ type: UserConfirmEmailBody })
  @ApiBearerAuth('jwt')
  @UseGuards(AuthUserGuard)
  @Post('user/confirm-email')
  async confirmEmail(@Body() { code }, @Req() req: CustomUserRequest) {
    try {
      const email = req.user.email;
      return await this.authUserService.confirmEmail(email, { code });
    } catch (e) {
      throw e;
    }
  }
}
