import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  Patch,
  Post,
  Query,
  Req,
  UseGuards,
} from '@nestjs/common';
import { CylindersService } from './cylinders.service';
import { CreateCylinderDto } from './dto/create-cylinder.dto';
import { UpdateCylinderDto } from './dto/update-cylinder.dto';
import { AccountType } from '@prisma/client';
import { AccountTypesGuard } from '../../common/guards/accountTypes.guard';
import { AccountTypes } from '../../common/decorators/accountType.decorator';
import { JwtAuthGuard } from 'src/auth/guards/jwt-auth.guard';
import { Public } from 'src/common/decorators/public.decorator';
import { AssignToClientDto } from './dto/assign-to-client.dto';
import { AssignToWarehouseDto } from './dto/assign-to-warehouse.dto';
import { RfidsDto } from './dto/rfids.dto';
import { AssignClientDto } from './dto/assign-client.dto';
import { BulkClaimCylindersDto } from './dto/bulk-claim-cylinders.dto';

@Controller('cylinders')
export class CylindersController {
  constructor(private readonly cylinderService: CylindersService) { }

  @Post()
  create(@Body() createCylinderDto: CreateCylinderDto, @Req() req: any) {
    console.log(req.user);
    return this.cylinderService.create(createCylinderDto, req.user);
  }

  @Post('assign-client')
  assignClient(
    @Body() body: AssignClientDto,
    @Req() req: any,
  ) {
    return this.cylinderService.assignClient(body, req.user);
  }

  @Post('assign-to-client')
  assignToClient(
    @Body() assignToClientDto: AssignToClientDto,
    @Req() req: any,
  ) {
    return this.cylinderService.assignToClient(assignToClientDto, req.user);
  }

  @Patch('lot/:lotNumber/assign-client')
  updateLotClientAssignment(
    @Param('lotNumber') lotNumber: string,
    @Body() body: { clientId: string; cylinderIds: string[] },
    @Req() req: any,
  ) {
    return this.cylinderService.updateLotClientAssignment(lotNumber, body, req.user);
  }
  @Post('assign-to-warehouse') //post method of assign warehouse
  async assignToWarehouse(@Body() dto: AssignToWarehouseDto, @Req() req: any) {
    return this.cylinderService.assignToWarehouse(dto, req.user);
  }

  @Post('assign-new-to-warehouse') // admin assigns selected NEW cylinders to a warehouse
  async assignNewToWarehouse(
    @Body() body: { warehouseId: string; cylinderIds: string[] },
    @Req() req: any,
  ) {
    return this.cylinderService.assignNewToWarehouse(
      body.warehouseId,
      body.cylinderIds,
      req.user,
    );
  }

  @Patch('mark-inside') // plant marks selected ASSIGNED cylinders as INSIDE
  async markInside(
    @Body() body: { cylinderIds: string[] },
    @Req() req: any,
  ) {
    return this.cylinderService.markInside(body.cylinderIds, req.user);
  }

  @Patch(':id')
  updateCylinder(
    @Param('id') id: string,
    @Body() updateCylinderDto: UpdateCylinderDto,
    @Req() req: any,
  ) {
    return this.cylinderService.update(id, updateCylinderDto, req.user);
  }

  @Get('lots')
  getUniqueLots(
    @Query('page') page?: string,
    @Query('perPage') perPage?: string,
    @Query('search') search?: string,
  ) {
    const pageNumber = parseInt(page ?? '1');
    const itemsPerPage = parseInt(perPage ?? '10');
    return this.cylinderService.getUniqueLots(pageNumber, itemsPerPage, search);
  }


  @Get('getclaims')
  getClaims(
    @Query('page') page?: string,
    @Query('perPage') perPage?: string,
    @Query('search') search?: string,
    @Req() req?: any,
  ) {
    const pageNumber = parseInt(page ?? '1');
    const itemsPerPage = parseInt(perPage ?? '10');
    return this.cylinderService.getClaims(pageNumber, itemsPerPage, search, req.user);
  }

