import {
  Body, Controller, Delete, Get, Param, Patch, Post, Put, 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 { CanalesService } from './canales.service';
import { CreateCanalDto, UpdateCanalDto } from './dto/canal.dto';
import { MensajeriaService } from './mensajeria.service';
import type { CategoriaPlantilla } from './whatsapp/whatsapp-provider.interface';

@ApiTags('CRM · Canales de mensajería')
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), SubmoduloGuard)
@RequireSubmodulo('CRM_CANALES')
@Controller({ path: 'crm/canales', version: '1' })
export class CanalesController {
  constructor(
    private readonly service: CanalesService,
    private readonly mensajeria: MensajeriaService,
  ) {}

  @Get('tarifas')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CAN_CANAL_VER')
  @ApiQuery({ name: 'pais', required: false, example: 'PY' })
  @ApiOperation({
    summary: 'Tarifas de WhatsApp cargadas',
    description:
      'Las publica Meta y se cargan a mano. Sin tarifa cargada, el estimador devuelve null en ' +
      'vez de cero: un costo de 0 invita a mandar campañas creyendo que son gratis.',
  })
  tarifas(@Query('pais') pais?: string) {
    return this.mensajeria.listarTarifas(pais);
  }

  @Put('tarifas')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CAN_CANAL_EDITAR')
  @ApiOperation({ summary: 'Carga o actualiza una tarifa publicada por Meta' })
  upsertTarifa(
    @Body()
    body: { pais: string; categoria: CategoriaPlantilla; precio_usd: number; vigente_desde: string },
  ) {
    return this.mensajeria.upsertTarifa(body.pais, body.categoria, body.precio_usd, body.vigente_desde);
  }

  @Get()
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CAN_CANAL_VER')
  @ApiQuery({ name: 'tipo', required: false, description: 'whatsapp | email | instagram | facebook | webchat' })
  @ApiOperation({
    summary: 'Canales de la empresa',
    description: 'Las credenciales se devuelven enmascaradas: nunca salen en claro.',
  })
  findAll(@GetUser() user: LoginUserInfo, @Query('tipo') tipo?: string) {
    return this.service.findAll(user.empresa_id, tipo);
  }

  @Get(':id')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CAN_CANAL_VER')
  findOne(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.findOne(id, user.empresa_id);
  }

  @Get(':id/estado-sesion')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CAN_CANAL_VER')
  @ApiOperation({
    summary: 'Estado de la sesión del canal',
    description: 'Sólo aplica a Evolution en modo Baileys, donde la sesión por QR se cae sola.',
  })
  estadoSesion(@Param('id') id: string) {
    return this.mensajeria.estadoSesion(id);
  }

  @Post()
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CAN_CANAL_CREAR')
  @ApiOperation({
    summary: 'Da de alta un canal',
    description:
      'Valida que el proveedor sirva para el tipo y que estén las credenciales que ese proveedor ' +
      'necesita, para no descubrirlo en el primer envío.',
  })
  create(@Body(ValidationPipe) dto: CreateCanalDto, @GetUser() user: LoginUserInfo) {
    return this.service.create(dto, user.empresa_id, user.id);
  }

  @Patch(':id')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CAN_CANAL_EDITAR')
  @ApiOperation({
    summary: 'Edita un canal',
    description: 'Las credenciales se mezclan: lo que no se envía conserva el valor guardado.',
  })
  update(@Param('id') id: string, @Body(ValidationPipe) dto: UpdateCanalDto, @GetUser() user: LoginUserInfo) {
    return this.service.update(id, dto, user.empresa_id, user.id);
  }

  @Delete(':id')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_CAN_CANAL_ELIMINAR')
  @ApiOperation({
    summary: 'Da de baja un canal (lógica)',
    description: 'No se borra: las conversaciones que pasaron por él son el historial del cliente.',
  })
  remove(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.remove(id, user.empresa_id, user.id);
  }
}
