import {
  Controller,
  Get,
  Param,
  ParseUUIDPipe,
  Query,
  Res,
} from "@nestjs/common";
import { ApiBearerAuth, ApiOperation, ApiTags } from "@nestjs/swagger";
import type { Response } from "express";

import { BookingView } from "../../common/booking-guards";
import { BillingService } from "./billing.service";
import { FilterInvoiceDto } from "./dto/filter-invoice.dto";

@ApiTags("billing")
@Controller("billing")
@BookingView()
@ApiBearerAuth()
export class BillingController {
  constructor(private readonly billingService: BillingService) {}

  @Get("invoices")
  @ApiOperation({
    summary: "List invoices (paginated, filterable by company/status/search)",
  })
  findAll(@Query() query: FilterInvoiceDto) {
    return this.billingService.findAllPaginated(query);
  }

  @Get("invoices/:id")
  @ApiOperation({ summary: "Get an invoice with its line items" })
  findById(@Param("id", ParseUUIDPipe) id: string) {
    return this.billingService.findById(id);
  }

  @Get("invoices/:id/document")
  @ApiOperation({ summary: "Download the sealed invoice PDF" })
  async document(@Param("id", ParseUUIDPipe) id: string, @Res() res: Response) {
    const { filename, buffer } = await this.billingService.document(id);
    sendPdf(res, filename, buffer);
  }

  @Get("invoices/:id/receipt")
  @ApiOperation({ summary: "Download the sealed payment receipt PDF" })
  async receipt(@Param("id", ParseUUIDPipe) id: string, @Res() res: Response) {
    const { filename, buffer } = await this.billingService.receipt(id);
    sendPdf(res, filename, buffer);
  }
}

/** Stream a generated PDF as a file download. */
export function sendPdf(res: Response, filename: string, buffer: Buffer): void {
  res.setHeader("Content-Type", "application/pdf");
  res.setHeader("Content-Disposition", `attachment; filename="${filename}"`);
  res.setHeader("Content-Length", buffer.length);
  res.send(buffer);
}
