import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  ParseUUIDPipe,
  Post,
  UseGuards,
} from '@nestjs/common';
import { DestinationVehicleTypeService } from './destination-vehicle-type.service';
import { JwtAuthGuard } from '../../auth/guards/jwt-auth.guard';
import { PermissionGuard } from '../../auth/guards/permission.guard';
import { Permissions } from '../../auth/decorators/permissions.decorator';
import { Lookup } from '../../common/decorators/lookup.decorator';
import { AccessLevel, ModuleName } from '../../entities/role-permission.entity';
import { successResponse } from '../../common/responses/api-response';

/**
 * Master-data CRUD for destination → vehicle type assignments.
 *
 * Gated under SETTINGS module (where Destinations + Vehicle Types
 * already live). The GET endpoints used as dropdowns by Quote/Booking
 * forms expose a separate @Lookup() route so any authed user can read
 * them without needing Settings:view permission.
 */
@Controller('destination-vehicle-types')
@UseGuards(JwtAuthGuard, PermissionGuard)
export class DestinationVehicleTypeController {
  constructor(private readonly service: DestinationVehicleTypeService) {}

  /** Admin list — grouped by destination. */
  @Get()
  @Permissions({ module: ModuleName.DESTINATION_VEHICLE_TYPE, accessLevel: AccessLevel.VIEW })
  async findAll() {
    const data = await this.service.findAllGrouped();
    return successResponse(data, 'Destination vehicle types fetched');
  }

  /**
   * Lookup: vehicle types available for a destination. Used by the
   * Quote/Booking transport row's cab-type dropdown.
   */
  @Get('lookup/:destinationId')
  @Lookup()
  async lookupByDestination(@Param('destinationId', ParseUUIDPipe) destinationId: string) {
    const data = await this.service.findByDestination(destinationId);
    return successResponse(data, 'Vehicle types for destination');
  }

  /**
   * Upsert: replace the full mapping set for a destination in one call.
   * Body: { destination_id, vehicle_type_ids: string[] }
   */
  @Post()
  @Permissions({ module: ModuleName.DESTINATION_VEHICLE_TYPE, accessLevel: AccessLevel.EDIT })
  async upsert(@Body() body: { destination_id: string; vehicle_type_ids: string[] }) {
    const data = await this.service.upsertForDestination(body);
    return successResponse(data, 'Mapping saved');
  }

  @Delete(':destinationId')
  @Permissions({ module: ModuleName.DESTINATION_VEHICLE_TYPE, accessLevel: AccessLevel.DELETE })
  async remove(@Param('destinationId', ParseUUIDPipe) destinationId: string) {
    const data = await this.service.removeByDestination(destinationId);
    return successResponse(data, 'Mapping cleared');
  }

  /**
   * Find-or-create a vehicle type by typed name AND map it to the
   * destination. Used by Movement Chart's inline "type a new vehicle"
   * flow — when ops types e.g. "Ola" the FE calls this and gets back
   * the vehicle_type_id to save against the row.
   *
   *   - case-insensitive name match against existing vehicle_types
   *   - tenant-scoped (CLS); never touches another tenant's row
   *   - idempotent on the destination mapping side
   *
   * Permissioned under DRIVER_ASSIGNMENT:edit (not SETTINGS) — ops
   * staff editing the Movement Chart should be able to add a vehicle
   * type on the fly without needing Settings access.
   */
  @Post('placeholder')
  @Permissions({ module: ModuleName.DRIVER_ASSIGNMENT, accessLevel: AccessLevel.EDIT })
  async createPlaceholder(@Body() body: { name: string; destination_id: string }) {
    const data = await this.service.createPlaceholder(body);
    return successResponse(data, 'Vehicle type ready');
  }
}
