import { Body, Controller, Delete, Get, Param, Post, Put, Query, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiOperation, ApiParam, ApiQuery, ApiTags } from '@nestjs/swagger';
import { RequireModule } from 'src/auth/decorators/require-module.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 { ModuleGuard } from 'src/auth/guards/module.guard';
import { PermissionGuard } from 'src/auth/guards/permission.guard';
import { ActualizarReglaPrecioDto } from './dto/actualizar-regla-precio.dto';
import { CrearReglaPrecioDto } from './dto/crear-regla-precio.dto';
import { RecalcularListaDto } from './dto/recalcular-lista.dto';
import { PreciosEngineService } from './precios-engine.service';

@ApiTags('Reglas de Precio')
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), ModuleGuard, PermissionGuard)
@RequireModule('INVENTARIO')
@Controller({ path: 'reglas-precio', version: '1' })
export class ReglasPrecioController {
  constructor(private readonly preciosEngine: PreciosEngineService) {}

  @Post()
  @RequirePermission('INVENTARIO', 'INV_RGP_REGLA_CREAR')
  @ApiOperation({ summary: 'Crear regla de precio (marcación desde costo)' })
  async crear(@Body() dto: CrearReglaPrecioDto, @GetUser() user: LoginUserInfo) {
    const data = await this.preciosEngine.crear(dto, user.empresa_id, user.id);
    return { success: true, message: 'Regla de precio creada exitosamente', data };
  }

  @Get()
  @RequirePermission('INVENTARIO', 'INV_RGP_REGLA_VER')
  @ApiOperation({ summary: 'Listar reglas de precio de la empresa' })
  @ApiQuery({ name: 'activo', required: false })
  @ApiQuery({ name: 'listaPreciosId', required: false })
  async listar(
    @GetUser() user: LoginUserInfo,
    @Query('activo') activo?: string,
    @Query('listaPreciosId') listaPreciosId?: string,
  ) {
    const data = await this.preciosEngine.listar(user.empresa_id, {
      activo: activo === undefined ? undefined : activo === 'true',
      listaPreciosId,
    });
    return { success: true, data, total: data.length };
  }

  @Get(':id')
  @RequirePermission('INVENTARIO', 'INV_RGP_REGLA_VER')
  @ApiOperation({ summary: 'Obtener regla de precio por ID' })
  @ApiParam({ name: 'id' })
  async obtener(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    const data = await this.preciosEngine.obtenerPorId(id, user.empresa_id);
    return { success: true, data };
  }

  @Put(':id')
  @RequirePermission('INVENTARIO', 'INV_RGP_REGLA_EDITAR')
  @ApiOperation({ summary: 'Actualizar regla de precio' })
  @ApiParam({ name: 'id' })
  async actualizar(@Param('id') id: string, @Body() dto: ActualizarReglaPrecioDto, @GetUser() user: LoginUserInfo) {
    const data = await this.preciosEngine.actualizar(id, dto, user.empresa_id, user.id);
    return { success: true, message: 'Regla de precio actualizada exitosamente', data };
  }

  @Delete(':id')
  @RequirePermission('INVENTARIO', 'INV_RGP_REGLA_ELIMINAR')
  @ApiOperation({ summary: 'Desactivar regla de precio' })
  @ApiParam({ name: 'id' })
  async eliminar(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    const data = await this.preciosEngine.eliminar(id, user.empresa_id, user.id);
    return { success: true, message: 'Regla de precio desactivada exitosamente', data };
  }

  @Post(':id/previsualizar')
  @RequirePermission('INVENTARIO', 'INV_RGP_REGLA_VER')
  @ApiOperation({ summary: 'Previsualizar impacto de una regla: cuántos productos afecta y ejemplos' })
  @ApiParam({ name: 'id' })
  @ApiQuery({ name: 'limit', required: false })
  async previsualizar(@Param('id') id: string, @GetUser() user: LoginUserInfo, @Query('limit') limit?: string) {
    const data = await this.preciosEngine.previsualizar(id, user.empresa_id, Number(limit) || 20);
    return { success: true, data };
  }

  @Post('recalcular')
  @RequirePermission('INVENTARIO', 'INV_RGP_REGLA_EDITAR')
  @ApiOperation({ summary: 'Recalcular precios de una lista aplicando las reglas activas' })
  async recalcular(@Body() dto: RecalcularListaDto, @GetUser() user: LoginUserInfo) {
    const data = await this.preciosEngine.recalcularLista(dto, user.empresa_id, user.id);
    return { success: true, message: 'Recálculo de precios ejecutado', data };
  }

  @Get('producto/:productoId/sugerido')
  @RequirePermission('INVENTARIO', 'INV_RGP_REGLA_VER')
  @ApiOperation({ summary: 'Precio sugerido de un producto según las reglas de una lista' })
  @ApiParam({ name: 'productoId' })
  @ApiQuery({ name: 'listaPreciosId', required: true })
  async precioSugerido(
    @Param('productoId') productoId: string,
    @Query('listaPreciosId') listaPreciosId: string,
    @GetUser() user: LoginUserInfo,
  ) {
    const data = await this.preciosEngine.calcularPrecio(productoId, listaPreciosId, user.empresa_id);
    return { success: true, data };
  }
}
