import {
  Body,
  Controller,
  Get,
  Param,
  ParseUUIDPipe,
  Post,
  Put,
  Query,
  UploadedFile,
  UseGuards,
  UseInterceptors,
  ValidationPipe,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { FileInterceptor } from '@nestjs/platform-express';
import { ApiBearerAuth, ApiConsumes, ApiOperation, ApiQuery, ApiTags } from '@nestjs/swagger';
import { inm_inusual_estado, inm_inusual_regla, inm_legajo_estado, inm_nivel_riesgo } from '@prisma/client';
import { RequirePermission } from 'src/auth/decorators/require-permission.decorator';
import { RequireSubmodulo } from 'src/auth/decorators/require-submodulo.decorator';
import type { LoginUserInfo } from 'src/auth/dto/login.dto';
import { GetUser } from 'src/auth/get-user.decorator';
import { PermissionGuard } from 'src/auth/guards/permission.guard';
import { SubmoduloGuard } from 'src/auth/guards/submodulo.guard';
import {
  CrearInusualDto,
  GestionarInusualDto,
  GuardarLegajoDto,
  MotivoCumplimientoDto,
  SubirDocumentoLegajoDto,
} from './dto/cumplimiento.dto';
import { InusualesInmService } from './inusuales.service';
import { LegajosClienteInmService, MAX_DOCUMENTO_BYTES } from './legajos-cliente.service';

@ApiTags('Inmobiliario · Cumplimiento')
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), SubmoduloGuard)
@RequireSubmodulo('INM_CUMPLIMIENTO')
@Controller({ path: 'inmobiliario/cumplimiento', version: '1' })
export class CumplimientoInmController {
  constructor(
    private readonly legajos: LegajosClienteInmService,
    private readonly inusuales: InusualesInmService,
  ) {}

  @Get('resumen')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_CUM_LEGAJO_VER')
  @ApiOperation({ summary: 'Tablero del oficial de cumplimiento' })
  resumen(@GetUser() user: LoginUserInfo) {
    return this.legajos.resumen(user.empresa_id);
  }

  @Get('legajos')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_CUM_LEGAJO_VER')
  @ApiQuery({ name: 'estado', required: false, enum: inm_legajo_estado })
  @ApiQuery({ name: 'riesgo', required: false, enum: inm_nivel_riesgo })
  @ApiQuery({ name: 'vencidos', required: false, type: Boolean })
  @ApiQuery({ name: 'q', required: false })
  listarLegajos(
    @GetUser() user: LoginUserInfo,
    @Query('estado') estado?: inm_legajo_estado,
    @Query('riesgo') riesgo?: inm_nivel_riesgo,
    @Query('vencidos') vencidos?: string,
    @Query('q') q?: string,
  ) {
    return this.legajos.listar(user.empresa_id, { estado, riesgo, vencidos: vencidos === 'true', q });
  }

  @Get('legajos/cliente/:clienteId')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_CUM_LEGAJO_VER')
  @ApiOperation({ summary: 'Legajo del cliente (null si no tiene), documentos, operaciones y antecedentes' })
  legajo(@Param('clienteId', ParseUUIDPipe) clienteId: string, @GetUser() user: LoginUserInfo) {
    return this.legajos.delCliente(clienteId, user.empresa_id);
  }

  @Put('legajos/cliente/:clienteId')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_CUM_LEGAJO_EDITAR')
  guardar(
    @Param('clienteId', ParseUUIDPipe) clienteId: string,
    @Body(ValidationPipe) dto: GuardarLegajoDto,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.legajos.guardar(clienteId, dto, user.empresa_id, user.id);
  }

  @Post('legajos/cliente/:clienteId/aprobar')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_CUM_LEGAJO_APROBAR')
  aprobar(@Param('clienteId', ParseUUIDPipe) clienteId: string, @GetUser() user: LoginUserInfo) {
    return this.legajos.aprobar(clienteId, user.empresa_id, user.id);
  }

  @Post('legajos/cliente/:clienteId/observar')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_CUM_LEGAJO_APROBAR')
  observar(
    @Param('clienteId', ParseUUIDPipe) clienteId: string,
    @Body(ValidationPipe) dto: MotivoCumplimientoDto,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.legajos.observar(clienteId, dto, user.empresa_id, user.id);
  }

  @Post('legajos/cliente/:clienteId/documentos')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_CUM_LEGAJO_EDITAR')
  @UseInterceptors(FileInterceptor('archivo', { limits: { fileSize: MAX_DOCUMENTO_BYTES } }))
  @ApiConsumes('multipart/form-data')
  subirDocumento(
    @Param('clienteId', ParseUUIDPipe) clienteId: string,
    @Body(ValidationPipe) dto: SubirDocumentoLegajoDto,
    @UploadedFile() archivo: Express.Multer.File,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.legajos.subirDocumento(clienteId, dto, archivo, user.empresa_id, user.id);
  }

  @Get('legajos/documentos/:id/url')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_CUM_LEGAJO_VER')
  @ApiOperation({ summary: 'URL firmada (10 minutos) para ver el documento' })
  urlDocumento(@Param('id', ParseUUIDPipe) id: string, @GetUser() user: LoginUserInfo) {
    return this.legajos.urlDocumento(id, user.empresa_id);
  }

  @Post('legajos/documentos/:id/anular')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_CUM_LEGAJO_EDITAR')
  anularDocumento(
    @Param('id', ParseUUIDPipe) id: string,
    @Body(ValidationPipe) dto: MotivoCumplimientoDto,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.legajos.anularDocumento(id, dto, user.empresa_id, user.id);
  }

  @Get('inusuales')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_CUM_INUSUAL_VER')
  @ApiQuery({ name: 'estado', required: false, enum: inm_inusual_estado })
  @ApiQuery({ name: 'regla', required: false, enum: inm_inusual_regla })
  @ApiQuery({ name: 'cliente_id', required: false })
  @ApiQuery({ name: 'abiertas', required: false, type: Boolean })
  listarInusuales(
    @GetUser() user: LoginUserInfo,
    @Query('estado') estado?: inm_inusual_estado,
    @Query('regla') regla?: inm_inusual_regla,
    @Query('cliente_id') cliente_id?: string,
    @Query('abiertas') abiertas?: string,
  ) {
    return this.inusuales.listar(user.empresa_id, { estado, regla, cliente_id, abiertas: abiertas === 'true' });
  }

  @Get('inusuales/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_CUM_INUSUAL_VER')
  inusual(@Param('id', ParseUUIDPipe) id: string, @GetUser() user: LoginUserInfo) {
    return this.inusuales.detalle(id, user.empresa_id);
  }

  @Post('inusuales')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_CUM_INUSUAL_CREAR')
  crearInusual(@Body(ValidationPipe) dto: CrearInusualDto, @GetUser() user: LoginUserInfo) {
    return this.inusuales.crearManual(dto, user.empresa_id, user.id);
  }

  @Post('inusuales/:id/gestionar')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_CUM_INUSUAL_GESTIONAR')
  @ApiOperation({ summary: 'Pasar a análisis, descartar o registrar el ROS presentado' })
  gestionar(
    @Param('id', ParseUUIDPipe) id: string,
    @Body(ValidationPipe) dto: GestionarInusualDto,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.inusuales.gestionar(id, dto, user.empresa_id, user.id);
  }
}
