import { Body, Controller, Delete, Get, Param, Patch, Post, Query, Req, Res, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiOperation, ApiQuery, ApiTags } from '@nestjs/swagger';
import { Response } from 'express';
import type { LoginUserInfo } from '../auth/dto/login.dto';
import { GetUser } from '../auth/get-user.decorator';
import { AsignarEquipoDto } from './dto/asignar-equipo.dto';
import { CreateSupervisorDto } from './dto/create-supervisor.dto';
import { GenerarComisionSupervisorDto } from './dto/generar-comision.dto';
import { UpdateSupervisorDto } from './dto/update-supervisor.dto';
import { SupervisoresService } from './supervisores.service';

@ApiTags('Supervisores')
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'))
@Controller('supervisores')
export class SupervisoresController {
  constructor(private readonly service: SupervisoresService) {}

  @Post()
  @ApiOperation({ summary: 'Crear supervisor' })
  create(@GetUser() user: LoginUserInfo, @Body() dto: CreateSupervisorDto) {
    return this.service.create(user.empresa_id, dto);
  }

  @Get()
  @ApiOperation({ summary: 'Listar supervisores' })
  @ApiQuery({ name: 'active', required: false, type: Boolean })
  @ApiQuery({ name: 'search', required: false })
  findAll(
    @GetUser() user: LoginUserInfo,
    @Query('active') active?: string,
    @Query('search') search?: string,
  ) {
    return this.service.findAll(user.empresa_id, {
      active: active !== undefined ? active === 'true' : undefined,
      search,
    });
  }

  @Get('activos')
  @ApiOperation({ summary: 'Listar supervisores activos para selección' })
  findActivos(@GetUser() user: LoginUserInfo) {
    return this.service.findActivos(user.empresa_id);
  }

  @Get('reporte-comisiones')
  @ApiOperation({ summary: 'Reporte de comisiones por supervisor y período' })
  @ApiQuery({ name: 'supervisor_id', required: false })
  @ApiQuery({ name: 'periodo_desde', required: false })
  @ApiQuery({ name: 'periodo_hasta', required: false })
  getReporteComisiones(
    @GetUser() user: LoginUserInfo,
    @Query('supervisor_id') supervisor_id?: string,
    @Query('periodo_desde') periodo_desde?: string,
    @Query('periodo_hasta') periodo_hasta?: string,
  ) {
    return this.service.getReporteComisiones(user.empresa_id, { supervisor_id, periodo_desde, periodo_hasta });
  }

  @Get('reporte-comisiones/resumen/pdf')
  @ApiOperation({ summary: 'PDF resumen de comisiones supervisores' })
  @ApiQuery({ name: 'supervisor_id', required: false })
  @ApiQuery({ name: 'periodo_desde', required: false })
  @ApiQuery({ name: 'periodo_hasta', required: false })
  async getReporteComisionesResumenPdf(
    @GetUser() user: LoginUserInfo,
    @Res() res: Response,
    @Query('supervisor_id') supervisor_id?: string,
    @Query('periodo_desde') periodo_desde?: string,
    @Query('periodo_hasta') periodo_hasta?: string,
  ) {
    const pdf = await this.service.reporteComisionesResumenPdf(user.empresa_id, {
      supervisor_id, periodo_desde, periodo_hasta,
    });
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', 'inline; filename="comisiones-supervisores-resumen.pdf"');
    res.end(pdf);
  }

  @Get('reporte-comisiones/detalle/pdf')
  @ApiOperation({ summary: 'PDF detallado de comisiones supervisores (por equipo)' })
  @ApiQuery({ name: 'supervisor_id', required: false })
  @ApiQuery({ name: 'periodo_desde', required: false })
  @ApiQuery({ name: 'periodo_hasta', required: false })
  async getReporteComisionesDetallePdf(
    @GetUser() user: LoginUserInfo,
    @Res() res: Response,
    @Query('supervisor_id') supervisor_id?: string,
    @Query('periodo_desde') periodo_desde?: string,
    @Query('periodo_hasta') periodo_hasta?: string,
  ) {
    const pdf = await this.service.reporteComisionesDetallePdf(user.empresa_id, {
      supervisor_id, periodo_desde, periodo_hasta,
    });
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', 'inline; filename="comisiones-supervisores-detalle.pdf"');
    res.end(pdf);
  }

