import {
  Body,
  Controller,
  Delete,
  Get,
  HttpCode,
  HttpStatus,
  Param,
  ParseUUIDPipe,
  Patch,
  Post,
  Put,
} from "@nestjs/common";
import { ApiOperation, ApiTags } from "@nestjs/swagger";

import { FreightAdmin } from "../../common/booking-guards";
import { CreateFileUploadFieldDto } from "./dto/create-file-upload-field.dto";
import { CreateFileUploadSettingDto } from "./dto/create-file-upload-setting.dto";
import { UpdateFileUploadFieldDto } from "./dto/update-file-upload-field.dto";
import { UpdateFileUploadSettingDto } from "./dto/update-file-upload-setting.dto";
import { FileUploadSettingsService } from "./file-upload-settings.service";

@ApiTags("file-upload-settings")
@Controller("file-upload-settings")
export class FileUploadSettingsController {
  constructor(private readonly service: FileUploadSettingsService) {}

  // Reads stay open: the customer portal fetches these to render dynamic
  // upload forms (by-code / by-entity). Only writes are admin-guarded.

  @Get()
  @ApiOperation({ summary: "List all file upload settings" })
  list() {
    return this.service.list();
  }

  @Get(":id")
  @ApiOperation({ summary: "Get a file upload setting by ID" })
  getById(@Param("id", ParseUUIDPipe) id: string) {
    return this.service.getById(id);
  }

  @Get("by-code/:code")
  @ApiOperation({ summary: "Get a file upload setting by its stable code" })
  getByCode(@Param("code") code: string) {
    return this.service.getByCode(code);
  }

  @Get("by-entity/:entity")
  @ApiOperation({ summary: "Get all file upload settings for an entity type (customer, booking, etc.)" })
  getByEntity(@Param("entity") entity: string) {
    return this.service.getByEntity(entity);
  }

  @Post()
  @FreightAdmin()
  @ApiOperation({ summary: "Create a new file upload setting" })
  create(@Body() dto: CreateFileUploadSettingDto) {
    return this.service.create(dto);
  }

  @Patch(":id")
  @FreightAdmin()
  @ApiOperation({ summary: "Update a file upload setting's metadata" })
  update(
    @Param("id", ParseUUIDPipe) id: string,
    @Body() dto: UpdateFileUploadSettingDto,
  ) {
    return this.service.update(id, dto);
  }

  @Delete(":id")
  @FreightAdmin()
  @ApiOperation({ summary: "Soft-delete a file upload setting" })
  @HttpCode(HttpStatus.NO_CONTENT)
  remove(@Param("id", ParseUUIDPipe) id: string) {
    return this.service.remove(id);
  }

  /* ------------------------- field routes ------------------------- */

  @Put(":id/fields")
  @FreightAdmin()
  @ApiOperation({ summary: "Replace the full field list for a setting" })
  replaceFields(
    @Param("id", ParseUUIDPipe) id: string,
    @Body() fields: CreateFileUploadFieldDto[],
  ) {
    return this.service.replaceFields(id, fields);
  }

  @Post(":id/fields")
  @FreightAdmin()
  @ApiOperation({ summary: "Append a single field to a setting" })
  addField(
    @Param("id", ParseUUIDPipe) id: string,
    @Body() dto: CreateFileUploadFieldDto,
  ) {
    return this.service.addField(id, dto);
  }

  @Patch("fields/:fieldId")
  @FreightAdmin()
  @ApiOperation({ summary: "Update a single field" })
  updateField(
    @Param("fieldId", ParseUUIDPipe) fieldId: string,
    @Body() dto: UpdateFileUploadFieldDto,
  ) {
    return this.service.updateField(fieldId, dto);
  }

  @Delete("fields/:fieldId")
  @FreightAdmin()
  @ApiOperation({ summary: "Soft-delete a single field" })
  @HttpCode(HttpStatus.NO_CONTENT)
  removeField(@Param("fieldId", ParseUUIDPipe) fieldId: string) {
    return this.service.removeField(fieldId);
  }
}
