import { Body, Controller, Delete, Get, Param, Patch, Post, Query, UseGuards, ValidationPipe } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiBody, 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 { ActividadesService } from './actividades.service';
import { CheckGeoDto, CompletarActividadDto, CreateActividadDto, UpdateActividadDto } from './dto/actividad.dto';

@ApiTags('CRM · Actividades')
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), SubmoduloGuard)
@RequireSubmodulo('CRM_ACTIVIDADES')
@Controller({ path: 'crm/actividades', version: '1' })
export class ActividadesController {
  constructor(private readonly service: ActividadesService) {}

  @Get('agenda')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_ACT_ACTIVIDAD_VER')
  @ApiOperation({ summary: 'Pendientes del usuario, ordenadas por fecha' })
  @ApiQuery({ name: 'usuario_id', required: false, description: 'Por defecto, el propio.' })
  @ApiQuery({ name: 'desde', required: false })
  @ApiQuery({ name: 'hasta', required: false })
  agenda(
    @GetUser() user: LoginUserInfo,
    @Query('usuario_id') usuario_id?: string,
    @Query('desde') desde?: string,
    @Query('hasta') hasta?: string,
  ) {
    return this.service.agenda(user.empresa_id, usuario_id ?? user.id, desde, hasta);
  }

  @Get('oportunidad/:oportunidadId')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_ACT_ACTIVIDAD_VER')
  porOportunidad(@Param('oportunidadId') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.findPorOportunidad(id, user.empresa_id);
  }

  @Post()
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_ACT_ACTIVIDAD_CREAR')
  @ApiBody({ type: CreateActividadDto })
  create(@Body(ValidationPipe) dto: CreateActividadDto, @GetUser() user: LoginUserInfo) {
    return this.service.create(dto, user.empresa_id, user.id);
  }

  @Patch(':id')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_ACT_ACTIVIDAD_EDITAR')
  @ApiBody({ type: UpdateActividadDto })
  update(@Param('id') id: string, @Body(ValidationPipe) dto: UpdateActividadDto, @GetUser() user: LoginUserInfo) {
    return this.service.update(id, dto, user.empresa_id, user.id);
  }

  @Post(':id/completar')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_ACT_ACTIVIDAD_CONFIRMAR')
  @ApiOperation({
    summary: 'Cierra la actividad con su resultado',
    description:
      'Devuelve `sugerir_proxima: true` cuando la oportunidad queda sin nada agendado. ' +
      'Se informa en vez de bloquear: frenar al vendedor justo al volver de una visita es ' +
      'la forma más rápida de que deje de registrar actividades.',
  })
  @ApiBody({ type: CompletarActividadDto })
  completar(
    @Param('id') id: string,
    @Body(ValidationPipe) dto: CompletarActividadDto,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.service.completar(id, dto, user.empresa_id, user.id);
  }

  @Post(':id/check-in')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_ACT_ACTIVIDAD_EDITAR')
  @ApiOperation({ summary: 'Check-in geolocalizado de una visita' })
  @ApiBody({ type: CheckGeoDto })
  checkIn(@Param('id') id: string, @Body(ValidationPipe) dto: CheckGeoDto, @GetUser() user: LoginUserInfo) {
    return this.service.checkIn(id, dto, user.empresa_id);
  }

  @Post(':id/check-out')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_ACT_ACTIVIDAD_EDITAR')
  checkOut(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.checkOut(id, user.empresa_id);
  }

  @Delete(':id')
  @UseGuards(PermissionGuard)
  @RequirePermission('CRM', 'CRM_ACT_ACTIVIDAD_CANCELAR')
  @ApiOperation({ summary: 'Cancela la actividad. Una realizada no se cancela.' })
  cancelar(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.cancelar(id, user.empresa_id, user.id);
  }
}
