/* ============================================================
 * Copyright (c) 2026 RAVAPI Soluções. www.ravapi.com
 * Controller de referência — modo SaaS
 * ATENÇÃO: camada de ligação, ainda não coberta por teste automatizado.
 * ============================================================ */

import {
  Controller, Get, Post, Patch, Body, Param, Query, Inject, UseInterceptors,
} from '@nestjs/common';
import { TenantInterceptor } from './tenant.interceptor.ts';
import { IDENTIDADE } from './recibos.module.ts';
import type { IdentityProvider } from '../core/identity.ts';
import { RecibosService, type DadosRascunho, type FiltroRecibos } from '../domain/recibos.service.ts';
import type { Direcao, NovaContraparte, NovaEmpresa, NovaSerie } from '../domain/cadastros.service.ts';
import { CadastrosService } from '../domain/cadastros.service.ts';
import { LicencaService } from '../domain/licenca.service.ts';

@Controller('recibos')
@UseInterceptors(TenantInterceptor)
export class RecibosController {
  constructor(
    private readonly recibos: RecibosService,
    private readonly cadastros: CadastrosService,
    private readonly licenca: LicencaService,
    @Inject(IDENTIDADE) private readonly identidade: IdentityProvider,
  ) {}

  @Post('rascunhos')
  salvarRascunho(@Body() corpo: DadosRascunho) {
    return this.recibos.salvarRascunho(this.identidade.usuarioAtual(), corpo);
  }

  @Patch('rascunhos/:id')
  atualizarRascunho(@Param('id') id: string, @Body() corpo: DadosRascunho) {
    return this.recibos.salvarRascunho(this.identidade.usuarioAtual(), corpo, id);
  }

  /** Único caminho que cria documento selado. Não existe POST /recibos. */
  @Post('rascunhos/:id/selar')
  async selar(@Param('id') id: string, @Body() corpo: DadosRascunho) {
    const { recibo } = await this.recibos.selar(this.identidade.usuarioAtual(), corpo, id);
    return recibo;
  }

  @Post(':id/cancelamento')
  cancelar(@Param('id') id: string, @Body() corpo: { motivo: string }) {
    return this.recibos.cancelar(this.identidade.usuarioAtual(), id, corpo.motivo);
  }

  @Get('contrapartes')
  buscarContrapartes(@Query('q') termo = '') {
    return this.cadastros.buscarContrapartes(termo);
  }

  /** Cadastro rápido (docs/decisoes.md §16.3): CPF novo cria, existente devolve a mesma pessoa. */
  @Post('contrapartes')
  localizarOuCriarContraparte(@Body() corpo: NovaContraparte) {
    return this.cadastros.localizarOuCriar(this.identidade.usuarioAtual(), corpo);
  }

  @Get('licenca')
  verLicenca() {
    return this.licenca.atual();
  }

  /** Estático primeiro: 'series', 'empresa' e 'empresas' não podem cair na rota dinâmica :id abaixo. */
  @Get('series')
  listarSeries(@Query('companyId') companyId?: string) {
    return this.cadastros.listarSeries(this.identidade.usuarioAtual(), companyId);
  }

  @Post('series')
  criarSerie(@Body() corpo: NovaSerie) {
    return this.cadastros.criarSerie(this.identidade.usuarioAtual(), corpo);
  }

  @Get('empresa')
  minhaEmpresa() {
    return this.cadastros.minhaEmpresa();
  }

  @Post('empresas')
  criarEmpresa(@Body() corpo: NovaEmpresa) {
    return this.cadastros.criarEmpresa(this.identidade.usuarioAtual(), corpo);
  }

  @Get()
  listar(
    @Query('seriesId') seriesId?: string,
    @Query('direcao') direcao?: Direcao,
    @Query('busca') busca?: string,
  ) {
    const filtros: FiltroRecibos = { seriesId, direcao, busca };
    return this.recibos.listar(this.identidade.usuarioAtual(), filtros);
  }

  @Get(':id')
  buscarPorId(@Param('id') id: string) {
    return this.recibos.buscarPorId(this.identidade.usuarioAtual(), id);
  }

  @Get(':id/eventos')
  eventos(@Param('id') id: string) {
    return this.recibos.eventos(this.identidade.usuarioAtual(), id);
  }
}
