import { AuthMethod, MultiTenancyInterceptor, UseAuth } from '@backend/auth'
import {
	Body,
	Controller,
	Delete,
	Get,
	HttpCode,
	Param,
	ParseUUIDPipe,
	Post,
	Put,
	UseInterceptors,
} from '@nestjs/common'
import {
	ApiBadRequestResponse,
	ApiConflictResponse,
	ApiForbiddenResponse,
	ApiInternalServerErrorResponse,
	ApiNoContentResponse,
	ApiNotFoundResponse,
	ApiOkResponse,
	ApiTags,
	ApiUnauthorizedResponse,
} from '@nestjs/swagger'
import { UserService } from '../services'
import { CreateUserRequest, UpdateMessagingTokenRequest, UpdateUserRequest, UserResponse } from '../types'

@UseAuth(AuthMethod.JWT)
@UseInterceptors(MultiTenancyInterceptor)
@Controller('user')
@ApiTags('default')
export class UserController {
	constructor(private readonly _userService: UserService) {}

	@Get()
	@ApiOkResponse({ type: UserResponse, isArray: true })
	@ApiInternalServerErrorResponse()
	async findAll(): Promise<UserResponse[]> {
		return this._userService.findAll()
	}

	@Get(':id')
	@ApiOkResponse({ type: UserResponse })
	@ApiBadRequestResponse()
	@ApiNotFoundResponse()
	@ApiInternalServerErrorResponse()
	async findById(@Param('id', ParseUUIDPipe) id: string): Promise<UserResponse> {
		return this._userService.findById(id)
	}

	@Post()
	@ApiOkResponse({ type: UserResponse })
	@ApiBadRequestResponse()
	@ApiConflictResponse()
	@ApiInternalServerErrorResponse()
	async create(@Body() request: CreateUserRequest): Promise<UserResponse> {
		return this._userService.create(request)
	}

	@Put(':id')
	@ApiOkResponse({ type: UserResponse })
	@ApiBadRequestResponse()
	@ApiNotFoundResponse()
	@ApiInternalServerErrorResponse()
	async updateById(@Param('id', ParseUUIDPipe) id: string, @Body() request: UpdateUserRequest): Promise<UserResponse> {
		return this._userService.updateById(id, request)
	}

	@Put(':id/token')
	@HttpCode(204)
	@ApiNoContentResponse()
	@ApiBadRequestResponse()
	@ApiNotFoundResponse()
	@ApiInternalServerErrorResponse()
	async updateMessagingTokenById(
		@Param('id', ParseUUIDPipe) userId: string,
		@Body() request: UpdateMessagingTokenRequest,
	): Promise<void> {
		return this._userService.updateMessagingTokenById(userId, request)
	}

	@Delete(':id')
	@HttpCode(204)
	@ApiNoContentResponse()
	@ApiBadRequestResponse()
	@ApiNotFoundResponse()
	@ApiForbiddenResponse()
	@ApiInternalServerErrorResponse()
	async deleteById(@Param('id', ParseUUIDPipe) id: string): Promise<void> {
		return this._userService.deleteById(id)
	}

	@Get('me')
	@ApiOkResponse({ type: UserResponse })
	@ApiUnauthorizedResponse()
	@ApiInternalServerErrorResponse()
	async getProfile(): Promise<UserResponse> {
		return this._userService.getProfile()
	}
}
