import { Body, Controller, Get, Param, Post, UseGuards, ValidationPipe } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiBody, ApiOperation, ApiTags } from '@nestjs/swagger';
import { RequirePermission } from 'src/auth/decorators/require-permission.decorator';
import { RequireSubmodulo } from 'src/auth/decorators/require-submodulo.decorator';
import type { LoginUserInfo } from 'src/auth/dto/login.dto';
import { GetUser } from 'src/auth/get-user.decorator';
import { PermissionGuard } from 'src/auth/guards/permission.guard';
import { SubmoduloGuard } from 'src/auth/guards/submodulo.guard';
import { CierreVentaService } from './cierre-venta.service';
import { OverrideCreditoService } from './override-credito.service';
import { CerrarVentaDto } from './dto/cerrar-venta.dto';

@ApiTags('CRM · Cierre de venta')
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), SubmoduloGuard)
@RequireSubmodulo('CRM_CIERRE')
@Controller({ path: 'crm/oportunidades', version: '1' })
export class CierreVentaController {
  constructor(
    private readonly service: CierreVentaService,
    private readonly override: OverrideCreditoService,
  ) {}

  @Get('cierre/supervisores')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CIE_CIERRE_PROCESAR')
  @ApiOperation({
    summary: 'Quiénes pueden autorizar un cierre por encima del límite de crédito',
    description:
      'Usuarios con el privilegio CRM_CIE_CREDITO_AUTORIZAR y PIN configurado. Sin PIN no ' +
      'podrían firmar, así que no se ofrecen.',
  })
  supervisores(@GetUser() user: LoginUserInfo) {
    return this.override.supervisores(user.empresa_id);
  }

  @Post(':id/cierre/preview')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CIE_CIERRE_PROCESAR')
  @ApiOperation({
    summary: 'Simula el cierre sin persistir nada',
    description:
      'Valida cliente fiscal, DV del RUC, crédito e ítems, y devuelve el payload de facturación ' +
      'más el destino (orden de venta o factura directa). La factura emitida después tiene que ' +
      'coincidir 100% con esto.',
  })
  @ApiBody({ type: CerrarVentaDto })
  preview(@Param('id') id: string, @Body(ValidationPipe) dto: CerrarVentaDto, @GetUser() user: LoginUserInfo) {
    return this.service.preview(id, dto, user.empresa_id);
  }

  @Post(':id/cierre')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CIE_CIERRE_PROCESAR')
  @ApiOperation({
    summary: 'Ejecuta el cierre: crea los documentos y gana la oportunidad',
    description:
      'Siempre nace una orden de venta —es lo que reserva stock y deja trazabilidad— y, si no hay ' +
      'entrega ni anticipo, se factura en el acto. Primero el documento y después la oportunidad: ' +
      'al revés quedaría una oportunidad ganada sin nada detrás.',
  })
  @ApiBody({ type: CerrarVentaDto })
  ejecutar(@Param('id') id: string, @Body(ValidationPipe) dto: CerrarVentaDto, @GetUser() user: LoginUserInfo) {
    return this.service.ejecutar(id, dto, user.empresa_id, user.id);
  }
}
