import { Body, Controller, Delete, Get, Param, Patch, Post, Put, Query, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiOperation, ApiQuery, ApiTags } from '@nestjs/swagger';
import type { LoginUserInfo } from 'src/auth/dto/login.dto';
import { RequirePermission } from 'src/auth/decorators/require-permission.decorator';
import { GetUser } from 'src/auth/get-user.decorator';
import { PermissionGuard } from 'src/auth/guards/permission.guard';
import { AsientosService } from '../services/asientos.service';
import { CrearAsientoDto, EditarAsientoDto } from '../dto/crear-asiento.dto';

@ApiTags('Contabilidad - Asientos')
@Controller({ path: 'contabilidad/asientos', version: '1' })
@UseGuards(AuthGuard('jwt'), PermissionGuard)
@ApiBearerAuth()
export class AsientosController {
  constructor(private readonly service: AsientosService) {}

  @Get()
  @RequirePermission('CONTABILIDAD', 'CONT_ASI_ASIENTO_VER')
  @ApiOperation({ summary: 'Listar asientos contables' })
  @ApiQuery({ name: 'periodoId', required: false })
  @ApiQuery({ name: 'estado', required: false, enum: ['BORRADOR', 'CONFIRMADO', 'REVERTIDO'] })
  @ApiQuery({ name: 'desde', required: false })
  @ApiQuery({ name: 'hasta', required: false })
  @ApiQuery({ name: 'skip', required: false })
  @ApiQuery({ name: 'take', required: false })
  listar(
    @GetUser() user: LoginUserInfo,
    @Query('periodoId') periodoId?: string,
    @Query('estado') estado?: string,
    @Query('desde') desde?: string,
    @Query('hasta') hasta?: string,
    @Query('skip') skip?: string,
    @Query('take') take?: string,
  ) {
    return this.service.listar(user.empresa_id, {
      periodoId,
      estado,
      desde,
      hasta,
      skip: skip ? parseInt(skip) : 0,
      take: take ? parseInt(take) : 50,
    });
  }

  @Get(':id')
  @RequirePermission('CONTABILIDAD', 'CONT_ASI_ASIENTO_VER')
  @ApiOperation({ summary: 'Ver asiento con detalle de líneas' })
  getById(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.getById(id, user.empresa_id);
  }

  @Post()
  @RequirePermission('CONTABILIDAD', 'CONT_ASI_ASIENTO_CREAR')
  @ApiOperation({ summary: 'Crear asiento en borrador' })
  crear(@GetUser() user: LoginUserInfo, @Body() body: CrearAsientoDto) {
    return this.service.crear(user.empresa_id, user.id, body);
  }

  @Put(':id')
  @RequirePermission('CONTABILIDAD', 'CONT_ASI_ASIENTO_EDITAR')
  @ApiOperation({ summary: 'Editar asiento BORRADOR (reemplaza líneas, revalida partida doble)' })
  editar(@Param('id') id: string, @GetUser() user: LoginUserInfo, @Body() body: EditarAsientoDto) {
    return this.service.editar(id, user.empresa_id, user.id, body);
  }

  @Patch(':id/confirmar')
  @RequirePermission('CONTABILIDAD', 'CONT_ASI_ASIENTO_CONFIRMAR')
  @ApiOperation({ summary: 'Confirmar asiento (valida partida doble y período abierto)' })
  confirmar(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.confirmar(id, user.empresa_id);
  }

  @Post(':id/revertir')
  @RequirePermission('CONTABILIDAD', 'CONT_ASI_ASIENTO_REVERTIR')
  @ApiOperation({ summary: 'Revertir asiento confirmado (genera asiento espejo)' })
  revertir(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.revertir(id, user.empresa_id, user.id);
  }

  @Post(':id/corregir')
  @RequirePermission('CONTABILIDAD', 'CONT_ASI_ASIENTO_REVERTIR')
  @ApiOperation({ summary: 'Corregir asiento: lo revierte y devuelve los datos originales para crear uno nuevo' })
  corregir(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.corregir(id, user.empresa_id, user.id);
  }

  @Delete(':id')
  @RequirePermission('CONTABILIDAD', 'CONT_ASI_ASIENTO_ELIMINAR')
  @ApiOperation({ summary: 'Eliminar asiento BORRADOR (irreversible)' })
  eliminar(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.eliminar(id, user.empresa_id, user.id);
  }
}
