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 {
  AsignarTurnoDto,
  CreateTurnoDto,
  QueryAsignacionesDto,
  QueryTurnosDto,
  UpdateTurnoDto,
} from '../dto/turnos.dto';
import { QueryEmpleadosDto } from '../dto/query-empleados.dto';
import { TurnosService } from '../services/turnos.service';

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

  // ────────── Catálogo de turnos ──────────────────────────────────

  @Get('turnos')
  @RequirePermission('RRHH', 'RH_TUR_TURNO_VER')
  @ApiOperation({ summary: 'Listar turnos con sus bloques horarios' })
  listar(@GetUser() user: LoginUserInfo, @Query() query: QueryTurnosDto) {
    return this.service.listar(user.empresa_id, query);
  }

  @Get('turnos/:id')
  @RequirePermission('RRHH', 'RH_TUR_TURNO_VER')
  @ApiOperation({ summary: 'Obtener un turno con sus bloques' })
  obtener(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.obtener(id, user.empresa_id);
  }

  @Post('turnos')
  @RequirePermission('RRHH', 'RH_TUR_TURNO_CREAR')
  @ApiOperation({
    summary: 'Crear turno con sus bloques horarios',
    description:
      'SIMPLE → exactamente 1 bloque. CORTADO → 2+ bloques sin solapamiento (hora_entrada N+1 > hora_salida N).',
  })
  crear(@GetUser() user: LoginUserInfo, @Body() dto: CreateTurnoDto) {
    return this.service.crear(user.empresa_id, dto, user.id);
  }

  @Patch('turnos/:id')
  @RequirePermission('RRHH', 'RH_TUR_TURNO_EDITAR')
  @ApiOperation({
    summary: 'Actualizar turno y/o sus bloques',
    description: 'Si se envían bloques, reemplazan en su totalidad a los existentes.',
  })
  actualizar(
    @Param('id') id: string,
    @GetUser() user: LoginUserInfo,
    @Body() dto: UpdateTurnoDto,
  ) {
    return this.service.actualizar(id, user.empresa_id, dto);
  }

  @Delete('turnos/:id')
  @RequirePermission('RRHH', 'RH_TUR_TURNO_ELIMINAR')
  @ApiOperation({
    summary: 'Eliminar turno',
    description:
      'Si el turno tiene asignaciones o novedades históricas, no se elimina: se desactiva para preservar trazabilidad.',
  })
  eliminar(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.eliminar(id, user.empresa_id);
  }

  @Get('empleados')
  @RequirePermission('RRHH', 'RH_EMP_EMPLEADO_VER')
  @ApiOperation({ summary: 'Catálogo de empleados para flujos de presentismo' })
  listarEmpleadosCatalogo(@GetUser() user: LoginUserInfo, @Query() query: QueryEmpleadosDto) {
    return this.service.listarEmpleadosCatalogo(user.empresa_id, query);
  }

  // ────────── Asignaciones empleado ↔ turno ───────────────────────

  @Get('empleados/:empleadoId/turnos')
  @RequirePermission('RRHH', 'RH_TUR_TURNO_VER')
  @ApiOperation({
    summary: 'Listar asignaciones de turno de un funcionario',
    description: 'Filtrar por tipo (PERPETUA / OCASIONAL) y/o por fecha vigente.',
  })
  listarAsignacionesDeEmpleado(
    @Param('empleadoId') empleadoId: string,
    @GetUser() user: LoginUserInfo,
    @Query() query: QueryAsignacionesDto,
  ) {
    return this.service.listarAsignacionesDeEmpleado(empleadoId, user.empresa_id, query);
  }

  @Post('empleados/:empleadoId/turnos')
  @RequirePermission('RRHH', 'RH_TUR_TURNO_CREAR')
  @ApiOperation({
    summary: 'Asignar un turno a un funcionario',
    description:
      'PERPETUA: vigencia indefinida (fecha_fin debe ser null). ' +
      'OCASIONAL: requiere fecha_inicio y fecha_fin; HTTP 409 si solapa con otra ocasional de igual prioridad.',
  })
  asignar(
    @Param('empleadoId') empleadoId: string,
    @GetUser() user: LoginUserInfo,
    @Body() dto: AsignarTurnoDto,
  ) {
    return this.service.asignar(empleadoId, user.empresa_id, dto, user.id);
  }

  @Delete('empleados/:empleadoId/turnos/:asignId')
  @RequirePermission('RRHH', 'RH_TUR_TURNO_ELIMINAR')
  @ApiOperation({ summary: 'Eliminar una asignación de turno' })
  eliminarAsignacion(
    @Param('empleadoId') empleadoId: string,
    @Param('asignId') asignId: string,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.service.eliminarAsignacion(asignId, empleadoId, user.empresa_id);
  }
}
