import { Controller, Get, Post, Body, Patch, Param, Delete, ParseIntPipe, DefaultValuePipe, ParseArrayPipe, ParseBoolPipe, NotFoundException, UseGuards, Query } from '@nestjs/common';
import { UsersService } from './users.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { ApiBearerAuth, ApiCreatedResponse, ApiOkResponse, ApiTags } from '@nestjs/swagger';
import { UserEntity } from './entities/user.entity';
import { JwtAuthGuard } from 'src/auth/jwt-auth.guard';

@Controller('users')
@ApiTags('users')
export class UsersController {
	constructor(private readonly usersService: UsersService) {}
	// add logger
	@Post()
	@ApiCreatedResponse({ type: UserEntity })
	async create(@Body() createUserDto: CreateUserDto, @Query('emailUser', new DefaultValuePipe(false), ParseBoolPipe) emailUser: boolean) {
		return this.usersService.create(createUserDto, emailUser);
		// return { message: 'success' }; //new UserEntity(await this.usersService.create(createUserDto));
	}

	@Get()
	@UseGuards(JwtAuthGuard)
	@ApiBearerAuth()
	@ApiOkResponse({ type: UserEntity, isArray: true })
	async findAll(@Query('page', new DefaultValuePipe(1), ParseIntPipe) page: number, @Query('limit', new DefaultValuePipe(10), ParseIntPipe) limit: number, @Query('sortBy') sortBy: string, @Query('sortOrder') sortOrder: string, @Query('search') search: string, @Query('active') active: string | undefined, @Query('clientId', new DefaultValuePipe(0), ParseIntPipe) clientId: number | undefined, @Query('role', new DefaultValuePipe([]), ParseArrayPipe) role: string | Array<string> | undefined) {
		// const users = await this.usersService.findAll((page - 1) * limit, limit, sortBy, sortOrder, search, active, clientId, role);
		// return users.map((user) => new UserEntity(user));
		return this.usersService.findAll((page - 1) * limit, limit, sortBy, sortOrder, search, active, clientId, role);
	}

	@Get('/simple')
	@UseGuards(JwtAuthGuard)
	@ApiBearerAuth()
	@ApiOkResponse({ type: UserEntity, isArray: true })
	async findAllSimple(@Query() params: any) {
		const users = await this.usersService.findAllSimple(params);
		return users.map((user) => new UserEntity(user));
	}

	@Get(':id')
	@UseGuards(JwtAuthGuard)
	@ApiBearerAuth()
	@ApiOkResponse({ type: UserEntity })
	async findOne(@Param('id', ParseIntPipe) id: number) {
		const user = await this.usersService.findOne(id);
		if (user === null) {
			throw new NotFoundException();
		}
		return new UserEntity(user);
	}

	@Patch(':id')
	@UseGuards(JwtAuthGuard)
	@ApiBearerAuth()
	@ApiCreatedResponse({ type: UserEntity })
	async update(@Param('id', ParseIntPipe) id: number, @Body() updateUserDto: UpdateUserDto) {
		console.log(updateUserDto);
		return new UserEntity(await this.usersService.update(id, updateUserDto));
	}

	@Delete(':id')
	@UseGuards(JwtAuthGuard)
	@ApiBearerAuth()
	@ApiOkResponse({ type: UserEntity })
	async remove(@Param('id', ParseIntPipe) id: number) {
		return new UserEntity(await this.usersService.remove(id));
	}

	// activate code

	@Get('/activate/:code')
	@ApiOkResponse({ type: UserEntity })
	async checkActivate(@Param('code') code: string) {
		const user = await this.usersService.keyCheckUser(code);
		if (user === null) {
			throw new NotFoundException();
		}
		return { message: 'success' };
	}

	@Patch('/activate/:code')
	@ApiOkResponse({ type: UserEntity })
	async activate(@Param('code') code: string) {
		return await this.usersService.activateUser(code);
	}

	// password reset code
	@Post('/reset')
	@ApiOkResponse({ type: UserEntity })
	async passwordReset(@Body() body: any) {
		return await this.usersService.resetPassword(body.email);
	}

	@Patch('/reset/:key')
	@ApiOkResponse({ type: UserEntity })
	async updatePassword(@Param('key') key: string, @Body() body: any) {
		return await this.usersService.updatePassword(key, body);
	}
}
