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

import { FreightAdmin } from "../../common/booking-guards";
import { ContractTemplatesService } from "./contract-templates.service";
import {
  CreateArticleDto,
  PreviewContractTemplateDto,
  ReplaceArticlesDto,
  UpdateArticleDto,
  UpdateContractTemplateDto,
} from "./dto/contract-template.dto";

@ApiTags("contract-templates")
@Controller("contract-templates")
export class ContractTemplatesController {
  constructor(private readonly service: ContractTemplatesService) {}

  // Reads stay open to authenticated staff (the backoffice Templates tab);
  // writes are admin-guarded like other freight configuration resources.

  @Get()
  @ApiOperation({ summary: "List the six contract document templates" })
  list() {
    return this.service.list();
  }

  @Get(":code")
  @ApiOperation({ summary: "Get one contract template by code" })
  getByCode(@Param("code") code: string) {
    return this.service.getByCode(code);
  }

  @Patch(":code")
  @FreightAdmin()
  @ApiOperation({ summary: "Update template metadata (name, title, recitals, active flag)" })
  update(@Param("code") code: string, @Body() dto: UpdateContractTemplateDto) {
    return this.service.update(code, dto);
  }

  @Post(":code/preview")
  @ApiOperation({
    summary: "Render an HTML preview of the template against mock contract data",
  })
  preview(
    @Param("code") code: string,
    @Body() dto: PreviewContractTemplateDto,
  ) {
    return this.service.preview(code, dto);
  }

  /* ------------------------- article routes ------------------------- */

  @Put(":code/articles")
  @FreightAdmin()
  @ApiOperation({ summary: "Replace the full ordered article list (used for reorder)" })
  replaceArticles(@Param("code") code: string, @Body() dto: ReplaceArticlesDto) {
    return this.service.replaceArticles(code, dto.articles);
  }

  @Post(":code/articles")
  @FreightAdmin()
  @ApiOperation({ summary: "Add an article to the template" })
  addArticle(@Param("code") code: string, @Body() dto: CreateArticleDto) {
    return this.service.addArticle(code, dto);
  }

  @Patch(":code/articles/:articleId")
  @FreightAdmin()
  @ApiOperation({ summary: "Update an article's title or body" })
  updateArticle(
    @Param("code") code: string,
    @Param("articleId") articleId: string,
    @Body() dto: UpdateArticleDto,
  ) {
    return this.service.updateArticle(code, articleId, dto);
  }

  @Delete(":code/articles/:articleId")
  @FreightAdmin()
  @ApiOperation({ summary: "Remove an article from the template" })
  removeArticle(
    @Param("code") code: string,
    @Param("articleId") articleId: string,
  ) {
    return this.service.removeArticle(code, articleId);
  }
}
