import { ApiBody, ApiResponse, ApiTags } from '@nestjs/swagger';
import {
  Body,
  Controller,
  Get,
  Post,
  Req,
  Request,
  UseGuards,
} from '@nestjs/common';
import { AuthService } from '../../auth/auth.service';
import { GoogleAuthGuard } from '../../auth/google-auth.guard';
import { SkipAuth } from '../../auth/auth.decorators';
import { LocalAuthGuard } from '../../auth/local-auth.guard';
import { LoginQueryDto } from '../dtos/queries/login.query.dto';
import { CreateUserCommandDto } from '../../swagger-adapter/user/create-user-command.dto';
import { AuthGoogleService } from '../../auth/auth-google.service';
import { AuthGoogleLoginDto } from '../../swagger-adapter/auth/auth-google-login.dto';
import { CreateUserCommandHandlerService } from '@modules/security/usecases/user/create-user-command-handler.service';
import { UserRepositoryPort } from '@modules/security/repositories/user-repository.port';

@ApiTags('auth resource')
@Controller('api/auth')
export class AuthController {
  createUserCommandHandlerService: CreateUserCommandHandlerService;

  constructor(
    private authService: AuthService,
    private userRepositoryPort: UserRepositoryPort,
    private authGoogleService: AuthGoogleService,
  ) {
    this.createUserCommandHandlerService = new CreateUserCommandHandlerService(
      userRepositoryPort,
    );
  }

  @SkipAuth()
  @UseGuards(LocalAuthGuard)
  @Post('login')
  @ApiBody({ type: LoginQueryDto })
  @ApiResponse({ status: 201, description: 'User logged in successfully' })
  async login(@Request() req) {
    return this.authService.login(req.user);
  }

  @Post('register')
  register(@Body() user: CreateUserCommandDto) {
    return this.createUserCommandHandlerService.execute(user);
  }

  @SkipAuth()
  @UseGuards(GoogleAuthGuard)
  @Get('google/login')
  // eslint-disable-next-line @typescript-eslint/no-empty-function
  async googleLogin() {}

  @SkipAuth()
  @UseGuards(GoogleAuthGuard)
  @Get('google/callback')
  async googleAuthCallback(@Req() req) {
    const token = await this.authService.signIn(req.user);

    return { access_token: token };
  }

  @SkipAuth()
  @Post('google/mobile-sign-in')
  async googleMobileSignIn(@Body() loginDto: AuthGoogleLoginDto) {
    const user = await this.authGoogleService.getProfileByToken(loginDto);

    const token = await this.authService.signIn(user);

    return { access_token: token };
  }
}