  @Post('list')
  findAllWithPost(
    @Body()
    body: {
      per_page?: string | number;
      page?: string | number;
      search?: string;
      status?: string;
      lot?: string;
      month?: number;
      dateFrom?: string;
      dateTo?: string;
      clientId?: string;
      warehouseId?: string;
      vehicleId?: string;
      driverId?: string;
    },
    @Req() req: any,
  ) {
    const {
      per_page,
      page,
      search,
      status,
      lot,
      month,
      dateFrom,
      dateTo,
      clientId,
      warehouseId,
      vehicleId,
      driverId,
    } = body;

    const pageNumber = parseInt(String(page ?? '1'));
    const itemsPerPage = parseInt(String(per_page ?? '10'));

    return this.cylinderService.findAll(
      pageNumber,
      itemsPerPage,
      search,
      status,
      lot,
      month,
      dateFrom,
      dateTo,
      clientId,
      warehouseId,
      vehicleId,
      driverId,
      req.user,
    );
  }

  @Get()
  findAll(
    @Query('per_page') perPage?: string,
    @Query('page') page?: string,
    @Query('search') search?: string,
    @Query('status') status?: string,
    @Query('lot') lot?: string,
    @Query('month') month?: number,
    @Query('dateTo') dateTo?: string,
    @Query('dateFrom') dateFrom?: string,
    @Query('clientId') clientId?: string,
    @Query('warehouseId') warehouseId?: string,
    @Query('vehicleId') vehicleId?: string,
    @Query('driverId') driverId?: string,
    @Req() req?: any,
  ) {
    const pageNumber = parseInt(page ?? '1');
    // const perPage = parseInt(limit ?? "10");
    const itemsPerPage = parseInt(perPage ?? '10');

    return this.cylinderService.findAll(
      pageNumber,
      itemsPerPage,
      search,
      status,
      lot,
      month,
      dateFrom,
      dateTo,
      clientId,
      warehouseId,
      vehicleId,
      driverId,
      req.user
    );
  }

  @Get('search')
  searchCylinder(
    @Query('q') query: string,
    @Query('limit') limit?: string,
    @Query('page') page?: string,
  ) {
    const pageNumber = parseInt(page ?? '1');
    const perPage = parseInt(limit ?? '10');

    return this.cylinderService.searchCylinder(query, pageNumber, perPage);
  }

  @Get('report') //report api
  async getReport() {
    return await this.cylinderService.getAllCylinder(); // fetch all data
  }

  @Get('plants')
  findPlantUsers(
    @Query('page') page?: string,
    @Query('perPage') perPage?: string,
    @Query('search') search?: string,
  ) {
    const pageNumber = parseInt(page ?? '1');
    const perPageNumber = parseInt(perPage ?? '10');
    return this.cylinderService.findPlantUsers(pageNumber, perPageNumber, search);
  }


  @Patch('status/change/:id')
  changeStatus(@Param('id') id: string) {
    return this.cylinderService.changeStatus(id);
  }

  @Patch('bulk/claim')
  @UseGuards(JwtAuthGuard)
  bulkClaimCylinders(@Body() dto: BulkClaimCylindersDto, @Req() req: any) {
    return this.cylinderService.bulkClaimCylinders(dto, req.user);
  }

  @Public()
  @Get('view/:rfid')
  findByRfid(@Param('rfid') rfid: string) {
    return this.cylinderService.findByRfid(rfid);
  }

  @Public()
  @Get('rfid/:rfid')
  getByRfid(@Param('rfid') rfid: string) {
    return this.cylinderService.getByRfid(rfid);
  }

  @Public()
  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.cylinderService.findOne(id);
  }

  @Delete(':id')
  removeCylinder(@Param('id') id: string) {
    return this.cylinderService.remove(id);
  }

  @Post('reconcile')
  reconcileItems(@Body() body: RfidsDto) {
    return this.cylinderService.reconcilecylinders(body);
  }

  @Post('desolve')
  dissolveCylinders(@Body() body: RfidsDto) {
    return this.cylinderService.dissolveCylinders(body);
  }

}

