import { Body, Controller, Delete, Get, Param, Patch, Post, Put, Query, UseGuards, ValidationPipe } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiBody, ApiOperation, ApiQuery, ApiTags } from '@nestjs/swagger';
import { RequireSubmodulo } from 'src/auth/decorators/require-submodulo.decorator';
import { RequirePermission } from 'src/auth/decorators/require-permission.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 { CrmSeedService } from '../seeds/crm-seed.service';
import { CrmConfigService } from './crm-config.service';
import { CreateEtapaDto } from './dto/create-etapa.dto';
import { CreatePipelineDto } from './dto/create-pipeline.dto';
import { ReordenarEtapasDto } from './dto/reordenar-etapas.dto';
import { UpdateEtapaDto } from './dto/update-etapa.dto';
import { UpdatePipelineDto } from './dto/update-pipeline.dto';

@ApiTags('CRM · Configuración')
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), SubmoduloGuard)
@RequireSubmodulo('CRM_CONFIG')
@Controller({ path: 'crm/config', version: '1' })
export class CrmConfigController {
  constructor(
    private readonly configService: CrmConfigService,
    private readonly seedService: CrmSeedService,
  ) {}

  @Post('seed')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_CONFIG_SEMBRAR')
  @ApiOperation({
    summary: 'Siembra la configuración por defecto que falte',
    description:
      'Idempotente: agrega sólo lo que no existe y nunca pisa lo que el cliente cambió. ' +
      'Sirve para re-sembrar después de que una versión agregue catálogos nuevos.',
  })
  sembrar(@GetUser() user: LoginUserInfo) {
    return this.seedService.asegurarConfiguracion(user.empresa_id, user.id);
  }

  // --------------------------------------------------------------- pipelines

  @Get('pipelines')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_PIPELINE_VER')
  @ApiOperation({ summary: 'Pipelines de la empresa con sus etapas activas' })
  @ApiQuery({ name: 'solo_activos', required: false, description: 'true para excluir los dados de baja' })
  findAllPipelines(@GetUser() user: LoginUserInfo, @Query('solo_activos') soloActivos?: string) {
    return this.configService.findAllPipelines(user.empresa_id, soloActivos === 'true');
  }

  @Post('pipelines')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_PIPELINE_CREAR')
  @ApiBody({ type: CreatePipelineDto })
  createPipeline(@Body(ValidationPipe) dto: CreatePipelineDto, @GetUser() user: LoginUserInfo) {
    return this.configService.createPipeline(dto, user.empresa_id, user.id);
  }

  @Patch('pipelines/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_PIPELINE_EDITAR')
  @ApiBody({ type: UpdatePipelineDto })
  updatePipeline(
    @Param('id') id: string,
    @Body(ValidationPipe) dto: UpdatePipelineDto,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.configService.updatePipeline(id, dto, user.empresa_id, user.id);
  }

  @Delete('pipelines/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_PIPELINE_ELIMINAR')
  @ApiOperation({ summary: 'Baja lógica del pipeline: nunca se borra, queda inactivo' })
  removePipeline(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.configService.removePipeline(id, user.empresa_id, user.id);
  }

  // ------------------------------------------------------------------ etapas

  @Get('pipelines/:pipelineId/etapas')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_ETAPA_VER')
  @ApiQuery({ name: 'solo_activas', required: false })
  findEtapas(
    @Param('pipelineId') pipelineId: string,
    @GetUser() user: LoginUserInfo,
    @Query('solo_activas') soloActivas?: string,
  ) {
    return this.configService.findEtapas(pipelineId, user.empresa_id, soloActivas === 'true');
  }

  @Post('pipelines/:pipelineId/etapas')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_ETAPA_CREAR')
  @ApiBody({ type: CreateEtapaDto })
  createEtapa(
    @Param('pipelineId') pipelineId: string,
    @Body(ValidationPipe) dto: CreateEtapaDto,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.configService.createEtapa(pipelineId, dto, user.empresa_id, user.id);
  }

  @Put('pipelines/:pipelineId/etapas/orden')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_ETAPA_EDITAR')
  @ApiOperation({
    summary: 'Reordena las etapas del pipeline (drag & drop)',
    description: 'Hay que mandar TODAS las etapas activas del pipeline en el orden deseado.',
  })
  @ApiBody({ type: ReordenarEtapasDto })
  reordenarEtapas(
    @Param('pipelineId') pipelineId: string,
    @Body(ValidationPipe) dto: ReordenarEtapasDto,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.configService.reordenarEtapas(pipelineId, dto, user.empresa_id, user.id);
  }

  @Patch('etapas/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_ETAPA_EDITAR')
  @ApiBody({ type: UpdateEtapaDto })
  updateEtapa(@Param('id') id: string, @Body(ValidationPipe) dto: UpdateEtapaDto, @GetUser() user: LoginUserInfo) {
    return this.configService.updateEtapa(id, dto, user.empresa_id, user.id);
  }

  @Delete('etapas/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CFG_ETAPA_ELIMINAR')
  @ApiOperation({ summary: 'Baja lógica de la etapa: las oportunidades que pasaron por ella la referencian' })
  removeEtapa(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.configService.removeEtapa(id, user.empresa_id, user.id);
  }
}
