import { Controller, Get, Post, Body, Query, Inject, Res } from '@nestjs/common';
import { Public } from './Public';
import { AuthService } from './AuthService';
import { LoginParamsDTO, SignupParamsDTO, AuthSessionDTO } from './dtos/AuthDto';
import type { CommandResultDTO } from './presenters/CommandResultPresenter';
import type { Response } from 'express';

@Public()
@Controller('auth')
export class AuthController {
  constructor(@Inject(AuthService) private readonly authService: AuthService) {}

  @Post('signup')
  async signup(@Body() params: SignupParamsDTO): Promise<AuthSessionDTO> {
    return this.authService.signupWithEmail(params);
  }

  @Post('login')
  async login(@Body() params: LoginParamsDTO): Promise<AuthSessionDTO> {
    return this.authService.loginWithEmail(params);
  }

  @Get('session')
  async getSession(@Res() res: Response): Promise<void> {
    const session = await this.authService.getCurrentSession();
    // Nest treats `null`/`undefined` as "no body" for Express responses; we need JSON `null`
    // so browser clients can safely call `response.json()`.
    res.json(session);
  }

  @Post('logout')
  async logout(): Promise<CommandResultDTO> {
    return this.authService.logout();
  }

  @Get('iracing/start')
  async startIracingAuth(@Query('returnTo') returnTo?: string): Promise<{ redirectUrl: string }> {
    const redirectUrl = await this.authService.startIracingAuth(returnTo);
    return { redirectUrl };
  }

  @Get('iracing/callback')
  async iracingCallback(
    @Query('code') code: string,
    @Query('state') state: string,
    @Query('returnTo') returnTo?: string,
  ): Promise<AuthSessionDTO> {
    return this.authService.iracingCallback(code, state, returnTo);
  }
}
