import {
    Controller,
    Put,
    Get,
    Body,
    Param,
    HttpStatus,
    NotFoundException,
    Delete,
    BadRequestException,
    Req,
    Post,
    Query
} from '@nestjs/common'
import { UsersService } from './users.service'
import { UserProfileDto } from './dto/user-profile.dto'
import { UserUpdateDto } from './dto/user-update.dto'
import { IUsers } from './interfaces/users.interface'
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'
import { HasRoles } from '../auth/roles.decorator'
import { HasAnyRoles } from '../auth/roles.decorator'
import { Role } from '../model/role.enum'
import { IPaginationOptions } from 'nestjs-typeorm-paginate'
import { PageRequest } from '../common/dto/page-request'
import { Users } from './entities/users.entity'
import { UserCreateDto } from './dto/user-create.dto'
import { format } from 'date-fns'

@ApiTags('users.admin')
@Controller('/admin/users')
@ApiBearerAuth()
@HasAnyRoles(Role.Admin, Role.Api, Role.Org)
export class UsersAdminController {
    constructor(private readonly usersService: UsersService) {}

    @Post()
    public async list(@Body() page: PageRequest<Users>, @Req() req) {
        return await this.usersService.findAll(page)
    }

    @Put()
    public async create(@Body() user: UserCreateDto, @Req() req) {
        if (req.user.roles.includes(Role.Api)) {
            return await this.usersService.createSubUser(user, req.user.id)
        }
        return await this.usersService.create(user)
    }

    @Get('/get')
    public async get(@Req() req) {
        const user = await this.usersService.findById(req.user.userId)
        return user
    }

    @Put('/:userId')
    public async updateUser(@Param('userId') userId: string, @Body() userUpdateDto: UserUpdateDto) {
        try {
            await this.usersService.updateUser(Number(userId), userUpdateDto)

            return {
                message: 'User Updated successfully!',
                status: HttpStatus.OK
            }
        } catch (err) {
            throw new BadRequestException(err, 'Error: User not updated!')
        }
    }

    @Delete('/:userId')
    public async deleteUser(@Param('userId') userId: number): Promise<void> {
        await this.usersService.deleteUser(userId)
    }

    @Get('/getDatas')
    public async getDatas(@Query() { apiUserId }) {
        const apiNum = await this.usersService.getCount(apiUserId ? Number(apiUserId) : undefined, Role.Api)
        const userNum = await this.usersService.getCount(apiUserId ? Number(apiUserId) : undefined, Role.User)
        const todayNum = await this.usersService.getCount(
            apiUserId ? Number(apiUserId) : undefined,
            undefined,
            format(new Date(), 'yyyy-MM-dd')
        )
        const week = await this.usersService.getWeekCount(apiUserId ? Number(apiUserId) : undefined)
        return {
            api: apiNum,
            user: userNum,
            today: todayNum,
            week: week
        }
    }
}
