import { Body, Controller, Delete, Get, Param, ParseUUIDPipe, Post, Put, Query, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiOperation, 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 { GuardarReglaMapeoDto, OrdenReglasDto, ProbadorReglaDto, RetirarReglaDto } from '../dto/regla-mapeo.dto';
import { ReglasMapeoService } from '../services/reglas-mapeo.service';

/** Reglas de cuenta por dimensión (spec 2026-10-13). Mismos permisos que el mapeo. */
@ApiTags('Contabilidad - Reglas de Mapeo')
@Controller({ path: 'contabilidad/mapeo-reglas', version: '1' })
@UseGuards(AuthGuard('jwt'), PermissionGuard)
@ApiBearerAuth()
export class ReglasMapeoController {
  constructor(private readonly service: ReglasMapeoService) {}

  @Get()
  @RequirePermission('CONTABILIDAD', 'CONT_MAP_MAPEO_VER')
  @ApiOperation({ summary: 'Reglas de la empresa (de un concepto, si se indica), con su frase y constancia' })
  listar(@GetUser() user: LoginUserInfo, @Query('concepto') concepto?: string) {
    return this.service.listar(user.empresa_id, concepto || undefined);
  }

  @Get('dimensiones')
  @RequirePermission('CONTABILIDAD', 'CONT_MAP_MAPEO_VER')
  @ApiOperation({ summary: 'Qué dimensiones publica cada documento y los valores que se pueden elegir' })
  dimensiones(@GetUser() user: LoginUserInfo) {
    return this.service.dimensiones(user.empresa_id);
  }

  @Post('probador')
  @RequirePermission('CONTABILIDAD', 'CONT_MAP_MAPEO_VER')
  @ApiOperation({ summary: '¿Qué cuenta usaría? Resuelve el concepto con los valores elegidos y muestra la traza' })
  probador(@GetUser() user: LoginUserInfo, @Body() dto: ProbadorReglaDto) {
    return this.service.probador(user.empresa_id, dto);
  }

  @Post()
  @RequirePermission('CONTABILIDAD', 'CONT_MAP_MAPEO_EDITAR')
  @ApiOperation({ summary: 'Crear una regla (queda en borrador)' })
  crear(@GetUser() user: LoginUserInfo, @Body() dto: GuardarReglaMapeoDto) {
    return this.service.crear(user.empresa_id, user.id, dto);
  }

  // Antes de `:id`: si no, "orden" se tomaría como id.
  @Put('orden')
  @RequirePermission('CONTABILIDAD', 'CONT_MAP_MAPEO_EDITAR')
  @ApiOperation({ summary: 'Reordenar las reglas de un concepto: { concepto, ids } → orden 1..n' })
  reordenar(@GetUser() user: LoginUserInfo, @Body() dto: OrdenReglasDto) {
    return this.service.reordenar(user.empresa_id, user.id, dto);
  }

  @Put(':id')
  @RequirePermission('CONTABILIDAD', 'CONT_MAP_MAPEO_EDITAR')
  @ApiOperation({ summary: 'Editar una regla en borrador (una activa se retira y se crea otra)' })
  editar(@GetUser() user: LoginUserInfo, @Param('id', ParseUUIDPipe) id: string, @Body() dto: GuardarReglaMapeoDto) {
    return this.service.editar(user.empresa_id, user.id, id, dto);
  }

  @Post(':id/activar')
  @RequirePermission('CONTABILIDAD', 'CONT_MAP_MAPEO_EDITAR')
  @ApiOperation({ summary: 'Activar una regla: desde ahí se aplica en los asientos (deja constancia)' })
  activar(@GetUser() user: LoginUserInfo, @Param('id', ParseUUIDPipe) id: string) {
    return this.service.activar(user.empresa_id, user.id, id);
  }

  @Post(':id/retirar')
  @RequirePermission('CONTABILIDAD', 'CONT_MAP_MAPEO_EDITAR')
  @ApiOperation({ summary: 'Retirar una regla: cierra su vigencia (hoy o la fecha indicada), no la borra; informa cuántos asientos con la regla quedan desde esa fecha' })
  retirar(@GetUser() user: LoginUserInfo, @Param('id', ParseUUIDPipe) id: string, @Body() dto: RetirarReglaDto) {
    return this.service.retirar(user.empresa_id, user.id, id, { vigenteHasta: dto?.vigenteHasta });
  }

  @Delete(':id')
  @RequirePermission('CONTABILIDAD', 'CONT_MAP_MAPEO_EDITAR')
  @ApiOperation({ summary: 'Borrar una regla que nunca estuvo activa' })
  borrar(@GetUser() user: LoginUserInfo, @Param('id', ParseUUIDPipe) id: string) {
    return this.service.borrar(user.empresa_id, user.id, id);
  }
}
