import {
  Controller, Post, Get, Patch,
  Param, Body, Request, UseGuards, ParseIntPipe,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { AuthService } from './auth.service';
import { LoginDto } from './dto/login.dto';
import { UserService } from '../user/user.service';
import { CreateUserDto } from '../user/dto/create-user.dto';
import { UpdateUserDto } from '../user/dto/update-user.dto';
import { Public } from './../common/guards/decorators/public.decorator';

@Controller('auth')
export class AuthController {
  constructor(
    private readonly authService: AuthService,
    private readonly userService: UserService,
  ) {}

  // ✅ Register — now sends OTP email
  @Public()
  @Post('register')
  async register(@Body() createUserDto: CreateUserDto) {
    return this.authService.register(createUserDto);
  }

  // ✅ Verify email OTP after registration
  @Public()
  @Post('verify-email-otp')
  async verifyEmailOtp(@Body() body: { email: string; otp: string }) {
    return this.authService.verifyEmailOtp(body.email, body.otp);
  }

  // ✅ Resend OTP (verify or reset)
  @Public()
  @Post('resend-otp')
  async resendOtp(@Body() body: { email: string; type: 'verify' | 'reset' }) {
    return this.authService.resendOtp(body.email, body.type);
  }

  // ✅ Forgot password — sends reset OTP
  @Public()
  @Post('forgot-password')
  async forgotPassword(@Body() body: { email: string }) {
    return this.authService.forgotPassword(body.email);
  }

  // ✅ Verify reset OTP
  @Public()
  @Post('verify-reset-otp')
  async verifyResetOtp(@Body() body: { email: string; otp: string }) {
    return this.authService.verifyResetOtp(body.email, body.otp);
  }

  // ✅ Reset password — after OTP verified
  @Public()
  @Post('reset-password')
  async resetPassword(@Body() body: { email: string; password: string }) {
    return this.authService.resetPassword(body.email, body.password);
  }

  // ✅ Login
  @Public()
  @Post('login')
  async login(@Body() loginDto: LoginDto) {
    const user = await this.authService.validateUser(loginDto.email, loginDto.password);
    return this.authService.login(user);
  }

  // ✅ Get current user
  @UseGuards(AuthGuard('jwt'))
  @Get('me')
  async getMe(@Request() req: any) {
    return this.userService.findOne(req.user.id);
  }

  // ✅ Update user
  @UseGuards(AuthGuard('jwt'))
  @Patch('update/:id')
  async updateUser(
    @Param('id', ParseIntPipe) id: number,
    @Body() updateUserDto: UpdateUserDto,
  ) {
    if (updateUserDto.password) {
      updateUserDto.password = await this.authService.hashPassword(updateUserDto.password);
    }
    const user = await this.userService.update(id, updateUserDto);
    return { message: 'User updated successfully', user };
  }

  // ✅ Admin — get pending users
  @UseGuards(AuthGuard('jwt'))
  @Get('pending-users')
  async getPendingUsers() {
    return this.userService.findPendingUsers();
  }

  // ✅ Admin — approve user
  @UseGuards(AuthGuard('jwt'))
  @Patch('approve/:id')
  async approveUser(@Param('id', ParseIntPipe) id: number) {
    return this.authService.approveUser(id);
  }

  // ✅ Admin — reject user
  @UseGuards(AuthGuard('jwt'))
  @Patch('reject/:id')
  async rejectUser(@Param('id', ParseIntPipe) id: number) {
    return this.authService.rejectUser(id);
  }
}