import { Controller, Post, Get, Patch, Delete, Body, Param, Query } from '@nestjs/common';
import { ApiBearerAuth, ApiTags, ApiOperation } from '@nestjs/swagger';
import { BookingStaff } from '../../common/booking-guards';
import { FREIGHT_PERMS } from '../../seed/freight-permissions.registry';
import { MaintenanceService } from './maintenance.service';
import { MaintenanceDepthService } from './maintenance-depth.service';
import {
  CreateMaintenanceScheduleDto,
  CreateMaintenanceCostDto,
  UpdateMaintenanceScheduleDto,
  UpsertMaintenanceIntervalDto,
} from './dto/create-maintenance.dto';
import {
  CreateWorkOrderDto,
  UpdateWorkOrderDto,
  CreatePartDto,
  UpdatePartDto,
  CreateWarrantyDto,
} from './dto/create-maintenance-depth.dto';
import { WorkOrderStatus } from './entities/work-order.entity';

@ApiTags('Maintenance Management')
@ApiBearerAuth()
@Controller('maintenance')
export class MaintenanceController {
  constructor(
    private readonly maintenanceService: MaintenanceService,
    private readonly maintenanceDepthService: MaintenanceDepthService,
  ) {}

  @Post('schedules')
  @BookingStaff(FREIGHT_PERMS.maintenance.create)
  @ApiOperation({ summary: 'Schedule maintenance' })
  async scheduleMaintenanceAsync(@Body() dto: CreateMaintenanceScheduleDto) {
    return this.maintenanceService.scheduleMaintenanceAsync(dto);
  }

  @Post('costs')
  @BookingStaff(FREIGHT_PERMS.maintenance.create)
  @ApiOperation({ summary: 'Record maintenance cost' })
  async recordCost(@Body() dto: CreateMaintenanceCostDto) {
    return this.maintenanceService.recordMaintenanceCost(dto);
  }

  @Patch('schedules/:id')
  @BookingStaff(FREIGHT_PERMS.maintenance.update)
  @ApiOperation({ summary: 'Update maintenance schedule' })
  async updateSchedule(@Param('id') id: string, @Body() dto: UpdateMaintenanceScheduleDto) {
    return this.maintenanceService.updateMaintenanceSchedule(id, dto);
  }

  @Get('due-board')
  @BookingStaff([FREIGHT_PERMS.maintenance.view, FREIGHT_PERMS.fleetDashboard.view])
  @ApiOperation({ summary: 'Fleet-wide next-due maintenance board (by date and km)' })
  async getDueBoard() {
    return this.maintenanceService.getDueBoard();
  }

  @Post('intervals')
  @BookingStaff(FREIGHT_PERMS.maintenance.create)
  @ApiOperation({ summary: 'Define/adjust a service interval (e.g. oil change every 10,000 km)' })
  async upsertInterval(@Body() dto: UpsertMaintenanceIntervalDto) {
    return this.maintenanceService.upsertInterval(dto);
  }

  @Get('intervals/:vehicleId')
  @BookingStaff(FREIGHT_PERMS.maintenance.view)
  @ApiOperation({ summary: "A vehicle's active service intervals" })
  async getIntervals(@Param('vehicleId') vehicleId: string) {
    return this.maintenanceService.getIntervals(vehicleId);
  }

  @Delete('intervals/:id')
  @BookingStaff(FREIGHT_PERMS.maintenance.delete)
  @ApiOperation({ summary: 'Deactivate a service interval (stops auto-scheduling)' })
  async deactivateInterval(@Param('id') id: string) {
    return this.maintenanceService.deactivateInterval(id);
  }

  @Get('upcoming/:vehicleId')
  @BookingStaff(FREIGHT_PERMS.maintenance.view)
  @ApiOperation({ summary: 'Get upcoming maintenance' })
  async getUpcoming(@Param('vehicleId') vehicleId: string) {
    return this.maintenanceService.getUpcomingMaintenance(vehicleId);
  }

  @Get('history/:vehicleId')
  @BookingStaff(FREIGHT_PERMS.maintenance.view)
  @ApiOperation({ summary: 'Get maintenance history' })
  async getHistory(@Param('vehicleId') vehicleId: string) {
    return this.maintenanceService.getMaintenanceHistory(vehicleId);
  }

  @Get('stats')
  @BookingStaff([FREIGHT_PERMS.maintenance.view, FREIGHT_PERMS.fleetReports.view, FREIGHT_PERMS.fleetDashboard.view])
  @ApiOperation({ summary: 'Get fleet-wide maintenance statistics' })
  async getFleetStats() {
    return this.maintenanceService.getFleetMaintenanceStats();
  }

