import { Body, Controller, Get, Param, Patch, Post, Query, Res, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
import type { Response } from 'express';
import { RequireModule } from '../../auth/decorators/require-module.decorator';
import { RequirePermission } from '../../auth/decorators/require-permission.decorator';
import type { LoginUserInfo } from '../../auth/dto/login.dto';
import { GetUser } from '../../auth/get-user.decorator';
import { ModuleGuard } from '../../auth/guards/module.guard';
import { PermissionGuard } from '../../auth/guards/permission.guard';
import {
  AnularAcreditacionDto,
  GenerarAcreditacionDto,
  MarcarConfirmadoDto,
  MarcarEnviadoDto,
  QueryAcreditacionesDto,
} from '../dto/acreditaciones-bancarias.dto';
import { AcreditacionesBancariasService } from '../services/acreditaciones-bancarias.service';

@ApiTags('RRHH - Acreditaciones bancarias')
@Controller({ path: 'rrhh/acreditaciones-bancarias', version: '1' })
@UseGuards(AuthGuard('jwt'), ModuleGuard, PermissionGuard)
@RequireModule('RRHH')
@ApiBearerAuth()
export class AcreditacionesBancariasController {
  constructor(private readonly service: AcreditacionesBancariasService) {}

  @Get()
  @RequirePermission('RRHH', 'RH_BAN_ACREDITACION_VER')
  @ApiOperation({ summary: 'Listar acreditaciones generadas' })
  listar(@GetUser() user: LoginUserInfo, @Query() query: QueryAcreditacionesDto) {
    return this.service.listar(user.empresa_id, query);
  }

  @Get(':id')
  @RequirePermission('RRHH', 'RH_BAN_ACREDITACION_VER')
  @ApiOperation({ summary: 'Obtener acreditación con detalles' })
  obtener(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.obtener(id, user.empresa_id);
  }

  @Post()
  @RequirePermission('RRHH', 'RH_BAN_ACREDITACION_GENERAR')
  @ApiOperation({
    summary: 'Generar archivo de acreditación desde liquidación CERRADA + banco',
    description:
      'Filtra empleados con cuenta del banco indicado y neto > 0. Aplica el template del formato activo del banco (o uno específico) y persiste el contenido para re-descargar.',
  })
  generar(@GetUser() user: LoginUserInfo, @Body() dto: GenerarAcreditacionDto) {
    return this.service.generar(user.empresa_id, dto, user.id);
  }

  @Get(':id/descargar')
  @RequirePermission('RRHH', 'RH_BAN_ACREDITACION_GENERAR')
  @ApiOperation({ summary: 'Descargar el archivo (txt/csv según extensión del formato)' })
  async descargar(@Param('id') id: string, @GetUser() user: LoginUserInfo, @Res() res: Response) {
    const { nombre, contenido, encoding } = await this.service.descargarArchivo(id, user.empresa_id);
    res.setHeader('Content-Type', `text/plain; charset=${encoding}`);
    res.setHeader('Content-Disposition', `attachment; filename="${nombre}"`);
    res.send(contenido);
  }

  @Patch(':id/enviar')
  @RequirePermission('RRHH', 'RH_BAN_ACREDITACION_GENERAR')
  @ApiOperation({ summary: 'Marcar como ENVIADO al banco' })
  enviar(@Param('id') id: string, @GetUser() user: LoginUserInfo, @Body() dto: MarcarEnviadoDto) {
    return this.service.marcarEnviado(id, user.empresa_id, dto);
  }

  @Patch(':id/confirmar')
  @RequirePermission('RRHH', 'RH_BAN_ACREDITACION_GENERAR')
  @ApiOperation({ summary: 'Marcar como CONFIRMADO (banco acreditó)' })
  confirmar(
    @Param('id') id: string,
    @GetUser() user: LoginUserInfo,
    @Body() dto: MarcarConfirmadoDto,
  ) {
    return this.service.marcarConfirmado(id, user.empresa_id, dto, user.id);
  }

  @Patch(':id/anular')
  @RequirePermission('RRHH', 'RH_BAN_ACREDITACION_GENERAR')
  @ApiOperation({ summary: 'Anular acreditación (no permitido si está CONFIRMADA)' })
  anular(
    @Param('id') id: string,
    @GetUser() user: LoginUserInfo,
    @Body() dto: AnularAcreditacionDto,
  ) {
    return this.service.anular(id, user.empresa_id, dto, user.id);
  }
}
