import { Body, Controller, Get, HttpException, HttpStatus, Param, Post, Query, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiBody, ApiCreatedResponse, ApiQuery } from '@nestjs/swagger';
import { RequireModule, RequirePermission } from 'src/auth/decorators';
import type { LoginUserInfo } from 'src/auth/dto/login.dto';
import { GetUser } from 'src/auth/get-user.decorator';
import { ModuleGuard } from 'src/auth/guards/module.guard';
import { PermissionGuard } from 'src/auth/guards/permission.guard';
import { CreateNotaCreditoDto } from './dto/create-nota-credito.dto';
import {
    response_nota_credito_all,
    response_nota_credito_create,
    response_nota_credito_find,
    response_nota_credito_siguiente_numeracion,
} from './dto/doc-swagger';
import { NotaCreditosService } from './nota-creditos.service';

@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), ModuleGuard, PermissionGuard)
@RequireModule('VENTAS')
@Controller({ path: 'nota-creditos', version: '1' })
export class NotaCreditosController {
  constructor(private readonly notaCreditosService: NotaCreditosService) {}

  @Post()
  @RequirePermission('VENTAS', 'VEN_NC_NOTA_CREDITO_CREAR')
  @ApiBody({ type: CreateNotaCreditoDto })
  @ApiCreatedResponse(response_nota_credito_create)
  create(@Body() createNotaCreditoDto: CreateNotaCreditoDto, @GetUser() user: LoginUserInfo) {
    return this.notaCreditosService.create(createNotaCreditoDto, user.empresa_id, user?.id);
  }

  @Get('factura/:facturaId/saldos-disponibles')
  @RequirePermission('VENTAS', 'VEN_NC_NOTA_CREDITO_VER')
  saldosDisponiblesFactura(@Param('facturaId') facturaId: string, @GetUser() user: LoginUserInfo) {
    return this.notaCreditosService.saldosDisponiblesFactura(facturaId, user.empresa_id);
  }

  @Get('siguiente-numeracion/:est/:exp')
  @RequirePermission('VENTAS', 'VEN_NC_NOTA_CREDITO_VER')
  @ApiCreatedResponse(response_nota_credito_siguiente_numeracion)
  getSiguienteNumeracion(@Param('est') est: string, @Param('exp') exp: string, @GetUser() user: LoginUserInfo) {
    return this.notaCreditosService.getSiguienteNumeracion(est, exp, user.empresa_id);
  }

  @Get()
  @RequirePermission('VENTAS', 'VEN_NC_NOTA_CREDITO_VER')
  @ApiCreatedResponse(response_nota_credito_all)
  @ApiQuery({ name: 'page', required: false, type: Number })
  @ApiQuery({ name: 'limit', required: false, type: Number })
  @ApiQuery({ name: 'search', required: false, type: String })
  @ApiQuery({ name: 'estado', required: false, type: String })
  @ApiQuery({ name: 'fechaDesde', required: false, type: String })
  @ApiQuery({ name: 'fechaHasta', required: false, type: String })
  findAll(
    @Query('page') page: number,
    @Query('limit') limit: number,
    @Query('search') search: string,
    @Query('estado') estado: string,
    @Query('fechaDesde') fechaDesde: string,
    @Query('fechaHasta') fechaHasta: string,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.notaCreditosService.findAll(page, limit, user.empresa_id, {
      search,
      estado,
      fechaDesde,
      fechaHasta,
      usuarioId: user.id,
    });
  }

  @Get(':id')
  @RequirePermission('VENTAS', 'VEN_NC_NOTA_CREDITO_VER')
  @ApiCreatedResponse(response_nota_credito_find)
  findOne(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.notaCreditosService.findOne(id, user.empresa_id);
  }

  @Post('enviar-lote-middleware')
  @RequirePermission('VENTAS', 'VEN_NC_NOTA_CREDITO_CREAR')
  @ApiBody({
    description: 'IDs de notas de crédito a enviar al middleware',
    schema: {
      type: 'object',
      properties: {
        nota_credito_ids: { type: 'array', items: { type: 'string' } },
      },
    },
  })
  async enviarLoteMiddleware(@Body() body: { nota_credito_ids: string[] }, @GetUser() user: LoginUserInfo) {
    try {
      const result = await this.notaCreditosService.enviarLoteMiddleware(
        body.nota_credito_ids,
        user.empresa_id,
        user?.id,
      );
      return {
        message: 'Notas de crédito enviadas al middleware exitosamente',
        data: result,
      };
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Error desconocido';
      throw new HttpException(
        {
          success: false,
          message: 'Error al enviar notas de crédito al middleware',
          error: errorMessage,
        },
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }
}