  @Get('stats/:vehicleId')
  @BookingStaff([FREIGHT_PERMS.maintenance.view, FREIGHT_PERMS.fleetReports.view, FREIGHT_PERMS.fleetDashboard.view])
  @ApiOperation({ summary: 'Get maintenance statistics' })
  async getStats(@Param('vehicleId') vehicleId: string) {
    return this.maintenanceService.getVehicleMaintenanceStats(vehicleId);
  }

  // ---- Work Orders ----

  @Post('work-orders')
  @BookingStaff(FREIGHT_PERMS.maintenance.create)
  @ApiOperation({ summary: 'Create work order' })
  async createWorkOrder(@Body() dto: CreateWorkOrderDto) {
    return this.maintenanceDepthService.createWorkOrder(dto);
  }

  @Get('work-orders')
  @BookingStaff(FREIGHT_PERMS.maintenance.view)
  @ApiOperation({ summary: 'List work orders' })
  async listWorkOrders(
    @Query('vehicleId') vehicleId?: string,
    @Query('status') status?: WorkOrderStatus,
  ) {
    return this.maintenanceDepthService.findWorkOrders({ vehicleId, status });
  }

  @Get('work-orders/:id')
  @BookingStaff(FREIGHT_PERMS.maintenance.view)
  @ApiOperation({ summary: 'Get work order' })
  async getWorkOrder(@Param('id') id: string) {
    return this.maintenanceDepthService.findWorkOrderById(id);
  }

  @Patch('work-orders/:id')
  @BookingStaff(FREIGHT_PERMS.maintenance.update)
  @ApiOperation({ summary: 'Update work order' })
  async updateWorkOrder(@Param('id') id: string, @Body() dto: UpdateWorkOrderDto) {
    return this.maintenanceDepthService.updateWorkOrder(id, dto);
  }

  @Delete('work-orders/:id')
  @BookingStaff(FREIGHT_PERMS.maintenance.delete)
  @ApiOperation({ summary: 'Delete work order' })
  async deleteWorkOrder(@Param('id') id: string) {
    return this.maintenanceDepthService.deleteWorkOrder(id);
  }

  // ---- Parts / Tires ----

  @Post('parts')
  @BookingStaff(FREIGHT_PERMS.maintenance.create)
  @ApiOperation({ summary: 'Create part' })
  async createPart(@Body() dto: CreatePartDto) {
    return this.maintenanceDepthService.createPart(dto);
  }

  @Get('parts')
  @BookingStaff(FREIGHT_PERMS.maintenance.view)
  @ApiOperation({ summary: 'List parts / tire inventory' })
  async listParts(
    @Query('category') category?: string,
    @Query('lowStock') lowStock?: string,
  ) {
    return this.maintenanceDepthService.findParts({
      category,
      lowStock: lowStock === 'true',
    });
  }

  @Patch('parts/:id')
  @BookingStaff(FREIGHT_PERMS.maintenance.update)
  @ApiOperation({ summary: 'Update part' })
  async updatePart(@Param('id') id: string, @Body() dto: UpdatePartDto) {
    return this.maintenanceDepthService.updatePart(id, dto);
  }

  @Delete('parts/:id')
  @BookingStaff(FREIGHT_PERMS.maintenance.delete)
  @ApiOperation({ summary: 'Delete part' })
  async deletePart(@Param('id') id: string) {
    return this.maintenanceDepthService.deletePart(id);
  }

  // ---- Warranties ----

  @Post('warranties')
  @BookingStaff(FREIGHT_PERMS.maintenance.create)
  @ApiOperation({ summary: 'Create warranty' })
  async createWarranty(@Body() dto: CreateWarrantyDto) {
    return this.maintenanceDepthService.createWarranty(dto);
  }

  @Get('warranties')
  @BookingStaff(FREIGHT_PERMS.maintenance.view)
  @ApiOperation({ summary: 'List warranties' })
  async listWarranties(@Query('vehicleId') vehicleId?: string) {
    return this.maintenanceDepthService.findWarranties({ vehicleId });
  }

  @Delete('warranties/:id')
  @BookingStaff(FREIGHT_PERMS.maintenance.delete)
  @ApiOperation({ summary: 'Delete warranty' })
  async deleteWarranty(@Param('id') id: string) {
    return this.maintenanceDepthService.deleteWarranty(id);
  }
}
