import {
  Body,
  Controller,
  HttpCode,
  Post,
  Put,
  UseGuards,
  Request,
  Get,
  ConflictException,
} from "@nestjs/common";
import type { Request as ExpressRequest } from "express";
import { UsersService } from "../services/users.service.js";
import { BcryptService } from "../services/bcrypt.service.js";
import { JwtAuthGuard } from "../auth/jwt-auth.guard.js";
import { RegisterUserDto, UpdateUserDto, UserDto } from "@sigma/common";

@Controller("users")
export class UsersController {
  constructor(
    private usersService: UsersService,
    private bcryptService: BcryptService
  ) {}

  @Post()
  @HttpCode(201)
  async register(@Body() registerDto: RegisterUserDto): Promise<UserDto> {
    try {
      const user = await this.usersService.create({
        username: registerDto.username,
        passwordHash: await this.bcryptService.hashPassword(
          registerDto.password
        ),
        projects: [],
      });

      return {
        username: user.username,
      };
    } catch (error: any) {
      if ("code" in error && error.code === 11000) {
        throw new ConflictException("Username already exists");
      }

      throw error;
    }
  }

  @UseGuards(JwtAuthGuard)
  @Put()
  async update(
    @Request() req: ExpressRequest,
    @Body() updateDto: UpdateUserDto
  ) {
    this.usersService.update(req.user?._id, {
      passwordHash: await this.bcryptService.hashPassword(updateDto.password),
    });
  }

  @UseGuards(JwtAuthGuard)
  @Get("me")
  async getProfile(@Request() req: ExpressRequest): Promise<UserDto> {
    const user = await this.usersService.findOne(req.user?.username);

    return {
      username: user!.username,
    };
  }
}
