import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  Patch,
  Post,
  Query,
  Req,
  UploadedFile,
  UseGuards,
  UseInterceptors,
} from "@nestjs/common"
import {
  ApiBearerAuth,
  ApiBody,
  ApiConsumes,
  ApiOperation,
  ApiParam,
  ApiResponse,
  ApiTags,
} from "@nestjs/swagger"
import { AuthGuardMiddleware } from "src/middleware/auth-guard.middleware"
import { CreateFleetManagementDto } from "../dto/create-fleet-management.dto"
import { FindAllFleetManagementDto } from "../dto/find-all-fleet-management.dto"
import { UpdateFleetManagementDto } from "../dto/update-fleet-management.dto"
import { FleetManagement } from "../entities/fleet-management.entity"
import { FleetManagementService } from "./fleet-management.service"
import { FileInterceptor } from "@nestjs/platform-express"
import { vehicleRegistrationFileConfig } from "src/common/file-upload/fleet-registration-document.config"
import { AssignFleetByDriverDto } from "../dto/create-assign-fleet-by-driver.dto"
import { FleetTripFilterDto } from "../dto/fleet-trip-filter.dto"

@ApiTags("Fleet Management")
@UseGuards(AuthGuardMiddleware)
@ApiBearerAuth("access-token")
@Controller("fleet-management")
export class FleetManagementController {
  constructor(
    private readonly fleetManagementService: FleetManagementService,
  ) {}

  @Post()
  @UseInterceptors(
    FileInterceptor("registration_document", vehicleRegistrationFileConfig),
  )
  @ApiConsumes("multipart/form-data")
  @ApiBody({
    type: CreateFleetManagementDto,
  })
  @ApiOperation({ summary: "Create a new vehicle with registration document" })
  @ApiResponse({
    status: 201,
    description: "The vehicle has been successfully created.",
    type: FleetManagement,
  })
  create(
    @Body() createFleetManagementDto: CreateFleetManagementDto,
    @UploadedFile() file?: Express.Multer.File,
  ) {
    return this.fleetManagementService.create(createFleetManagementDto, file)
  }

  @Get()
  @ApiOperation({ summary: "Get all vehicles with pagination and filters" })
  @ApiResponse({
    status: 200,
    description: "Return all vehicles with pagination and filters",
    type: [FleetManagement],
  })
  findAll(@Req() request: any, @Query() query: FindAllFleetManagementDto) {
    return this.fleetManagementService.findAll(
      request.headers["authorization"],
      query,
    )
  }

  @Get("register-number-dropdown")
  @ApiOperation({ summary: "Get register number dropdown" })
  @ApiResponse({
    status: 200,
    description: "Return register number dropdown",
  })
  getRegisterNumberDropdown(@Req() request: any) {
    return this.fleetManagementService.getRegisterNumberDropdown(
      request.headers["authorization"],
    )
  }

  @Patch("assign-by-driver")
  @ApiOperation({ summary: "Assign a driver to a fleet and log assignment" })
  @ApiBody({ type: AssignFleetByDriverDto })
  async assignFleetByDriver(
    @Body() assignFleetByDriverDto: AssignFleetByDriverDto,
  ) {
    const { fleetId, driverId } = assignFleetByDriverDto
    return this.fleetManagementService.assignFleetByDriver(fleetId, driverId)
  }

  @Get(":id")
  @ApiOperation({ summary: "Get a vehicle by id" })
  @ApiResponse({
    status: 200,
    description: "Return the vehicle",
  })
  findOne(@Param("id") id: number) {
    return this.fleetManagementService.findOne(id)
  }

  @Patch(":id")
  @UseInterceptors(
    FileInterceptor("registration_document", vehicleRegistrationFileConfig),
  )
  @ApiConsumes("multipart/form-data")
  @ApiOperation({ summary: "Update a vehicle" })
  @ApiBody({ type: UpdateFleetManagementDto })
  @ApiResponse({
    status: 200,
    description: "The vehicle has been successfully updated.",
    type: FleetManagement,
  })
  @ApiResponse({ status: 404, description: "Vehicle not found" })
  update(
    @Param("id") id: number,
    @Body() updateFleetManagementDto: UpdateFleetManagementDto,
    @UploadedFile() file?: Express.Multer.File,
  ) {
    return this.fleetManagementService.update(
      id,
      updateFleetManagementDto,
      file,
    )
  }

  @Delete(":id")
  @ApiOperation({ summary: "Delete a vehicle" })
  @ApiResponse({
    status: 200,
    description: "The vehicle has been successfully deleted.",
  })
  @ApiResponse({ status: 404, description: "Vehicle not found" })
  remove(@Param("id") id: number) {
    return this.fleetManagementService.remove(id)
  }

  @Patch(":id/registration-document")
  @UseInterceptors(FileInterceptor("file", vehicleRegistrationFileConfig))
  @ApiConsumes("multipart/form-data")
  @ApiBody({
    schema: {
      type: "object",
      properties: {
        file: { type: "string", format: "binary" },
      },
      required: ["file"],
    },
  })
  async updateRegistrationDocument(
    @Param("id") id: number,
    @UploadedFile() file: Express.Multer.File,
  ) {
    return this.fleetManagementService.addRegistrationDocument(id, file)
  }

  @Get("/trip/:id")
  @ApiOperation({ summary: "Get all vehicles with pagination and filters" })
  @ApiResponse({
    status: 200,
    description: "Return all vehicles with pagination and filters",
    type: [FleetManagement],
  })
  getAllVehicleForTrip(
    @Param("id") id: number,
    @Query() query: FleetTripFilterDto,
  ) {
    return this.fleetManagementService.getAllVehiclesForTripAssignment(
      id,
      query,
    )
  }

  @Get("check-fleet-availability/:fleet_id/trip/:trip_id")
  @ApiParam({
    name: "fleet_id",
    type: Number,
    description: "Fleet/Vehicle ID to check availability",
    required: true,
  })
  @ApiParam({
    name: "trip_id",
    type: Number,
    description: "Trip ID for which the fleet needs to be checked",
    required: true,
  })
  async checkFleetAvailability(
    @Param("fleet_id") fleetIdStr: string,
    @Param("trip_id") tripIdStr: string,
  ) {
    const fleet_id = parseInt(fleetIdStr, 10)
    const trip_id = parseInt(tripIdStr, 10)

    return await this.fleetManagementService.checkFleetAvailability({
      fleet_id,
      trip_id,
    })
  }
}
