import {
    Body,
    Controller,
    Delete,
    Get,
    Param,
    Patch,
    Post,
    Put,
    Query,
    UseGuards,
    ValidationPipe,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiBody, ApiParam, ApiQuery, ApiTags } from '@nestjs/swagger';
import { RequireModule } from '../auth/decorators/require-module.decorator';
import { RequirePermission } from '../auth/decorators/require-permission.decorator';
import type { LoginUserInfo } from '../auth/dto/login.dto';
import { GetUser } from '../auth/get-user.decorator';
import { ModuleGuard } from '../auth/guards/module.guard';
import { PermissionGuard } from '../auth/guards/permission.guard';
import { CreatePedidoItemDto } from './dto/create-pedido-item.dto';
import { CreatePedidoDto } from './dto/create-pedido.dto';
import { QueryPedidosDto } from './dto/query-pedidos.dto';
import { UpdatePedidoItemDto } from './dto/update-pedido-item.dto';
import { UpdatePedidoDto } from './dto/update-pedido.dto';
import { PedidosService } from './pedidos.service';

@ApiTags('Pedidos')
@Controller({ version: '1', path: 'pedidos' })
@UseGuards(AuthGuard('jwt'), ModuleGuard, PermissionGuard)
@RequireModule('VENTAS')
@ApiBearerAuth()
export class PedidosController {
  constructor(private readonly service: PedidosService) {}

  // ═══════════ CRUD PEDIDO ═══════════

  @Post()
  @RequirePermission('VENTAS', 'VEN_PED_PEDIDO_CREAR')
  @ApiBody({ type: CreatePedidoDto })
  async create(@Body(ValidationPipe) dto: CreatePedidoDto, @GetUser() user: LoginUserInfo) {
    return this.service.create(dto, user.empresa_id, user.id);
  }

  @Get()
  @RequirePermission('VENTAS', 'VEN_PED_PEDIDO_VER')
  async findAll(@Query() query: QueryPedidosDto, @GetUser() user: LoginUserInfo) {
    return this.service.findAll(query, user.empresa_id, user.id);
  }

  @Get('pendientes-caja')
  @RequirePermission('VENTAS', 'VEN_PED_PEDIDO_VER')
  @ApiQuery({ name: 'sucursal_id', required: false })
  async findPendientesCaja(@GetUser() user: LoginUserInfo, @Query('sucursal_id') sucursal_id?: string) {
    return this.service.findPendientesCaja(user.empresa_id, sucursal_id);
  }

  @Get('contexto-negociacion/:clienteId')
  @RequirePermission('VENTAS', 'VEN_PED_PEDIDO_VER')
  @ApiParam({ name: 'clienteId', description: 'ID del cliente para obtener contexto de negociación' })
  async contextoNegociacion(@Param('clienteId') clienteId: string, @GetUser() user: LoginUserInfo) {
    return this.service.contextoNegociacion(clienteId, user.empresa_id);
  }

  @Get(':id')
  @RequirePermission('VENTAS', 'VEN_PED_PEDIDO_VER')
  @ApiParam({ name: 'id', description: 'ID del pedido' })
  async findOne(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.findOne(id, user.empresa_id);
  }

  @Put(':id')
  @RequirePermission('VENTAS', 'VEN_PED_PEDIDO_EDITAR')
  @ApiParam({ name: 'id', description: 'ID del pedido' })
  @ApiBody({ type: UpdatePedidoDto })
  async update(@Param('id') id: string, @Body(ValidationPipe) dto: UpdatePedidoDto, @GetUser() user: LoginUserInfo) {
    return this.service.update(id, dto, user.empresa_id, user.id);
  }

  @Delete(':id')
  @RequirePermission('VENTAS', 'VEN_PED_PEDIDO_ELIMINAR')
  @ApiParam({ name: 'id', description: 'ID del pedido' })
  async remove(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.remove(id, user.empresa_id, user.id);
  }

  // ═══════════ ITEMS ═══════════

  @Post(':id/items')
  @RequirePermission('VENTAS', 'VEN_PED_PEDIDO_EDITAR')
  @ApiParam({ name: 'id', description: 'ID del pedido' })
  @ApiBody({ type: CreatePedidoItemDto })
  async addItem(
    @Param('id') id: string,
    @Body(ValidationPipe) dto: CreatePedidoItemDto,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.service.addItem(id, dto, user.empresa_id, user.id);
  }

  @Put(':id/items/:itemId')
  @RequirePermission('VENTAS', 'VEN_PED_PEDIDO_EDITAR')
  @ApiParam({ name: 'id', description: 'ID del pedido' })
  @ApiParam({ name: 'itemId', description: 'ID del item' })
  @ApiBody({ type: UpdatePedidoItemDto })
  async updateItem(
    @Param('id') id: string,
    @Param('itemId') itemId: string,
    @Body(ValidationPipe) dto: UpdatePedidoItemDto,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.service.updateItem(id, itemId, dto, user.empresa_id, user.id);
  }

  @Delete(':id/items/:itemId')
  @RequirePermission('VENTAS', 'VEN_PED_PEDIDO_EDITAR')
  @ApiParam({ name: 'id', description: 'ID del pedido' })
  @ApiParam({ name: 'itemId', description: 'ID del item' })
  async removeItem(@Param('id') id: string, @Param('itemId') itemId: string, @GetUser() user: LoginUserInfo) {
    return this.service.removeItem(id, itemId, user.empresa_id, user.id);
  }

  // ═══════════ DESCUENTO GLOBAL ═══════════

  @Patch(':id/descuento-global')
  @RequirePermission('VENTAS', 'VEN_PED_PEDIDO_EDITAR')
  @ApiParam({ name: 'id', description: 'ID del pedido' })
  @ApiBody({ schema: { properties: { porcentaje: { type: 'number', description: 'Porcentaje de descuento global (0-100)' } } } })
  async aplicarDescuentoGlobal(
    @Param('id') id: string,
    @Body('porcentaje') porcentaje: number,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.service.aplicarDescuentoGlobal(id, user.empresa_id, user.id, porcentaje);
  }

  // ═══════════ FLUJO DE ESTADOS ═══════════

  @Patch(':id/confirmar')
  @RequirePermission('VENTAS', 'VEN_PED_PEDIDO_EDITAR')
  @ApiParam({ name: 'id', description: 'ID del pedido' })
  async confirmar(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.confirmar(id, user.empresa_id, user.id);
  }

  @Patch(':id/cancelar')
  @RequirePermission('VENTAS', 'VEN_PED_PEDIDO_ELIMINAR')
  @ApiParam({ name: 'id', description: 'ID del pedido' })
  async cancelar(@Param('id') id: string, @GetUser() user: LoginUserInfo, @Body('motivo') motivo?: string) {
    return this.service.cancelar(id, user.empresa_id, user.id, motivo);
  }

  @Patch(':id/facturado')
  @RequirePermission('VENTAS', 'VEN_PED_PEDIDO_FACTURAR')
  @ApiParam({ name: 'id', description: 'ID del pedido' })
  async marcarFacturado(
    @Param('id') id: string,
    @Body('factura_id') facturaId: string,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.service.marcarFacturado(id, facturaId, user.empresa_id, user.id);
  }

  // ═══════════ HISTORIAL ═══════════

  @Get(':id/historial')
  @RequirePermission('VENTAS', 'VEN_PED_PEDIDO_VER')
  @ApiParam({ name: 'id', description: 'ID del pedido' })
  async getHistorial(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.getHistorial(id, user.empresa_id);
  }
}
