import { Body, Controller, Delete, Get, Param, Patch, Post, Query, UseGuards, ValidationPipe } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiOperation, ApiQuery, ApiTags } from '@nestjs/swagger';
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 { CatalogosService } from './catalogos.service';
import {
  CreateCalendarioDto, CreateMotivoDto, CreateOrigenDto, CreateSlaDto,
  UpdateCalendarioDto, UpdateMotivoDto, UpdateOrigenDto, UpdateSlaDto,
} from './dto/catalogos.dto';

/**
 * Los cuatro catálogos que sembró CRM-04. Todas las bajas son lógicas: lo
 * histórico sigue apuntando a ellos.
 */
@ApiTags('CRM · Catálogos')
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), SubmoduloGuard)
@RequireSubmodulo('CRM_CONFIG')
@Controller({ path: 'crm/catalogos', version: '1' })
export class CatalogosController {
  constructor(private readonly service: CatalogosService) {}

  // ── Orígenes ────────────────────────────────────────────────────────────────

  @Get('origenes')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_CATALOGO_VER')
  @ApiQuery({ name: 'activos', required: false, description: 'true devuelve sólo los activos (para selects)' })
  findOrigenes(@GetUser() user: LoginUserInfo, @Query('activos') activos?: string) {
    return this.service.findOrigenes(user.empresa_id, activos === 'true');
  }

  @Post('origenes')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_CATALOGO_CREAR')
  @ApiOperation({
    summary: 'Crea un origen',
    description: 'Si el código existe pero está dado de baja, lo reactiva en vez de fallar.',
  })
  createOrigen(@Body(ValidationPipe) dto: CreateOrigenDto, @GetUser() user: LoginUserInfo) {
    return this.service.createOrigen(dto, user.empresa_id, user.id);
  }

  @Patch('origenes/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_CATALOGO_EDITAR')
  @ApiOperation({ summary: 'Edita un origen', description: 'El código no se cambia: es lo que agrupan los reportes.' })
  updateOrigen(@Param('id') id: string, @Body(ValidationPipe) dto: UpdateOrigenDto, @GetUser() user: LoginUserInfo) {
    return this.service.updateOrigen(id, dto, user.empresa_id, user.id);
  }

  @Delete('origenes/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_CATALOGO_ELIMINAR')
  @ApiOperation({ summary: 'Da de baja un origen (lógica)' })
  removeOrigen(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.removeOrigen(id, user.empresa_id, user.id);
  }

  // ── Motivos ─────────────────────────────────────────────────────────────────

  @Get('motivos')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_CATALOGO_VER')
  @ApiQuery({ name: 'tipo', required: false, description: 'perdida | descarte | churn' })
  @ApiQuery({ name: 'activos', required: false })
  findMotivos(@GetUser() user: LoginUserInfo, @Query('tipo') tipo?: string, @Query('activos') activos?: string) {
    return this.service.findMotivos(user.empresa_id, tipo, activos === 'true');
  }

  @Post('motivos')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_CATALOGO_CREAR')
  createMotivo(@Body(ValidationPipe) dto: CreateMotivoDto, @GetUser() user: LoginUserInfo) {
    return this.service.createMotivo(dto, user.empresa_id, user.id);
  }

  @Patch('motivos/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_CATALOGO_EDITAR')
  @ApiOperation({ summary: 'Edita un motivo', description: 'El tipo no se cambia: dejaría registros históricos mal clasificados.' })
  updateMotivo(@Param('id') id: string, @Body(ValidationPipe) dto: UpdateMotivoDto, @GetUser() user: LoginUserInfo) {
    return this.service.updateMotivo(id, dto, user.empresa_id, user.id);
  }

  @Delete('motivos/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_CATALOGO_ELIMINAR')
  removeMotivo(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.removeMotivo(id, user.empresa_id, user.id);
  }

  // ── Calendarios ─────────────────────────────────────────────────────────────

  @Get('calendarios')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_CATALOGO_VER')
  findCalendarios(@GetUser() user: LoginUserInfo) {
    return this.service.findCalendarios(user.empresa_id);
  }

  @Post('calendarios')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_CATALOGO_CREAR')
  createCalendario(@Body(ValidationPipe) dto: CreateCalendarioDto, @GetUser() user: LoginUserInfo) {
    return this.service.createCalendario(dto, user.empresa_id, user.id);
  }

  @Patch('calendarios/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_CATALOGO_EDITAR')
  updateCalendario(@Param('id') id: string, @Body(ValidationPipe) dto: UpdateCalendarioDto, @GetUser() user: LoginUserInfo) {
    return this.service.updateCalendario(id, dto, user.empresa_id, user.id);
  }

  @Delete('calendarios/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_CATALOGO_ELIMINAR')
  @ApiOperation({
    summary: 'Da de baja un calendario',
    description: 'Rechaza si es el default o si lo usan políticas de SLA activas: el reloj quedaría sin horario.',
  })
  removeCalendario(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.removeCalendario(id, user.empresa_id, user.id);
  }

  // ── Políticas de SLA ────────────────────────────────────────────────────────

  @Get('sla')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_CATALOGO_VER')
  findSla(@GetUser() user: LoginUserInfo) {
    return this.service.findSla(user.empresa_id);
  }

  @Post('sla')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_CATALOGO_CREAR')
  createSla(@Body(ValidationPipe) dto: CreateSlaDto, @GetUser() user: LoginUserInfo) {
    return this.service.createSla(dto, user.empresa_id, user.id);
  }

  @Patch('sla/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_CATALOGO_EDITAR')
  updateSla(@Param('id') id: string, @Body(ValidationPipe) dto: UpdateSlaDto, @GetUser() user: LoginUserInfo) {
    return this.service.updateSla(id, dto, user.empresa_id, user.id);
  }

  @Delete('sla/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_CATALOGO_ELIMINAR')
  removeSla(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.removeSla(id, user.empresa_id, user.id);
  }
}
