import { Controller, Headers, Post, Body, UseGuards, Get, Req, HttpException, HttpStatus, BadRequestException, InternalServerErrorException, NotFoundException, UnauthorizedException, Logger } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthSchema, JwtPayload } from '@nice/common';
import { AuthGuard } from './auth.guard';
import { UserProfileService } from './utils';
import { z } from 'zod';
import { FileValidationErrorType } from './types';
@Controller('auth')
export class AuthController {
  private logger = new Logger(AuthController.name)
  constructor(private readonly authService: AuthService) { }
  @Get('file')
  async authFileRequset(
    @Headers('x-original-uri') originalUri: string,
    @Headers('x-real-ip') realIp: string,
    @Headers('x-original-method') method: string,
    @Headers('x-query-params') queryParams: string,
    @Headers('host') host: string,
    @Headers('authorization') authorization: string,
  ) {
  
    try {
      const fileRequest = {
        originalUri,
        realIp,
        method,
        queryParams,
        host,
        authorization
      };

      const authResult = await this.authService.validateFileRequest(fileRequest);
      if (!authResult.isValid) {
        // 使用枚举类型进行错误处理
        switch (authResult.error) {
          case FileValidationErrorType.INVALID_URI:
            throw new BadRequestException(authResult.error);
          case FileValidationErrorType.RESOURCE_NOT_FOUND:
            throw new NotFoundException(authResult.error);
          case FileValidationErrorType.AUTHORIZATION_REQUIRED:
          case FileValidationErrorType.INVALID_TOKEN:
            throw new UnauthorizedException(authResult.error);
          default:
            throw new InternalServerErrorException(authResult.error || FileValidationErrorType.UNKNOWN_ERROR);
        }
      }
      return {
        headers: {
          'X-User-Id': authResult.userId,
          'X-Resource-Type': authResult.resourceType,
        },
      };
    } catch (error: any) {
      this.logger.verbose(`File request auth failed from ${realIp} reason:${error.message}`)
      throw error;
    }
  }
  @UseGuards(AuthGuard)
  @Get('user-profile')
  async getUserProfile(@Req() request: Request) {

    const payload: JwtPayload = (request as any).user;
    const { staff } = await UserProfileService.instance.getUserProfileById(payload.sub);
    return staff
  }
  @Post('login')
  async login(@Body() body: z.infer<typeof AuthSchema.signInRequset>) {
    return this.authService.signIn(body);
  }
  @Post('signup')
  async signup(@Body() body: z.infer<typeof AuthSchema.signUpRequest>) {
    return this.authService.signUp(body);
  }
  @Post('refresh-token')
  async refreshToken(
    @Body() body: z.infer<typeof AuthSchema.refreshTokenRequest>,
  ) {
    return this.authService.refreshToken(body);
  }
  // @UseGuards(AuthGuard)
  @Post('logout')
  async logout(@Body() body: z.infer<typeof AuthSchema.logoutRequest>) {
    return this.authService.logout(body);
  }
  @UseGuards(AuthGuard) // Protecting the changePassword endpoint with AuthGuard
  @Post('change-password')
  async changePassword(
    @Body() body: z.infer<typeof AuthSchema.changePassword>,
  ) {
    return this.authService.changePassword(body);
  }
}
