import {
  Body,
  Controller,
  Get,
  Headers,
  Patch,
  Post,
  Query,
  Req,
  UploadedFile,
  UseGuards,
  UseInterceptors,
} from "@nestjs/common"
import { FileInterceptor } from "@nestjs/platform-express"
import {
  ApiBearerAuth,
  ApiBody,
  ApiConsumes,
  ApiHeader,
  ApiOperation,
  ApiResponse,
  ApiTags,
} from "@nestjs/swagger"
import { Request } from "express"
import { profilePicConfig } from "../../../common/file-upload/profile-pic.config"
import { AuthGuardMiddleware } from "../../../middleware/auth-guard.middleware"
import { AuthService } from "./auth.service"
import { ChangePasswordDto } from "../dto/change-password.dto"
import { EditProfileDto } from "../dto/edit-profile.dto"
import { LoginDto } from "../dto/login.dto"
import { ResetPasswordDto } from "../dto/reset-password.dto"
import { failureResponse } from "src/common/response/response"
import { MobileLoginDto } from "../dto/mobile-login.dto"
import { RefreshTokenDto } from "../dto/refresh-token.dto"
@Controller("auth")
@ApiTags("Auth")
export class AuthController {
  constructor(private readonly authService: AuthService) {}

  @Post("login")
  @ApiOperation({ summary: "Login API" })
  @ApiResponse({ status: 200, description: "Check Login" })
  login(@Body() loginDto: LoginDto) {
    return this.authService.login(loginDto)
  }

  @Post("forgot-password")
  @ApiBody({
    schema: {
      type: "object",
      properties: {
        email: {
          type: "string",
          example: "admin@admin.com",
          description: "Your registered email address",
        },
      },
      required: ["name"],
    },
  })
  forgotPassword(@Body("email") email: string) {
    return this.authService.forgotPassword(email)
  }

  @Post("reset-password")
  resetPassword(
    @Req() req: Request,
    @Body() resetPasswordDto: ResetPasswordDto,
    @Query("token") token: string,
  ) {
    // const token = req.query.token as string
    if (!token) {
      return failureResponse(400, "Token is missing in query params")
    }
    return this.authService.resetPassword(token, resetPasswordDto)
  }

  @Get("get-profile")
  @ApiBearerAuth("access-token")
  @UseGuards(AuthGuardMiddleware)
  getProfile(@Req() request: Request) {
    return this.authService.getProfile(request.headers["authorization"])
  }

  @Patch("edit-profile")
  @ApiConsumes("multipart/form-data")
  @ApiBody({
    description: "Edit profile",
    schema: {
      type: "object",
      properties: {
        first_name: { type: "string", description: "First name of the user" },
        last_name: {
          type: "string",
          description: "Last name of the user",
          nullable: true,
        },
        contact_no: {
          type: "string",
          description: "Mobile number of the user",
        },
        profile_pic: {
          type: "string",
          format: "binary",
          description: "Profile picture of the user",
        },
      },
      required: ["first_name", "contact_no"],
    },
  })
  @ApiBearerAuth("access-token")
  @UseGuards(AuthGuardMiddleware)
  @UseInterceptors(FileInterceptor("profile_pic", profilePicConfig))
  editProfile(
    @Req() request: Request,
    @Body() editProfileDto: EditProfileDto,
    @UploadedFile() profile_pic: any,
  ) {
    return this.authService.editProfile(
      request.headers["authorization"],
      editProfileDto,
      profile_pic,
    )
  }

  @Post("change-password")
  @ApiBearerAuth("access-token")
  @UseGuards(AuthGuardMiddleware)
  changePassword(
    @Req() request: Request,
    @Body() changePasswordDto: ChangePasswordDto,
  ) {
    return this.authService.changePassword(
      request.headers["authorization"],
      changePasswordDto,
    )
  }

  @Post("logout")
  @ApiBearerAuth("access-token")
  @UseGuards(AuthGuardMiddleware)
  logout(@Req() request: Request) {
    return this.authService.logout(request.headers["authorization"])
  }

  @Post("mobile-login")
  @ApiOperation({ summary: "Mobile Login with Email or Contact No" })
  @ApiHeader({
    name: "device_token",
    description: "Device token for push notification",
    required: false,
  })
  @ApiBody({
    schema: {
      type: "object",
      properties: {
        email: {
          type: "string",
          example: "user@example.com",
          description: "Email (optional if contact_no provided)",
        },
        country_code: {
          type: "string",
          example: "+91",
          description: "Country code required if using contact_no",
        },
        contact_no: {
          type: "string",
          example: "9876543210",
          description: "Contact Number (optional if email provided)",
        },
        device_id: {
          type: "string",
          example: "abc123xyz",
          description: "Device ID",
        },
        device_type: {
          type: "string",
          example: "android",
          description: "Device Type (android/ios)",
        },
        os_version: {
          type: "string",
          example: "13.0",
          description: "OS Version",
        },
        role: {
          type: "string",
          example: "driver",
          description: "Role of the user",
        },
        fcm_token: {
          type: "string",
          example: "abc123xyz",
          description: "FCM Token",
        },
      },
      required: [],
    },
  })
  mobileLogin(@Body() mobileLoginDto: MobileLoginDto, @Req() request: Request) {
    const deviceToken = request.headers["device_token"] as string
    mobileLoginDto.device_token = deviceToken
    return this.authService.mobileLogin(mobileLoginDto)
  }

  @Post("verify-otp")
  @ApiOperation({ summary: "Verify OTP with expiry check (1 minute)" })
  @ApiResponse({ status: 200, description: "OTP verification result" })
  @ApiBody({
    schema: {
      type: "object",
      properties: {
        user_id: {
          type: "number",
          example: 70,
          description: "User ID",
        },
        otp: {
          type: "string",
          example: "123456",
          description: "OTP code",
        },
      },
      required: ["otp", "user_id"],
    },
  })
  @ApiHeader({
    name: "fcm-token",
    description: "FCM Token for push notifications",
    required: false,
    schema: {
      type: "string",
      example: "abc123xyz",
    },
  })
  async verifyOtp(
    @Body() body: { otp: string; user_id: number },
    @Headers("fcm-token") fcmToken?: string,
  ) {
    return this.authService.verifyOtp(body.otp, body.user_id, fcmToken)
  }

  @Post("refresh-token")
  @ApiOperation({ summary: "Refresh Access Token using Refresh Token" })
  @ApiResponse({ status: 200, description: "New access token generated" })
  @ApiBody({
    description: "Refresh token to get new access token",
    type: RefreshTokenDto,
  })
  async refreshToken(@Body() refreshTokenDto: RefreshTokenDto) {
    return this.authService.refreshAccessToken(refreshTokenDto.refresh_token)
  }

  @Post("remove-fcm-token")
  @ApiBearerAuth("access-token")
  @UseGuards(AuthGuardMiddleware)
  removeFcmToken(@Body() body: { fcm_token: string }) {
    return this.authService.removeFcmTokens([body.fcm_token])
  }
}
