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 {
  ActualizarDetalleIpsDto,
  AnularReporteIpsDto,
  GenerarReporteIpsDto,
  MarcarDeclaradoDto,
  MarcarPagadoDto,
  QueryReportesIpsDto,
} from '../dto/reportes-ips.dto';
import { ReportesIpsService } from '../services/reportes-ips.service';

@ApiTags('RRHH - Reportes IPS / REOP')
@Controller({ path: 'rrhh/reportes-ips', version: '1' })
@UseGuards(AuthGuard('jwt'), ModuleGuard, PermissionGuard)
@RequireModule('RRHH')
@ApiBearerAuth()
export class ReportesIpsController {
  constructor(private readonly service: ReportesIpsService) {}

  @Get()
  @RequirePermission('RRHH', 'RH_IPS_IPS_VER')
  @ApiOperation({ summary: 'Listar reportes IPS / REOP' })
  listar(@GetUser() user: LoginUserInfo, @Query() query: QueryReportesIpsDto) {
    return this.service.listar(user.empresa_id, query);
  }

  @Get(':id')
  @RequirePermission('RRHH', 'RH_IPS_IPS_VER')
  @ApiOperation({ summary: 'Detalle de reporte (con líneas por empleado)' })
  obtener(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.obtener(id, user.empresa_id);
  }

  @Post()
  @RequirePermission('RRHH', 'RH_IPS_IPS_GENERAR')
  @ApiOperation({
    summary: 'Generar reporte IPS desde una liquidación mensual CERRADA',
    description:
      'Toma los resúmenes con aporte_obrero > 0 de la liquidación y consolida totales (base aportable, obrero 9%, patronal 16.5%, admin 1%, total a depositar) ' +
      'y una fila de detalle por empleado para el archivo REOP.',
  })
  generar(@GetUser() user: LoginUserInfo, @Body() dto: GenerarReporteIpsDto) {
    return this.service.generar(user.empresa_id, dto, user.id);
  }

  @Patch(':id/declarar')
  @RequirePermission('RRHH', 'RH_IPS_IPS_GENERAR')
  @ApiOperation({ summary: 'Marcar como DECLARADO (registrar fecha de declaración al IPS)' })
  declarar(@Param('id') id: string, @GetUser() user: LoginUserInfo, @Body() dto: MarcarDeclaradoDto) {
    return this.service.marcarDeclarado(id, user.empresa_id, dto);
  }

  @Patch(':id/pagar')
  @RequirePermission('RRHH', 'RH_IPS_IPS_GENERAR')
  @ApiOperation({ summary: 'Marcar como PAGADO (registrar fecha de pago y comprobante)' })
  pagar(@Param('id') id: string, @GetUser() user: LoginUserInfo, @Body() dto: MarcarPagadoDto) {
    return this.service.marcarPagado(id, user.empresa_id, dto, user.id);
  }

  @Patch(':id/detalle/:detalleId')
  @RequirePermission('RRHH', 'RH_IPS_IPS_GENERAR')
  @ApiOperation({ summary: 'Actualizar días trabajados de una fila del detalle (solo en estado GENERADO)' })
  actualizarDetalle(
    @Param('id') id: string,
    @Param('detalleId') detalleId: string,
    @GetUser() user: LoginUserInfo,
    @Body() dto: ActualizarDetalleIpsDto,
  ) {
    return this.service.actualizarDetalle(id, detalleId, dto, user.empresa_id);
  }

  @Patch(':id/anular')
  @RequirePermission('RRHH', 'RH_IPS_IPS_GENERAR')
  @ApiOperation({ summary: 'Anular reporte (solo si no fue pagado)' })
  anular(
    @Param('id') id: string,
    @GetUser() user: LoginUserInfo,
    @Body() dto: AnularReporteIpsDto,
  ) {
    return this.service.anular(id, user.empresa_id, dto, user.id);
  }

  @Get(':id/reop')
  @RequirePermission('RRHH', 'RH_IPS_IPS_EXPORTAR')
  @ApiOperation({ summary: 'Descargar archivo REOP en formato Excel (.xlsx)' })
  async descargarReop(
    @Param('id') id: string,
    @GetUser() user: LoginUserInfo,
    @Res() res: Response,
  ) {
    const { buffer, filename } = await this.service.generarArchivoReop(id, user.empresa_id);
    res.setHeader(
      'Content-Type',
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    );
    res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
    res.send(buffer);
  }
}
