import { Controller, Get, Post, Param, Body, Query, Res } from '@nestjs/common'
import { Response } from 'express'
import { InjectModel } from '@nestjs/mongoose'
import { Model } from 'mongoose'
import { InvoicesService } from './invoices.service'
import { InvoicePdfService } from './invoice-pdf.service'
import { CreateInvoiceDto } from './dto/create-invoice.dto'
import { GenerateInvoiceDto } from './dto/generate-invoice.dto'
import { ClientFolder, ClientFolderDocument } from '../common/schemas'

@Controller('invoices')
export class InvoicesController {
  constructor(
    private readonly service: InvoicesService,
    private readonly pdfService: InvoicePdfService,
    @InjectModel(ClientFolder.name) private folderModel: Model<ClientFolderDocument>,
  ) {}

  @Post()
  create(@Body() dto: CreateInvoiceDto) {
    return this.service.create(dto)
  }

  @Post('generate')
  generateFromTimeEntries(@Body() dto: GenerateInvoiceDto) {
    return this.service.generateFromTimeEntries(dto)
  }

  @Get()
  findAll(
    @Query('clientFolderId') clientFolderId?: string,
    @Query('matterId') matterId?: string,
    @Query('status') status?: string,
    @Query('limit') limit?: string,
    @Query('offset') offset?: string,
  ) {
    return this.service.findAll({
      clientFolderId, matterId, status,
      limit: limit ? parseInt(limit) : undefined,
      offset: offset ? parseInt(offset) : undefined,
    })
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.service.findOne(id)
  }

  @Post(':id/send')
  markSent(@Param('id') id: string) {
    return this.service.markSent(id)
  }

  @Post(':id/pay')
  markPaid(
    @Param('id') id: string,
    @Body('paidAmount') paidAmount: number,
    @Body('paidDate') paidDate?: string,
  ) {
    return this.service.markPaid(id, paidAmount, paidDate ? new Date(paidDate) : undefined)
  }

  @Post(':id/void')
  voidInvoice(@Param('id') id: string) {
    return this.service.voidInvoice(id)
  }

  @Get(':id/pdf')
  async downloadPdf(@Param('id') id: string, @Res() res: Response) {
    const invoice = await this.service.findOne(id)
    const folder  = await this.folderModel.findById(invoice.clientFolderId).exec()
    if (!folder) { res.status(404).json({ message: 'Client folder not found' }); return }

    const pdf = await this.pdfService.generate(invoice, folder)
    res.set({
      'Content-Type':        'application/pdf',
      'Content-Disposition': `attachment; filename="${invoice.invoiceNumber}.pdf"`,
      'Content-Length':      pdf.length,
    })
    res.end(pdf)
  }
}
