import {
  Controller,
  UseGuards,
  Post,
  HttpCode,
  HttpStatus,
  Req,
  Res,
  UnauthorizedException,
  Get,
  Param,
  Body
} from '@nestjs/common';
import { Response } from 'express';
import { AuthService } from './auth.service';
import { RolesService } from 'src/roles/roles.service';
import { LocalAuthGuard } from './guards/local-auth.guard'
import { RefreshTokenGuard } from './guards/refreshToken.guard';
import { Public } from '../common/decorators/public.decorator';
import RequestWithUser from '../common/interfaces/requestWithUser.interface';
import { ResetPasswordDto } from './dto/reset-password.dto';
// import { UsersService } from 'src/users/users.service';

@Controller('auth')
export class AuthController {
  constructor(
    private authService: AuthService,
    private rolesService: RolesService,
    // private readonly usersService: UsersService
  ) {}

  @Post('login')
  @Public()
  @UseGuards(LocalAuthGuard)
  @HttpCode(HttpStatus.OK)
  // See local.strategy.ts
  async login(
    @Req() req: RequestWithUser,
    // Leave response handling to nest, see the warning at the end of:
    // https://docs.nestjes.com/controllers#routing
    @Res({ passthrough: true }) res: Response
  ) {
    // console.log('Triggered auth.controller.ts.login');
    // console.log('headers during login', req.headers)
    // console.log('cookies', req.cookies)
    // console.log('signed cookies', req.signedCookies)
    // console.log('req.user', req.user);
    const { user_id, username, user_class_id } = req.user;
    const roles = await this.rolesService.findNamesByUserId(user_id)
    const tokens = await this.authService.getTokens(user_id, username, user_class_id, roles);
    this.authService.setClientCookies(res, tokens);
    // Return the tokens (server to server)
    return { redirect: '/member/guidelines', ...tokens };
  }

  @Post('reset')
  @Public()
  @HttpCode(HttpStatus.OK)
  // See local.strategy.ts
  async reset(
    @Req() req: RequestWithUser,
    @Body() body: ResetPasswordDto,
    // Leave response handling to nest, see the warning at the end of:
    // https://docs.nestjes.com/controllers#routing
    @Res({ passthrough: true }) res: Response
  ) {
    // console.log('Triggered auth.controller.ts.reset');
    // console.log('req.username', body.username)
    // const { user_id, username } = req.user;
    // const roles = await this.rolesService.findNamesByUserId(user_id)
    // const tokens = await this.authService.getTokens(user_id, username, roles);
    // this.authService.setClientCookies(res, tokens);
    // // Return the tokens (server to server)
    return { redirect: '/reset-instructions' };
  }

  @Post('refresh')
  // See refresh.strategy.ts
  @Public() // no access token is presented, it has expired
  @UseGuards(RefreshTokenGuard)
  @HttpCode(HttpStatus.OK)
  async refresh(
    @Req() req: RequestWithUser,
    @Res({ passthrough: true }) res: Response
  ) {
    const { access_token, refresh_token } = req.user;
    if (!access_token || !refresh_token) throw new UnauthorizedException();
    const tokens = { access_token, refresh_token };
    this.authService.setClientCookies(res, tokens);
    // Return the tokens (server to server)
    return { tokens };
  }

  @Post('logout')
  @HttpCode(HttpStatus.NO_CONTENT)
  async logout(
    @Req() req: RequestWithUser,
    // Leave response handling to nest
    @Res({ passthrough: true }) res: Response
  ) {
    // console.log('Triggered auth.controller.ts.logout')
    const { user_id } = req.user;
    await this.authService.logout(user_id);
    // await this.usersService.clearSelectedProfile(user_id);
    this.authService.clearClientCookies(res);
    return;
  }

  @Post('confirm/:type/:userHash/:token')
  @Public()
  @HttpCode(HttpStatus.OK)
  async confirmRegistration(
    @Param('type') type: string,
    @Param('userHash') userHash: string,
    @Param('token') token: string
  ) {
    // console.log('registration')
    // console.log('type', type)
    // console.log('userHash', userHash)
    // console.log('token', token)
    return ;
  }

  // @Post('confirm/change-of-email/:userHash/:token')
  // @Public()
  // @HttpCode(HttpStatus.OK)
  // async confirmEmail() {
  //   console.log('change-of-email')
  //   console.log('userHash', userHash)
  //   console.log('token', token)
  //   return;
  // }

  // @Post('confirm/change-of-password/:userHash/:token')
  // @Public()
  // @HttpCode(HttpStatus.OK)
  // async confirmPassword() {
  //   console.log('change-of-password')
  //   console.log('userHash', userHash)
  //   console.log('token', token)
  //   return;
  // }
}