import { AuthMethod, MultiTenancyInterceptor, UseAuth } from '@backend/auth'
import { Body, Controller, HttpCode, Post, Put, UseInterceptors } from '@nestjs/common'
import { ApiResponse, ApiTags } from '@nestjs/swagger'
import { AuthService } from './services'
import {
	LoginRequest,
	LoginResponse,
	RequestResetPasswordRequest,
	ResetPasswordRequest,
	UpdatePasswordRequest,
	VerifyEmailRequest,
	VerifyTokenRequest,
	VerifyTokenResponse,
} from './types'

@Controller('auth')
@ApiTags('default')
export class AuthController {
	constructor(private readonly _authService: AuthService) {}

	@Post('login')
	@HttpCode(200)
	@ApiResponse({
		status: 200,
		description: 'Login successful',
		type: LoginResponse,
	})
	async login(@Body() request: LoginRequest): Promise<LoginResponse> {
		return this._authService.login(request)
	}

	@Post('verify')
	@HttpCode(204)
	@ApiResponse({
		status: 204,
		description: 'Email verified',
	})
	async verifyEmail(@Body() request: VerifyEmailRequest): Promise<void> {
		return this._authService.startEmailVerification(request)
	}

	@Post('verify/token')
	@HttpCode(200)
	@ApiResponse({
		status: 200,
		description: 'Email token verified',
		type: VerifyTokenResponse,
	})
	async verifyEmailToken(@Body() request: VerifyTokenRequest): Promise<VerifyTokenResponse> {
		return this._authService.verifyToken(request.token)
	}

	@Post('password/reset')
	@HttpCode(204)
	@ApiResponse({
		status: 204,
		description: 'Reset password email sent',
	})
	async sendResetPasswordEmail(@Body() request: RequestResetPasswordRequest): Promise<void> {
		return this._authService.sendResetPasswordEmail(request)
	}

	@Post('password/reset/new')
	@HttpCode(204)
	@ApiResponse({
		status: 204,
		description: 'Password reset successful',
	})
	async resetPassword(@Body() request: ResetPasswordRequest): Promise<void> {
		return this._authService.resetPassword(request)
	}

	@Put('password')
	@UseAuth(AuthMethod.JWT)
	@UseInterceptors(MultiTenancyInterceptor)
	@HttpCode(204)
	@ApiResponse({
		status: 204,
		description: 'Password updated successful',
	})
	async updatePassword(@Body() request: UpdatePasswordRequest): Promise<void> {
		return this._authService.updatePassword(request)
	}
}
