import {
  Body,
  Controller,
  Delete,
  Get,
  Headers,
  Param,
  ParseBoolPipe,
  Patch,
  Post,
  Put,
  Query,
  Req,
  Res,
  UploadedFile,
  UploadedFiles,
  UseGuards,
  UseInterceptors,
} from '@nestjs/common';
import { AdminService } from './admin.service';
import { Request, Response } from 'express';
import { AdminLoginDto } from './dto/login.dto';
import { AdminGuard } from './guards/admin.auth.guard';
import { UserGuard } from 'src/users/guards/user.auth.guard';
import { CreateShipmentDto } from './dto/create-shipment.dto';
import { SHIPMENT_TYPE, USER_ROLE } from 'src/utils/constants';
import {
  AnyFilesInterceptor,
  FileFieldsInterceptor,
  FileInterceptor,
} from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { editFileName, mediaFileFilter } from 'src/utils/file.upload.helper';
import { AddStatusDto } from './dto/add-status.dto';
import { UpdateShipmentDto } from './dto/update-shipment.dto';
import { VerifyAdminOtpDto } from './dto/verify-otp.dto';
import { ChangePasswordDto } from 'src/users/dto/change-password.dto';
import { ReplyInquiryDto } from 'src/users/dto/reply-inquiry.dto';
import { CreateShipmentModeDto } from './dto/create-shipment-mode.dto';
import { DeleteUserDto } from './dto/delete-user.dto';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateSingleUserDto } from './dto/update-single-user.dto';
import { AssignRoleDto } from './dto/assign-role.dto';
import {
  ApiBearerAuth,
  ApiExcludeEndpoint,
  ApiHeader,
  ApiOperation,
  ApiParam,
  ApiQuery,
} from '@nestjs/swagger';
import { AddMultiStatusDto } from './dto/add-multi-status.dto';
import { UserRegisterDto } from './dto/user.register.dto';
import { MongoIdPipe } from 'src/utils/validateMongoId';
import { CreateEstimateDto, CreateQuotationDto } from './dto/quotation.dto';
@ApiBearerAuth('access-token')
@Controller('admin')
export class AdminController {
  constructor(private readonly adminService: AdminService) {}

  /*************************************ADMIN LOGIN**************************************/
  @Post('login')
  @ApiOperation({ summary: 'Admin Login' })
  @ApiHeader({ name: 'Content-Language', required: false })
  async adminLogin(
    @Headers('Content-Language') lang: string,
    @Body() body: AdminLoginDto,
    @Res() res: Response,
  ) {
    console.log('running login apis');
    return await this.adminService.adminLogin(lang, body, res);
  }
  /*------------------------------------------------------------------------------------*/

  /*************************************DASHBOARD****************************************/
  @Get('dashboard')
  @ApiOperation({ summary: 'Dashboard' })
  @ApiQuery({ name: 'report', required: false })
  @UseGuards(AdminGuard)
  async dashboard(@Query('report') report: string, @Res() res: Response) {
    return await this.adminService.dashboard(report, res);
  }
  /*------------------------------------------------------------------------------------*/