  @Get('comisiones/:comisionId/detalle')
  @ApiOperation({ summary: 'Detalle de una comisión de supervisor con desglose por equipo' })
  getDetalleComision(@GetUser() user: LoginUserInfo, @Param('comisionId') comisionId: string) {
    return this.service.getDetalleComision(user.empresa_id, comisionId);
  }

  @Get(':id')
  @ApiOperation({ summary: 'Obtener supervisor por ID' })
  findOne(@GetUser() user: LoginUserInfo, @Param('id') id: string) {
    return this.service.findOne(user.empresa_id, id);
  }

  @Patch(':id')
  @ApiOperation({ summary: 'Actualizar supervisor' })
  update(@GetUser() user: LoginUserInfo, @Param('id') id: string, @Body() dto: UpdateSupervisorDto) {
    return this.service.update(user.empresa_id, id, dto);
  }

  @Delete(':id')
  @ApiOperation({ summary: 'Desactivar supervisor' })
  remove(@GetUser() user: LoginUserInfo, @Param('id') id: string) {
    return this.service.remove(user.empresa_id, id);
  }

  // Equipo
  @Get(':id/equipo')
  @ApiOperation({ summary: 'Ver vendedores/cobradores del equipo del supervisor' })
  getEquipo(@GetUser() user: LoginUserInfo, @Param('id') id: string) {
    return this.service.getEquipo(user.empresa_id, id);
  }

  @Post(':id/equipo')
  @ApiOperation({ summary: 'Asignar vendedores/cobradores al supervisor' })
  asignarEquipo(@GetUser() user: LoginUserInfo, @Param('id') id: string, @Body() dto: AsignarEquipoDto) {
    return this.service.asignarEquipo(user.empresa_id, id, dto);
  }

  @Delete(':id/equipo/:vcId')
  @ApiOperation({ summary: 'Desasignar vendedor/cobrador del supervisor' })
  desasignarEquipo(@GetUser() user: LoginUserInfo, @Param('id') id: string, @Param('vcId') vcId: string) {
    return this.service.desasignarEquipo(user.empresa_id, id, vcId);
  }

  // Comisiones
  @Get(':id/comisiones/preview')
  @ApiOperation({ summary: 'Vista previa de comisión del supervisor (sin persistir)' })
  @ApiQuery({ name: 'periodo_desde', required: true })
  @ApiQuery({ name: 'periodo_hasta', required: true })
  previewComision(
    @GetUser() user: LoginUserInfo,
    @Param('id') id: string,
    @Query('periodo_desde') periodo_desde: string,
    @Query('periodo_hasta') periodo_hasta: string,
  ) {
    return this.service.previewComision(user.empresa_id, id, { periodo_desde, periodo_hasta });
  }

  @Post(':id/comisiones/generar')
  @ApiOperation({ summary: 'Generar comisión del supervisor por período' })
  generarComision(@GetUser() user: LoginUserInfo, @Param('id') id: string, @Body() dto: GenerarComisionSupervisorDto) {
    return this.service.generarComision(user.empresa_id, id, dto);
  }

  @Post('comisiones/:comisionId/recalcular')
  @ApiOperation({ summary: 'Recalcular snapshot de una comisión pendiente con datos actuales' })
  recalcularComision(@GetUser() user: LoginUserInfo, @Param('comisionId') comisionId: string) {
    return this.service.recalcularComision(user.empresa_id, comisionId);
  }

  @Get(':id/comisiones')
  @ApiOperation({ summary: 'Historial de comisiones del supervisor' })
  getComisiones(@GetUser() user: LoginUserInfo, @Param('id') id: string) {
    return this.service.getComisiones(user.empresa_id, id);
  }

  @Patch('comisiones/:comisionId/liquidar')
  @ApiOperation({ summary: 'Marcar comisión de supervisor como liquidada' })
  liquidarComision(@GetUser() user: LoginUserInfo, @Param('comisionId') comisionId: string) {
    return this.service.liquidarComision(user.empresa_id, comisionId);
  }

  @Delete('comisiones/:comisionId')
  @ApiOperation({ summary: 'Eliminar una comisión de supervisor pendiente (no liquidada)' })
  eliminarComision(
    @GetUser() user: LoginUserInfo,
    @Param('comisionId') comisionId: string,
    @Req() req: any,
  ) {
    return this.service.eliminarComision(user.empresa_id, comisionId, user.id, {
      ip: req.ip,
      userAgent: req.headers['user-agent'],
    });
  }
}
