import {
  Body,
  Controller,
  Delete,
  Get,
  Headers,
  Param,
  Post,
  Query,
  Req,
  Res,
  UploadedFile,
  UseGuards,
  UseInterceptors,
} from '@nestjs/common';
import { UsersService } from './users.service';
import { Request, Response } from 'express';
import { LoginDto } from 'src/users/dto/login.dto';
import { VerifyOtpDto } from './dto/verify-otp.dto';
import { SignUpDto } from './dto/signup.dto';
import { ResendOtpDto } from './dto/resend-otp.dto';
import { ChangePasswordDto } from './dto/change-password.dto';
import { UserGuard } from './guards/user.auth.guard';
import { CreateInquiryDto } from './dto/create-inquiry.dto';
import { LogoutDto } from './dto/logout.dto';
import { FileInterceptor } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { editFileName, mediaFileFilter } from 'src/utils/file.upload.helper';
import { ApiHeader, ApiOperation, ApiParam, ApiQuery } from '@nestjs/swagger';

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  /***************************************SIGNUP*****************************************/
  @Post('signup')
  @ApiOperation({ summary: 'Signup' })
  @ApiHeader({ name: 'Content-Language', required: false })
  async SignUp(
    @Headers('Content-Language') lang: string,
    @Body() body: SignUpDto,
    @Res() res: Response,
  ) {
    return await this.usersService.SignUp(lang, body, res);
  }
  /*------------------------------------------------------------------------------------*/

  /***************************************RESEND OTP*************************************/
  @Post('resend_otp')
  @ApiOperation({ summary: 'Resend Otp' })
  @ApiHeader({ name: 'Content-Language', required: false })
  async resendOtp(
    @Headers('Content-Language') lang: string,
    @Body() body: ResendOtpDto,
    @Res() res: Response,
  ) {
    return await this.usersService.resendOtp(lang, body, res);
  }
  /*------------------------------------------------------------------------------------*/

  /***************************************VERIFY OTP*************************************/
  @Post('verify_otp')
  @ApiOperation({ summary: 'Verify Otp' })
  @ApiHeader({ name: 'Content-Language', required: false })
  async verifyOtp(
    @Headers('Content-Language') lang: string,
    @Body() body: VerifyOtpDto,
    @Res() res: Response,
  ) {
    return await this.usersService.verifyOtp(lang, body, res);
  }
  /*------------------------------------------------------------------------------------*/

  /***************************************LOGIN *****************************************/
  @Post('login')
  @ApiOperation({ summary: `User's Login` })
  @ApiHeader({ name: 'Content-Language', required: false })
  async login(
    @Headers('Content-Language') lang: string,
    @Body() body: LoginDto,
    @Res() res: Response,
  ) {
    return await this.usersService.login(lang, body, res);
  }
  /*------------------------------------------------------------------------------------*/

  /***************************************CHANGE PASSWORD********************************/
  @Post('change_password')
  @ApiOperation({ summary: 'Change Password' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @UseGuards(UserGuard)
  async changePassword(
    @Req() req: Request,
    @Headers('Content-Language') lang: string,
    @Body() body: ChangePasswordDto,
    @Res() res: Response,
  ) {
    return await this.usersService.changePassword(req, lang, body, res);
  }
  /*------------------------------------------------------------------------------------*/

  /************************************GET MY SHIPMENTS**********************************/
  @Get('get_my_shipments')
  @ApiOperation({ summary: 'Get My Shipments' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiQuery({ name: 'page', required: true, default: 1 })
  @ApiQuery({ name: 'limit', required: true, default: 10 })
  @ApiQuery({ name: 'job_id', required: false })
  @ApiQuery({ name: 'type', required: false })
  @UseGuards(UserGuard)
  async getMyShipments(
    @Req() req: Request,
    @Headers('Content-Language') lang: string,
    @Query('type') type: string,
    @Query('page') page: number,
    @Query('limit') limit: number,
    @Query('search') search :string,
    @Query('job_id') job_id: string,
    @Res() res: Response,
  ) {
    return await this.usersService.getMyShipmentsNew(
      req,
      lang,
      type,
      page,
      limit,
      job_id,
      res,
      search
    );
  }
  /*------------------------------------------------------------------------------------*/

  /************************************CREATE INQUIRY************************************/
  @Post('create_inquiry')
  @ApiOperation({ summary: 'Create Inquiry' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @UseGuards(UserGuard)
  async createInquiry(
    @Req() req: Request,
    @Headers('Content-Language') lang: string,
    @Body() body: CreateInquiryDto,
    @Res() res: Response,
  ) {
    return await this.usersService.createInquiry(req, lang, body, res);
  }
  /*------------------------------------------------------------------------------------*/

  /************************************GET MY INQUIRIES**********************************/
  @Get('get_my_inquiries')
  @ApiOperation({ summary: 'Get My Inquiries' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiQuery({ name: 'page', required: true, default: 1 })
  @ApiQuery({ name: 'limit', required: true, default: 10 })
  @UseGuards(UserGuard)
  async getMyInquiries(
    @Req() req: Request,
    @Query('page') page: number,
    @Query('limit') limit: number,
    @Res() res: Response,
  ) {
    return await this.usersService.getMyInquiries(req, page, limit, res);
  }
  /*------------------------------------------------------------------------------------*/

  /************************************LOG OUT*******************************************/
  @Post('log_out')
  @ApiOperation({ summary: 'Log Out' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @UseGuards(UserGuard)
  async logout(
    @Req() req: Request,
    @Headers('Content-Language') lang: string,
    @Body() body: LogoutDto,
    @Res() res: Response,
  ) {
    return await this.usersService.logout(req, lang, body, res);
  }
  /*------------------------------------------------------------------------------------*/

  /************************************GET PROFILE***************************************/
  @Get('get_profile')
  @ApiOperation({ summary: 'Get My Profile' })
  @UseGuards(UserGuard)
  async getProfile(@Req() req: Request, @Res() res: Response) {
    return await this.usersService.getProfile(req, res);
  }
  /*------------------------------------------------------------------------------------*/

  /***********************************GET MY NOTIFICATIONS*******************************/
  @Get('get_all_notifications')
  @ApiOperation({ summary: 'Get My Notifications' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiQuery({ name: 'page', required: true, default: 1 })
  @ApiQuery({ name: 'limit', required: true, default: 10 })
  @UseGuards(UserGuard)
  async getMyNotifications(
    @Req() req: Request,
    @Headers('Content-Language') lang: string,
    @Query('page') page: number,
    @Query('limit') limit: number,
    @Res() res: Response,
  ) {
    return await this.usersService.getMyNotifications(
      req,
      lang,
      page,
      limit,
      res,
    );
  }
  /*------------------------------------------------------------------------------------*/

  /*********************************UPLOAD SHIPMENT DOCUMENT*****************************/
  @Post('upload_shipment_document/:shipment_id')
  @ApiOperation({ summary: 'Upload Shipment Document' })
  @ApiParam({ name: 'shipment_id' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @UseGuards(UserGuard)
  @UseInterceptors(
    FileInterceptor('shipment_document', {
      storage: diskStorage({
        destination: './uploads',
        filename: editFileName,
      }),
      fileFilter: mediaFileFilter,
      limits: { fileSize: 20 * 1024 * 1024 },
    }),
  )
  async uploadShipmentDocument(
    @Req() req: Request,
    @Headers('Content-Language') lang: string,
    @Param('shipment_id') shipment_id: string,
    @UploadedFile() file: Express.Multer.File,
    @Res() res: Response,
  ) {
    return await this.usersService.uploadShipmentDocument(
      req,
      lang,
      shipment_id,
      file,
      res,
    );
  }
  /*------------------------------------------------------------------------------------*/

  /*********************************DELETE MY INQUIRY************************************/
  @Delete('delete_my_inquiry/:inquiry_id')
  @ApiOperation({ summary: 'Delete My Inquiry' })
  @ApiParam({ name: 'inquiry_id' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @UseGuards(UserGuard)
  async deleteMyInquiry(
    @Req() req: Request,
    @Headers('Content-Language') lang: string,
    @Param('inquiry_id') inquiry_id: string,
    @Res() res: Response,
  ) {
    return await this.usersService.deleteMyInquiry(req, lang, inquiry_id, res);
  }
  /*------------------------------------------------------------------------------------*/

  /*********************************CHANGE MY LANGUAGE***********************************/
  @Post('change_my_language')
  @ApiOperation({ summary: 'Change My Default Language' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @UseGuards(UserGuard)
  async changeMyLanguage(
    @Req() req: Request,
    @Headers('Content-Language') lang: string,
    @Res() res: Response,
  ) {
    return await this.usersService.changeMyLanguage(req, lang, res);
  }
  /*------------------------------------------------------------------------------------*/

  /*********************************GET SINGLE SHIPMENT**********************************/
  @Get('get_shipment/:shipment_id')
  @ApiOperation({ summary: 'Get Single Shipment' })
  @ApiParam({ name: 'shipment_id' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @UseGuards(UserGuard)
  async getSingleShipment(
    @Req() req: Request,
    @Param('shipment_id') shipment_id: string,
    @Headers('Content-Language') lang: string,
    @Res() res: Response,
  ) {
    return await this.usersService.getSingleShipmentNew(
      req,
      shipment_id,
      lang,
      res,
    );
  }
  /*------------------------------------------------------------------------------------*/

  /*********************************GET SINGLE INQUIRY***********************************/
  @Get('get_inquiry/:inquiry_id')
  @ApiOperation({ summary: 'Get Single Inquiry' })
  @ApiParam({ name: 'inquiry_id' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @UseGuards(UserGuard)
  async getSingleInquiry(
    @Req() req: Request,
    @Param('inquiry_id') inquiry_id: string,
    @Headers('Content-Language') lang: string,
    @Res() res: Response,
  ) {
    return await this.usersService.getSingleInquiry(req, inquiry_id, lang, res);
  }
  /*------------------------------------------------------------------------------------*/

  /*********************************DELETE MY ACCOUNT************************************/
  @Post('delete_my_account')
  @ApiOperation({ summary: 'Delete My Account' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @UseGuards(UserGuard)
  async deleteMyAccount(
    @Req() req: Request,
    @Headers('Content-Language') lang: string,
    @Res() res: Response,
  ) {
    return await this.usersService.deleteMyAccount(req, lang, res);
  }
  /*------------------------------------------------------------------------------------*/
}