  /*************************************FORGOT PASSWORD**********************************/
  @Post('forgot_password')
  @ApiOperation({ summary: 'Forgot Password' })
  @ApiHeader({ name: 'Content-Language', required: false })
  async forgotPassword(
    @Headers('Content-Language') lang: string,
    @Res() res: Response,
  ) {
    return await this.adminService.forgotPassword(lang, 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: VerifyAdminOtpDto,
    @Res() res: Response,
  ) {
    return await this.adminService.verifyOtp(lang, body, res);
  }
  /*------------------------------------------------------------------------------------*/
  @Post('verify_shipment/:id')
  @ApiOperation({ summary: 'Verify Shipment' })
  @ApiHeader({ name: 'Content-Language', required: false })
  // @UseGuards(AdminGuard)
  // @UseGuards(UserGuard)
  async verifyShipment(
    @Param('id') shipmentId: string,
    @Headers('Content-Language') lang: string,
    @Body('code') code: string,
    @Res() res: Response,
  ) {
    return await this.adminService.verifyShipment(shipmentId, lang, code, res);
  }

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

  /********************************GET ALL SHIPMENTS*************************************/
  @Get('get_all_shipments')
  @ApiOperation({ summary: 'Get All Shipments' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiQuery({ name: 'page', required: true, default: 1 })
  @ApiQuery({ name: 'limit', required: true, default: 10 })
  @ApiQuery({ name: 'search', required: false, default: '' })
  @ApiQuery({ name: 'modeId', required: false, default: '' })
  @ApiQuery({ name: 'userId', required: false, default: '' })
  @ApiQuery({ name: 'status', required: false, default: '' })
  @ApiQuery({ name: 'shipment_type', enum: SHIPMENT_TYPE, required: false })
  @UseGuards(AdminGuard)
  async getAllShipments(
    @Headers('Content-Language') lang: string,
    @Query('modeId') modeId: string,
    @Query('userId') userId: string,
    @Query('page') page: number,
    @Query('limit') limit: number,
    @Query('search') search: string,
    @Query('status') status: string,
    @Query('shipment_type') shipment_type: SHIPMENT_TYPE,
    @Res() res: Response,
  ) {
    return await this.adminService.getAllShipments(
      res,
      lang,
      page,
      limit,
      search,
      status,
      modeId,
      shipment_type,
      userId,
    );
  }
  /*------------------------------------------------------------------------------------*/

  // @@ get all count
  @UseGuards(AdminGuard)
  @Get('get_total_count')
  @ApiOperation({ summary: 'Get All Shipments' })
  @ApiHeader({ name: 'Content-Language', required: false })
  async getTotalCount() {
    return await this.adminService.getTotalCount();
  }

  // @@ Get all count of active/complete

  /********************************CREATE SHIPMENT***************************************/
  @Post('create_shipment')
  @UseGuards(AdminGuard)
  @UseInterceptors(
    AnyFilesInterceptor({
      storage: diskStorage({
        destination: './uploads',
        filename: editFileName,
      }),
      fileFilter: mediaFileFilter,
      limits: {
        fileSize: 50 * 1024 * 1024,
      },
    }),
  )
  async createShipment(
    @Req() req: Request,
    @Headers('Content-Language') lang: string,
    @Query('notify', ParseBoolPipe) notify: boolean,
    @Body() body: CreateShipmentDto,
    @UploadedFiles() files: Express.Multer.File[],
    @Res() res: Response,
  ) {

    if (body?.commodity) {
      body.commodity = JSON.parse(body.commodity);
    }

    if (body?.employees) {
      body.employees = JSON.parse(body.employees);
    }

    const staticFiles = {
      shipment_document: [],
      shipment_invoice: [],
      receiving_slip: [],
    };

    files.forEach((file) => {

      // Static fields
      if (
        file.fieldname === 'shipment_document' ||
        file.fieldname === 'shipment_invoice' ||
        file.fieldname === 'receiving_slip'
      ) {
        staticFiles[file.fieldname].push(file);
        return;
      }

      const match = file.fieldname.match(
        /commodity\[(\d+)\]\[commodity_description\]\[(\d+)\]\[(.*?)\]/
      );

      if (match) {
        const commodityIndex = match[1];
        const descriptionIndex = match[2];
        const imageKey = match[3];

        if (
          body.commodity?.[commodityIndex]
            ?.commodity_description?.[descriptionIndex]
        ) {
          body.commodity[commodityIndex]
            .commodity_description[descriptionIndex][imageKey] = `${req.protocol}://${req.headers.host}/${file.path}`;
        }
      }

    });

    return await this.adminService.createShipment(
      req,
      lang,
      notify,
      body,
      staticFiles,
      res,
    );
  }


  // @Post('create_shipment')
  // @ApiOperation({ summary: 'Create Shipment' })
  // @ApiHeader({ name: 'Content-Language', required: false })
  // @ApiQuery({ name: 'notify', type: Boolean, required: true, default: false })
  // @UseGuards(AdminGuard)
  // @UseInterceptors(
  //   FileFieldsInterceptor(
  //     [
  //       { name: 'shipment_document', maxCount: 10 },
  //       { name: 'shipment_invoice', maxCount: 10 },
  //       { name: 'receiving_slip', maxCount: 10 },
  //     ],
  //     {
  //       storage: diskStorage({
  //         destination: './uploads',
  //         filename: editFileName,
  //       }),
  //       fileFilter: mediaFileFilter,
  //       limits: {
  //         fileSize: 50 * 1024 * 1024,
  //       },
  //     },
  //   ),
  // )
  // async createShipment(
  //   @Req() req: Request,
  //   @Headers('Content-Language') lang: string,
  //   @Query('notify', ParseBoolPipe) notify: boolean,
  //   @Body() body: CreateShipmentDto,
  //   @UploadedFiles()
  //   files: {
  //     shipment_document?: Express.Multer.File[];
  //     shipment_invoice?: Express.Multer.File[];
  //     receiving_slip?: Express.Multer.File[];
  //   },
  //   @Res() res: Response,
  // ) {
  //   if (body?.commodity) {
  //     body.commodity = JSON.parse(body.commodity);
  //   }
  //   if (body?.employees) {
  //     body.employees = JSON.parse(body.employees);
  //   }
  //   return await this.adminService.createShipment(
  //     req,
  //     lang,
  //     notify,
  //     body,
  //     files,
  //     res,
  //   );
  // }
  /*------------------------------------------------------------------------------------*/

  /********************************UPDATE SHIPMENT***************************************/

  @Post('update_shipment/:shipment_id')
@UseGuards(AdminGuard)
@UseInterceptors(
  AnyFilesInterceptor({
    storage: diskStorage({
      destination: './uploads',
      filename: editFileName,
    }),
    fileFilter: mediaFileFilter,
    limits: {
      fileSize: 50 * 1024 * 1024,
    },
  }),
)
async updateShipment(
  @Req() req: Request,
  @Param('shipment_id') shipment_id: string,
  @Query('notify', ParseBoolPipe) notify: boolean,
  @Headers('Content-Language') lang: string,
  @Body() body: UpdateShipmentDto,
  @UploadedFiles() files: Express.Multer.File[],
  @Res() res: Response,
) {
  if (body?.commodity) {
    body.commodity = JSON.parse(body.commodity);
  }

  if (body?.employees) {
    body.employees = JSON.parse(body.employees);
  }

  const staticFiles = {
    shipment_document: [],
    shipment_invoice: [],
    receiving_slip: [],
  };

  files.forEach((file) => {

    if (
      file.fieldname === 'shipment_document' ||
      file.fieldname === 'shipment_invoice' ||
      file.fieldname === 'receiving_slip'
    ) {
      staticFiles[file.fieldname].push(file);
      return;
    }

    const match = file.fieldname.match(
      /commodity\[(\d+)\]\[commodity_description\]\[(\d+)\]\[(.*?)\]/
    );

    if (match) {
      const commodityIndex = match[1];
      const descriptionIndex = match[2];
      const imageKey = match[3];

      if (
        body.commodity?.[commodityIndex]
          ?.commodity_description?.[descriptionIndex]
      ) {
        body.commodity[commodityIndex]
          .commodity_description[descriptionIndex][imageKey] =
          `${req.protocol}://${req.headers.host}/${file.path}`;
      }
    }
  });

  return await this.adminService.updateShipment(
    req,
    shipment_id,
    notify,
    lang,
    body,
    staticFiles,
    res,
  );
}



  // @Post('update_shipment/:shipment_id')
  // @ApiOperation({ summary: 'Update Shipment' })
  // @ApiHeader({ name: 'Content-Language', required: false })
  // @ApiQuery({ name: 'notify', type: Boolean, required: true, default: false })
  // @UseGuards(AdminGuard)
  // @UseInterceptors(
  //   FileFieldsInterceptor(
  //     [
  //       { name: 'shipment_document', maxCount: 10 },
  //       { name: 'shipment_invoice', maxCount: 10 },
  //       { name: 'receiving_slip', maxCount: 10 },
  //     ],
  //     {
  //       storage: diskStorage({
  //         destination: './uploads',
  //         filename: editFileName,
  //       }),
  //       fileFilter: mediaFileFilter,
  //       limits: {
  //         fileSize: 50 * 1024 * 1024,
  //       },
  //     },
  //   ),
  // )
  // async updateShipment(
  //   @Req() req: Request,
  //   @Param('shipment_id') shipment_id: string,
  //   @Query('notify', ParseBoolPipe) notify: boolean,
  //   @Headers('Content-Language') lang: string,
  //   @Body() body: UpdateShipmentDto,
  //   @UploadedFiles()
  //   files: {
  //     shipment_document?: Express.Multer.File[];
  //     shipment_invoice?: Express.Multer.File[];
  //     receiving_slip?: Express.Multer.File[];
  //   },
  //   @Res() res: Response,
  // ) {
  //   if (body?.commodity) {
  //     body.commodity = JSON.parse(body?.commodity);
  //   }
  //   if (body?.employees) {
  //     body.employees = JSON.parse(body?.employees);
  //   }
  //   return await this.adminService.updateShipment(
  //     req,
  //     shipment_id,
  //     notify,
  //     lang,
  //     body,
  //     files,
  //     res,
  //   );
  // }
  /*------------------------------------------------------------------------------------*/

  /********************************GET ALL USERS*****************************************/
  @Get('get_all_users')
  @ApiOperation({ summary: 'Get All Users' })
  @ApiQuery({ name: 'page', required: true, default: 1 })
  @ApiQuery({ name: 'limit', required: true, default: 10 })
  @ApiQuery({ name: 'search', required: false, default: '' })
  @UseGuards(AdminGuard)
  async getAllUsers(
    @Query('page') page: number,
    @Query('limit') limit: number,
    @Query('search') search: string,
    @Res() res: Response,
  ) {
    return await this.adminService.getAllUsers(page, limit, search, res);
  }
  /*------------------------------------------------------------------------------------*/

  /********************************GET ALL SHIPMENT MODES********************************/
  @Get('get_all_shipment_modes')
  @ApiOperation({ summary: 'Get All Shipment Modes' })
  @ApiQuery({ name: 'page', required: true, default: 1 })
  @ApiQuery({ name: 'limit', required: true, default: 10 })
  @ApiQuery({ name: 'search', required: false, default: '' })
  @UseGuards(AdminGuard)
  async getAllShipmentModes(
    @Query('page') page: number,
    @Query('limit') limit: number,
    @Query('search') search: string,
    @Res() res: Response,
  ) {
    return await this.adminService.getAllShipmentModes(
      page,
      limit,
      search,
      res,
    );
  }
  /*------------------------------------------------------------------------------------*/

  /************************************TRANSLATE*****************************************/
  @Get('translate/:translate_to')
  @ApiOperation({ summary: 'Translate data in english or arabic' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiParam({ name: 'translate_to', required: true })
  @ApiQuery({ name: 'keyword', required: false, default: '' })
  @UseGuards(AdminGuard)
  async translateKeyword(
    @Headers('Content-Language') lang: string,
    @Param('translate_to') translate_to: string,
    @Query('keyword') keyword: string,
    @Res() res: Response,
  ) {
    return await this.adminService.translateKeyword(
      lang,
      translate_to,
      keyword,
      res,
    );
  }
  /*------------------------------------------------------------------------------------*/

  /********************************BLOCK UNBLOCK USER************************************/
  @Post('change_user_status/:user_id')
  @ApiOperation({ summary: 'Block or unblock user' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiParam({ name: 'user_id' })
  @UseGuards(AdminGuard)
  async changeUserStatus(
    @Headers('Content-Language') lang: string,
    @Param('user_id') user_id: string,
    @Res() res: Response,
  ) {
    return await this.adminService.changeUserStatus(lang, user_id, res);
  }
  /*------------------------------------------------------------------------------------*/

  /********************************DELETE SHIPMENT***************************************/
  @Delete('delete_shipment/:shipment_id')
  @ApiOperation({ summary: 'Delete Shipment' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiParam({ name: 'shipment_id' })
  @UseGuards(AdminGuard)
  async deleteShipment(
    @Headers('Content-Language') lang: string,
    @Param('shipment_id') shipment_id: string,
    @Res() res: Response,
  ) {
    return await this.adminService.deleteShipment(lang, shipment_id, res);
  }
  /*------------------------------------------------------------------------------------*/

  /********************************DELETE SHIPMENT MODE**********************************/
  @Delete('delete_shipment_mode/:shipment_mode_id')
  @ApiOperation({ summary: 'Delete Shipment Mode' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiParam({ name: 'shipment_mode_id' })
  @UseGuards(AdminGuard)
  async deleteShipmentMode(
    @Headers('Content-Language') lang: string,
    @Param('shipment_mode_id') shipment_mode_id: string,
    @Res() res: Response,
  ) {
    return await this.adminService.deleteShipmentMode(
      lang,
      shipment_mode_id,
      res,
    );
  }
  /*------------------------------------------------------------------------------------*/

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

  /*************************UPLOAD SHIPMENT DOCUMENT*************************************/
  @Post('upload_shipment_document/:shipment_id')
  @ApiOperation({ summary: 'Upload Shipment Document' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiParam({ name: 'shipment_id' })
  @ApiQuery({ name: 'notify', required: true, default: false, type: Boolean })
  @UseGuards(AdminGuard)
  @UseInterceptors(
    FileFieldsInterceptor([{ name: 'shipment_document', maxCount: 10 }], {
      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,
    @Query('notify', ParseBoolPipe) notify: boolean,
    @UploadedFiles() files: { shipment_document?: Express.Multer.File[] },
    @Res() res: Response,
  ) {
    return await this.adminService.uploadShipmentDocument(
      req,
      lang,
      shipment_id,
      notify,
      files,
      res,
    );
  }
  /*------------------------------------------------------------------------------------*/

  /*************************UPLOAD RECEVING SLIP*************************************/
  @Post('upload_receiving_slip/:shipment_id')
  @ApiOperation({ summary: 'Upload receving slip' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiParam({ name: 'shipment_id' })
  @ApiQuery({ name: 'notify', required: true, default: false, type: Boolean })
  @UseGuards(AdminGuard)
  @UseInterceptors(
    FileFieldsInterceptor([{ name: 'receiving_slip', maxCount: 10 }], {
      storage: diskStorage({
        destination: './uploads',
        filename: editFileName,
      }),
      fileFilter: mediaFileFilter,
      limits: {
        fileSize: 20 * 1024 * 1024,
      },
    }),
  )
  async uploadReceivingSlip(
    @Req() req: Request,
    @Headers('Content-Language') lang: string,
    @Param('shipment_id') shipment_id: string,
    @Query('notify', ParseBoolPipe) notify: boolean,
    @UploadedFiles() files: { receiving_slip?: Express.Multer.File[] },
    @Res() res: Response,
  ) {
    return await this.adminService.uploadReceivingSlip(
      req,
      lang,
      shipment_id,
      notify,
      files,
      res,
    );
  }
  /*------------------------------------------------------------------------------------*/
  /*************************UPLOAD SHIPMENT INVOICE**************************************/
  @Post('upload_shipment_invoice/:shipment_id')
  @ApiOperation({ summary: 'Upload Shipment Invoice' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiParam({ name: 'shipment_id' })
  @ApiQuery({ name: 'notify', required: true, type: Boolean, default: false })
  @UseGuards(AdminGuard)
  @UseInterceptors(
    FileFieldsInterceptor([{ name: 'shipment_invoice', maxCount: 10 }], {
      storage: diskStorage({
        destination: './uploads',
        filename: editFileName,
      }),
      fileFilter: mediaFileFilter,
      limits: {
        fileSize: 20 * 1024 * 1024,
      },
    }),
  )
  async uploadShipmentInvoice(
    @Req() req: Request,
    @Headers('Content-Language') lang: string,
    @Param('shipment_id') shipment_id: string,
    @Query('notify', ParseBoolPipe) notify: boolean,
    @UploadedFiles() files: { shipment_invoice?: Express.Multer.File[] },
    @Res() res: Response,
  ) {
    return await this.adminService.uploadShipmentInvoice(
      req,
      lang,
      shipment_id,
      notify,
      files,
      res,
    );
  }
  /*------------------------------------------------------------------------------------*/

  /********************************ADD SHIPMENT STATUS***********************************/
  @Post('add_shipment_status/:shipment_id')
  @ApiOperation({ summary: 'Add Shipment Status' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiParam({ name: 'shipment_id' })
  @ApiQuery({ name: 'notify', required: true, type: Boolean, default: false })
  @UseGuards(AdminGuard)
  async addShipmentStatus(
    @Headers('Content-Language') lang: string,
    @Param('shipment_id') shipment_id: string,
    @Query('notify', ParseBoolPipe) notify: boolean,
    @Body() body: AddStatusDto,
    @Res() res: Response,
  ) {
    return await this.adminService.addShipmentStatus(
      lang,
      shipment_id,
      notify,
      body,
      res,
    );
  }
  /*------------------------------------------------------------------------------------*/

  /********************************ADD MULTI SHIPMENT STATUS***********************************/
  @Post('add_multi_shipment_status')
  @ApiOperation({ summary: 'Add Multi Shipment Status' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiQuery({ name: 'notify', required: true, type: Boolean, default: false })
  @UseGuards(AdminGuard)
  async addMultipleShipmentsStatus(
    @Headers('Content-Language') lang: string,
    @Query('notify', ParseBoolPipe) notify: boolean,
    @Body() body: AddMultiStatusDto,
    @Res() res: Response,
  ) {
    return await this.adminService.addMultiShipmentStatus(
      lang,
      notify,
      body,
      res,
    );
  }

  /*------------------------------------------------------------------------------------*/

  /********************************UPDATE SHIPMENT STATUS********************************/
  @Post('update_shipment_status/:status_id')
  @ApiOperation({ summary: 'Update Shipment Status' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiParam({ name: 'status_id' })
  @UseGuards(AdminGuard)
  async updateShipmentStatus(
    @Headers('Content-Language') lang: string,
    @Param('status_id') status_id: string,
    @Body() body: AddStatusDto,
    @Res() res: Response,
  ) {
    return await this.adminService.updateShipmentStatus(
      lang,
      status_id,
      body,
      res,
    );
  }
  /*------------------------------------------------------------------------------------*/

  /*************************DELETE SINGLE SHIPMENT DOCUMENT******************************/
  @Delete('delete_shipment_document/:doc_id')
  @ApiOperation({ summary: 'Delete Shipment Document' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiParam({ name: 'doc_id' })
  @UseGuards(AdminGuard)
  async deleteShipmentDocument(
    @Headers('Content-Language') lang: string,
    @Param('doc_id') doc_id: string,
    @Res() res: Response,
  ) {
    return await this.adminService.deleteShipmentDocument(lang, doc_id, res);
  }
  /*------------------------------------------------------------------------------------*/

  /*************************DELETE SINGLE SHIPMENT DOCUMENT******************************/
  @Delete('delete_receiving_slip/:doc_id')
  @ApiOperation({ summary: 'Delete receiv slip' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiParam({ name: 'doc_id' })
  @UseGuards(AdminGuard)
  async deleteReceivingSlip(
    @Headers('Content-Language') lang: string,
    @Param('doc_id') doc_id: string,
    @Res() res: Response,
  ) {
    return await this.adminService.deleteReceivingSlip(lang, doc_id, res);
  }
  /*------------------------------------------------------------------------------------*/

  /************************************GET ALL INQUIRIES*********************************/
  @Get('get_all_inquiry')
  @ApiOperation({ summary: 'Get All Inquiries' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiQuery({ name: 'status', required: false })
  @ApiQuery({ name: 'page', required: true, default: 1 })
  @ApiQuery({ name: 'limit', required: true, default: 10 })
  @ApiQuery({ name: 'search', required: false, default: '' })
  @UseGuards(AdminGuard)
  async getAllInquiry(
    @Headers('Content-Language') lang: string,
    @Query('status') status: string,
    @Query('page') page: number,
    @Query('limit') limit: number,
    @Query('search') search: string,
    @Res() res: Response,
  ) {
    return await this.adminService.getAllInquiry(
      lang,
      status,
      page,
      limit,
      search,
      res,
    );
  }
  /*------------------------------------------------------------------------------------*/

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

  /************************************RESOLVE INQUIRY***********************************/
  @Post('resolve_query/:inquiry_id')
  @ApiOperation({ summary: 'Resolve Inquiry' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiParam({ name: 'inquiry_id' })
  @UseGuards(AdminGuard)
  async resolveQuery(
    @Headers('Content-Language') lang: string,
    @Param('inquiry_id') inquiry_id: string,
    @Res() res: Response,
  ) {
    return await this.adminService.resolveInquiry(lang, inquiry_id, res);
  }
  /*------------------------------------------------------------------------------------*/

  /************************************DELETE INQUIRY************************************/
  @Delete('delete_query/:inquiry_id')
  @ApiOperation({ summary: 'Delete Inquiry' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiParam({ name: 'inquiry_id' })
  @UseGuards(AdminGuard)
  async deleteQuery(
    @Headers('Content-Language') lang: string,
    @Param('inquiry_id') inquiry_id: string,
    @Res() res: Response,
  ) {
    return await this.adminService.deleteInquiry(lang, inquiry_id, res);
  }
  /*------------------------------------------------------------------------------------*/

  /************************************GET USERS OPTIONS*********************************/
  @Get('get_users_options')
  @ApiOperation({ summary: 'Get User Options' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiQuery({ name: 'type', required: true })
  @UseGuards(AdminGuard)
  async getUsersOptions(
    @Headers('Content-Language') lang: string,
    @Query('type') type: string,
    @Res() res: Response,
  ) {
    return await this.adminService.getUsersOptions(lang, type, res);
  }
  /*------------------------------------------------------------------------------------*/

  /************************************GET SINGLE USER***********************************/
  @Get('get_single_user/:user_id')
  @ApiOperation({ summary: 'Get Single User' })
  @ApiParam({ name: 'user_id' })
  @UseGuards(AdminGuard)
  async getSingleUser(@Param('user_id') user_id: string, @Res() res: Response) {
    return await this.adminService.getSingleUser(user_id, res);
  }
  /*------------------------------------------------------------------------------------*/

  /************************************REPLY INQUIRY*************************************/
  @Post('reply_inquiry/:inquiry_id')
  @ApiOperation({ summary: 'Reply Inquiry' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiQuery({ name: 'notify', required: true, default: false })
  @UseGuards(AdminGuard)
  async replyInquiry(
    @Param('inquiry_id') inquiry_id: string,
    @Query('notify', ParseBoolPipe) notify: boolean,
    @Headers('Content-Language') lang: string,
    @Body() body: ReplyInquiryDto,
    @Res() res: Response,
  ) {
    return await this.adminService.replyInquiry(
      inquiry_id,
      notify,
      lang,
      body,
      res,
    );
  }
  /*------------------------------------------------------------------------------------*/

  /*****************************ADD QUOTATION DOCUMENT***********************************/
  @Post('upload_quotation/:inquiry_id')
  @ApiOperation({ summary: 'Upload quotation document' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiParam({ name: 'inquiry_id' })
  @ApiQuery({ name: 'notify', required: true, type: Boolean, default: false })
  @UseGuards(AdminGuard)
  @UseInterceptors(
    FileInterceptor('quotation', {
      storage: diskStorage({
        destination: './uploads',
        filename: editFileName,
      }),
      fileFilter: mediaFileFilter,
      limits: {
        fileSize: 20 * 1024 * 1024,
      },
    }),
  )
  async addQuotationDocument(
    @Req() req: Request,
    @Param('inquiry_id') inquiry_id: string,
    @Query('notify', ParseBoolPipe) notify: boolean,
    @Headers('Content-Language') lang: string,
    @UploadedFile() file: Express.Multer.File,
    @Res() res: Response,
  ) {
    return await this.adminService.addQuotationDocument(
      req,
      inquiry_id,
      notify,
      lang,
      file,
      res,
    );
  }
  /*------------------------------------------------------------------------------------*/

  /*****************************COMPLETE SHIPMENT****************************************/
  @Post('complete_shipment/:shipment_id')
  @ApiOperation({ summary: 'Complete Shipment' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiParam({ name: 'shipment_id' })
  @UseGuards(AdminGuard)
  async completeShipment(
    @Param('shipment_id') shipment_id: string,
    @Headers('Content-Language') lang: string,
    @Res() res: Response,
  ) {
    return await this.adminService.completeShipment(shipment_id, lang, res);
  }
  /*------------------------------------------------------------------------------------*/

  @Post('complete_multiple_shipments')
  @ApiOperation({ summary: 'Complete Multiple Shipments' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @UseGuards(AdminGuard)
  async completeMultipleShipments(
    @Body('shipment_ids') shipment_ids: string[],
    @Headers('Content-Language') lang: string,
    @Res() res: Response,
  ) {
    return await this.adminService.completeMultipleShipments(
      shipment_ids,
      lang,
      res,
    );
  }

  /*****************************CREATE SHIPMENT MODE*************************************/
  @Post('create_shipment_mode')
  @ApiOperation({ summary: 'Create Shipment Mode' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @UseGuards(AdminGuard)
  async createShipmentMode(
    @Headers('Content-Language') lang: string,
    @Body() body: CreateShipmentModeDto,
    @Res() res: Response,
  ) {
    return await this.adminService.createShipmentMode(lang, body, res);
  }
  /*------------------------------------------------------------------------------------*/

  /********************************DELETE USER*******************************************/
  @Post('delete_user_account')
  @ApiOperation({ summary: 'Delete User Account' })
  @ApiHeader({ name: 'Content-Language', required: false })
  async deleteUser(
    @Body() body: DeleteUserDto,
    @Headers('Content-Language') lang: string,
    @Res() res: Response,
  ) {
    return await this.adminService.deleteUser(body, lang, res);
  }
  /*------------------------------------------------------------------------------------*/

  /*****************************SEND SHIPMENT NOTIFICATION*******************************/
  @Post('send_shipment_notification/:shipment_id')
  @ApiOperation({ summary: 'Send Shipment Notifications' })
  @ApiParam({ name: 'shipment_id' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiQuery({ name: 'type', required: true })
  @UseGuards(AdminGuard)
  async sendShipmentNotifications(
    @Param('shipment_id') shipment_id: string,
    @Headers('Content-Language') lang: string,
    @Query('type') type: string,
    @Res() res: Response,
  ) {
    return await this.adminService.sendShipmentNotifications(
      shipment_id,
      lang,
      type,
      res,
    );
  }
  /*------------------------------------------------------------------------------------*/

  /*****************************SEND INQUIRY NOTIFICATION********************************/
  @Post('send_inquiry_notification/:inquiry_id')
  @ApiOperation({ summary: 'Send Inquiry Notifications' })
  @ApiParam({ name: 'inquiry_id' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiQuery({ name: 'type', required: true })
  @UseGuards(AdminGuard)
  async sendInquiryNotifications(
    @Param('inquiry_id') inquiry_id: string,
    @Headers('Content-Language') lang: string,
    @Query('type') type: string,
    @Res() res: Response,
  ) {
    return await this.adminService.sendInquiryNotifications(
      inquiry_id,
      lang,
      type,
      res,
    );
  }
  /*------------------------------------------------------------------------------------*/

  /*********************************CREATE USER******************************************/
  @Post('create_user_account')
  @ApiExcludeEndpoint()
  @UseGuards(AdminGuard)
  async createUser(
    @Body() body: CreateUserDto,
    @Headers('Content-Language') lang: string,
    @Res() res: Response,
  ) {
    return await this.adminService.createUser(body, lang, res);
  }
  /*------------------------------------------------------------------------------------*/

  /*********************************GET USER DETAILS*************************************/
  @Post('get_user_details_all/:user_id')
  @ApiExcludeEndpoint()
  @UseGuards(AdminGuard)
  async getUserDetails(
    @Param('user_id') user_id: string,
    @Res() res: Response,
  ) {
    return await this.adminService.getUserDetails(user_id, res);
  }
  /*------------------------------------------------------------------------------------*/

  /*********************************HARD DELETE USER*************************************/
  @Post('hard_delete_user/:user_id')
  @ApiExcludeEndpoint()
  @UseGuards(AdminGuard)
  async hardDeleteUser(
    @Param('user_id') user_id: string,
    @Res() res: Response,
  ) {
    return await this.adminService.hardDeleteUser(user_id, res);
  }
  /*------------------------------------------------------------------------------------*/

  /*********************************UPDATE SINGLE USER***********************************/
  @Post('update_single_user/:user_id')
  @ApiExcludeEndpoint()
  @UseGuards(AdminGuard)
  async updateSingleUser(
    @Param('user_id') user_id: string,
    @Body() body: UpdateSingleUserDto,
    @Res() res: Response,
  ) {
    return await this.adminService.updateSingleUser(user_id, body, res);
  }
  /*------------------------------------------------------------------------------------*/

  /*********************************GET DUMMY USERS**************************************/
  @Get('get_dummy_users')
  @ApiExcludeEndpoint()
  @UseGuards(AdminGuard)
  async getDummyUsers(
    @Query('page') page: number,
    @Query('limit') limit: number,
    @Res() res: Response,
  ) {
    return await this.adminService.getDummyUsers(page, limit, res);
  }
  /*------------------------------------------------------------------------------------*/

  /*********************************ASSIGN ADMIN*****************************************/
  // @Post('assign_admin/:user_id')
  // @ApiOperation({ summary: 'Make User Subadmin' })
  // @ApiHeader({ name: 'Content-Language', required: false })
  // @ApiParam({ name: 'user_id' })
  // // @UseGuards(AdminGuard)
  // async assignAdmin(
  //   @Param('user_id') user_id: string,
  //   @Headers('Content-Language') lang: string,
  //  @Body() body: AssignRoleDto,
  //   @Res() res: Response,
  // ) {
  //   return await this.adminService.assignRole(res ,user_id, body.role, lang );
  // }

  @Post('assign_admin/:user_id')
  @ApiOperation({ summary: 'Make User Subadmin' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @ApiParam({ name: 'user_id' })
  @UseGuards(AdminGuard)
  async assignAdmin(
    @Param('user_id') user_id: string,
    @Headers('Content-Language') lang: string,
    @Res() res: Response,
  ) {
    return await this.adminService.assignAdmin(user_id, lang, res);
  }
  /*------------------------------------------------------------------------------------*/

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

  /******************************UNDO COMPLETE SHIPMENT**********************************/
  @Post('undo_complete_shipment/:shipment_id')
  @ApiExcludeEndpoint()
  @UseGuards(AdminGuard)
  async undoCompleteShipment(
    @Param('shipment_id') shipment_id: string,
    @Res() res: Response,
  ) {
    return await this.adminService.undoCompleteShipment(shipment_id, res);
  }
  /*------------------------------------------------------------------------------------*/

  /*********************************DELETE DEVICE****************************************/
  @Delete('delete_device/:single_device_id')
  @ApiExcludeEndpoint()
  @UseGuards(AdminGuard)
  async deleteDevices(
    @Param('single_device_id') single_device_id: string,
    @Res() res: Response,
  ) {
    return await this.adminService.deleteDevices(single_device_id, res);
  }
  /*------------------------------------------------------------------------------------*/

  /*********************************DELETE DEVICE****************************************/
  @Get('search_module')
  @ApiOperation({ summary: 'Global Search Module' })
  @ApiQuery({ name: 'page', required: true, default: 1 })
  @ApiQuery({ name: 'limit', required: true, default: 10 })
  @ApiQuery({ name: 'search', required: false, default: '' })
  @UseGuards(AdminGuard)
  async searchModules(
    @Query('page') page: number,
    @Query('limit') limit: number,
    @Query('search') search: string,
    @Res() res: Response,
  ) {
    return await this.adminService.searchModules(page, limit, search, res);
  }
  /*------------------------------------------------------------------------------------*/

  /*****************************GET SINGLE USER DATA*************************************/
  @Get('get_single_user_data/:user_id')
  @ApiOperation({ summary: 'Single User Data' })
  @ApiParam({ name: 'user_id' })
  @UseGuards(AdminGuard)
  async getSingleUserData(
    @Param('user_id') user_id: string,
    @Res() res: Response,
  ) {
    return await this.adminService.getSingleUserData(user_id, res);
  }
  /*------------------------------------------------------------------------------------*/

  /************************SEND NOTIFICATIONS TO ALL USERS*******************************/
  @Post('send_notification')
  @ApiOperation({ summary: 'Send Notification' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @UseGuards(AdminGuard)
  async sendNotificationToAllUsers(
    @Headers('Content-Language') lang: string,
    @Res() res: Response,
  ) {
    return await this.adminService.sendNotificationToAllUsers(lang, res);
  }
  /*------------------------------------------------------------------------------------*/

  // @@@ user register by admin

  @Post('register')
  @ApiOperation({ summary: 'Register' })
  @ApiHeader({ name: 'Content-Language', required: false })
  async Register(
    @Headers('Content-Language') lang: string,
    @Body() body: UserRegisterDto,
    @Res() res: Response,
  ) {
    return await this.adminService.Register(lang, body, res);
  }

  // get user total,active,past shipment count
  @Get('get_user_shipment_counts/:userId')
  @ApiOperation({ summary: 'Get User Shipment Counts' })
  @ApiParam({ name: 'userId' })
  @UseGuards(AdminGuard)
  async getUserShipmentCounts(
    @Param('userId') userId: string,
    @Res() res: Response,
  ) {
    return await this.adminService.getUserShipmentCounts(userId, res);
  }

  /************************Quotation*******************************/
  @Post('quotation')
  @ApiOperation({ summary: 'Quotation' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @UseGuards(AdminGuard)
  async createQuotation(
    @Headers('Content-Language') lang: string,
    @Res() res: Response,
    @Body() createQuotationDto:CreateQuotationDto
  ) {
    return await this.adminService.createQuotation(lang, createQuotationDto, res);
  }

  @Patch('quotation/:id')
  @ApiOperation({ summary: 'Quotation' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @UseGuards(AdminGuard)
  async updateQuotation(
    @Headers('Content-Language') lang: string,
    @Body() createQuotationDto:CreateQuotationDto,
    @Res() res: Response,
    @Param('id',MongoIdPipe) id: string,
  ) {
    return await this.adminService.updateQuotation(lang, createQuotationDto, res, id);
  }

  @Delete('quotation/:id')
  @ApiOperation({ summary: 'Quotation' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @UseGuards(AdminGuard)
  async deleteQuotation(
    @Headers('Content-Language') lang: string,
    @Res() res: Response,
    @Param('id', MongoIdPipe) id: string,
  ) {
    return await this.adminService.deleteQuotation(lang, res, id);
  }

  @Get("quotation")
  @ApiOperation({ summary: 'Quotation' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @UseGuards(AdminGuard)
  async getAllQuotation(
    @Headers('Content-Language') lang: string,
    @Res() res: Response,
    @Query("page") page:string,
    @Query("limit") limit:string,
    @Query("search") search:string,
    @Query("status") status:string,
  ){
    return await this.adminService.getAllQuotation(lang, res, Number(page), Number(limit), search,status);
  }

  @Get('quotation/:id')
  @ApiOperation({ summary: 'Quotation' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @UseGuards(AdminGuard)
  async getQuotation(
    @Headers('Content-Language') lang: string,
    @Res() res: Response,
    @Param('id', MongoIdPipe) id: string,
  ) {
    return await this.adminService.getQuotation(lang, res, id);
  }

  @Post("estimate")
  @ApiOperation({ summary: 'Estimate' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @UseGuards(AdminGuard)
  async createEstimate(
    @Headers('Content-Language') lang: string,
    @Res() res: Response,
    @Body() CreateEstimateDto:CreateEstimateDto
  ) {
    return await this.adminService.createEstimate(lang, CreateEstimateDto, res);
  }

  @Patch('estimate/:id')
  @ApiOperation({ summary: 'Quotation' })
  @ApiHeader({ name: 'Content-Language', required: false })
  @UseGuards(AdminGuard)
  async updateEstimate(
    @Headers('Content-Language') lang: string,
    @Body() CreateEstimateDto:CreateEstimateDto,
    @Res() res: Response,
    @Param('id',MongoIdPipe) id: string,
  ) {
    return await this.adminService.updateEstimate(lang, CreateEstimateDto, res, id);
  }
}
