import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  Patch,
  Post,
  Query,
  UseGuards,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
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 { SincronizarRelojDto } from '../dto/marcaciones.dto';
import {
  CreateRelojDto,
  QueryRelojesDto,
  UpdateRelojDto,
} from '../dto/relojes.dto';
import { RelojesMarcadoresService } from '../services/relojes-marcadores.service';

@ApiTags('RRHH - Presentismo - Relojes')
@Controller({ path: 'rrhh/presentismo/relojes', version: '1' })
@UseGuards(AuthGuard('jwt'), ModuleGuard, PermissionGuard)
@RequireModule('RRHH')
@ApiBearerAuth()
export class RelojesMarcadoresController {
  constructor(private readonly service: RelojesMarcadoresService) {}

  @Get()
  @RequirePermission('RRHH', 'RH_MAR_MARCACION_VER')
  @ApiOperation({ summary: 'Listar relojes marcadores con filtros y paginación' })
  listar(@GetUser() user: LoginUserInfo, @Query() query: QueryRelojesDto) {
    return this.service.listar(user.empresa_id, query);
  }

  @Get(':id')
  @RequirePermission('RRHH', 'RH_MAR_MARCACION_VER')
  @ApiOperation({ summary: 'Obtener detalle de un reloj marcador' })
  obtener(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.obtener(id, user.empresa_id);
  }

  @Post()
  @RequirePermission('RRHH', 'RH_MAR_MARCACION_CREAR')
  @ApiOperation({
    summary: 'Registrar un reloj marcador (API o PLANILLA)',
    description:
      'La api_key se almacena cifrada con AES-256-CBC usando AI_ENCRYPTION_KEY. La respuesta NUNCA devuelve la credencial en claro.',
  })
  crear(@GetUser() user: LoginUserInfo, @Body() dto: CreateRelojDto) {
    return this.service.crear(user.empresa_id, dto, user.id);
  }

  @Patch(':id')
  @RequirePermission('RRHH', 'RH_MAR_MARCACION_EDITAR')
  @ApiOperation({ summary: 'Actualizar configuración de un reloj marcador' })
  actualizar(
    @Param('id') id: string,
    @GetUser() user: LoginUserInfo,
    @Body() dto: UpdateRelojDto,
  ) {
    return this.service.actualizar(id, user.empresa_id, dto);
  }

  @Delete(':id')
  @RequirePermission('RRHH', 'RH_MAR_MARCACION_ELIMINAR')
  @ApiOperation({
    summary: 'Eliminar reloj marcador',
    description:
      'Si el reloj tiene marcaciones cargadas no se elimina: se desactiva para no perder trazabilidad.',
  })
  eliminar(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.eliminar(id, user.empresa_id);
  }

  @Post(':id/sincronizar')
  @RequirePermission('RRHH', 'RH_MAR_MARCACION_CREAR')
  @ApiOperation({
    summary: 'Ejecutar sincronización manual con el reloj API',
    description:
      'Consulta el endpoint del reloj, ingiere las marcaciones recibidas en raw y ' +
      'ejecuta deduplicación. Devuelve el resumen del lote (batch_importacion_id, ' +
      'totales, errores y dedup).',
  })
  sincronizar(
    @Param('id') id: string,
    @GetUser() user: LoginUserInfo,
    @Body() body: SincronizarRelojDto,
  ) {
    return this.service.sincronizar(id, user.empresa_id, {
      desde: body.desde ? new Date(body.desde) : undefined,
      hasta: body.hasta ? new Date(body.hasta) : undefined,
      userId: user.id,
    });
  }
}
