import {
  Body,
  Controller,
  Get,
  Param,
  Patch,
  Post,
  Put,
  Query,
  Res,
  UseGuards,
  UseInterceptors,
  ValidationPipe,
} from '@nestjs/common';
import type { Response } from 'express';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiBody, ApiParam, 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 { Auditable } from '../audit/auditable.decorator';
import { AuditInterceptor } from '../audit/audit.interceptor';
import { CreateOrdenVentaDto } from './dto/create-orden-venta.dto';
import { QueryOrdenesVentaDto } from './dto/query-ordenes-venta.dto';
import { PedidosService } from './pedidos.service';

@ApiTags('Órdenes de Venta')
@Controller({ version: '1', path: 'ordenes-venta' })
@UseGuards(AuthGuard('jwt'), ModuleGuard, PermissionGuard)
@RequireModule('VENTAS')
@UseInterceptors(AuditInterceptor)
@ApiBearerAuth()
export class OrdenesVentaController {
  constructor(private readonly service: PedidosService) {}

  @Post()
  @RequirePermission('VENTAS', 'VEN_OV_ORDEN_VENTA_CREAR')
  @Auditable('orden_venta')
  @ApiBody({ type: CreateOrdenVentaDto })
  crear(@Body(ValidationPipe) dto: CreateOrdenVentaDto, @GetUser() user: LoginUserInfo) {
    return this.service.crearOrden(dto, user.empresa_id, user.id);
  }

  @Get('stats')
  @RequirePermission('VENTAS', 'VEN_OV_ORDEN_VENTA_VER')
  stats(@Query() query: QueryOrdenesVentaDto, @GetUser() user: LoginUserInfo) {
    return this.service.statsOrdenes(query, user.empresa_id);
  }

  @Get()
  @RequirePermission('VENTAS', 'VEN_OV_ORDEN_VENTA_VER')
  listar(@Query() query: QueryOrdenesVentaDto, @GetUser() user: LoginUserInfo) {
    return this.service.findAllOrdenes(query, user.empresa_id);
  }

  @Get(':id')
  @RequirePermission('VENTAS', 'VEN_OV_ORDEN_VENTA_VER')
  @ApiParam({ name: 'id', type: String })
  detalle(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.findOneOrden(id, user.empresa_id);
  }

  @Put(':id')
  @RequirePermission('VENTAS', 'VEN_OV_ORDEN_VENTA_EDITAR')
  @Auditable('orden_venta')
  @ApiParam({ name: 'id', type: String })
  @ApiBody({ type: CreateOrdenVentaDto })
  actualizar(
    @Param('id') id: string,
    @Body(ValidationPipe) dto: Partial<CreateOrdenVentaDto>,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.service.updateOrden(id, dto, user.empresa_id, user.id);
  }

  @Patch(':id/confirmar')
  @RequirePermission('VENTAS', 'VEN_OV_ORDEN_VENTA_EDITAR')
  @Auditable('orden_venta')
  @ApiParam({ name: 'id', type: String })
  confirmar(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.confirmarOrden(id, user.empresa_id, user.id);
  }

  @Patch(':id/aprobar')
  @RequirePermission('VENTAS', 'VEN_OV_ORDEN_VENTA_EDITAR')
  @Auditable('orden_venta')
  @ApiParam({ name: 'id', type: String })
  aprobar(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.aprobarOrden(id, user.empresa_id, user.id);
  }

  @Patch(':id/iniciar')
  @RequirePermission('VENTAS', 'VEN_OV_ORDEN_VENTA_EDITAR')
  @Auditable('orden_venta')
  @ApiParam({ name: 'id', type: String })
  iniciar(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.iniciarOrden(id, user.empresa_id, user.id);
  }

  @Get(':id/items-facturados')
  @RequirePermission('VENTAS', 'VEN_OV_ORDEN_VENTA_VER')
  @ApiParam({ name: 'id', type: String })
  itemsFacturados(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.getItemsFacturadosOrden(id, user.empresa_id);
  }

  @Get(':id/pdf')
  @RequirePermission('VENTAS', 'VEN_OV_ORDEN_VENTA_VER')
  @ApiParam({ name: 'id', type: String })
  async pdf(@Param('id') id: string, @GetUser() user: LoginUserInfo, @Res() res: Response) {
    const buffer = await this.service.generateOrdenPdf(id, user.empresa_id);
    res.set({
      'Content-Type': 'application/pdf',
      'Content-Disposition': `inline; filename="orden-venta-${id}.pdf"`,
      'Content-Length': String(buffer.length),
    });
    res.end(buffer);
  }

  @Patch(':id/facturar')
  @RequirePermission('VENTAS', 'VEN_OV_ORDEN_VENTA_FACTURAR')
  @Auditable('orden_venta')
  @ApiParam({ name: 'id', type: String })
  facturar(
    @Param('id') id: string,
    @GetUser() user: LoginUserInfo,
    @Body('factura_id') facturaId: string,
  ) {
    return this.service.facturarOrden(id, facturaId, user.empresa_id, user.id);
  }

  @Patch(':id/cancelar')
  @RequirePermission('VENTAS', 'VEN_OV_ORDEN_VENTA_ELIMINAR')
  @Auditable('orden_venta')
  @ApiParam({ name: 'id', type: String })
  cancelar(
    @Param('id') id: string,
    @GetUser() user: LoginUserInfo,
    @Body('motivo') motivo?: string,
  ) {
    return this.service.cancelarOrden(id, user.empresa_id, user.id, motivo);
  }

  // Items — reutiliza los endpoints de pedidos para agregar/editar/eliminar items
  // POST   /pedidos/:id/items
  // PUT    /pedidos/:id/items/:itemId
  // DELETE /pedidos/:id/items/:itemId
  // (Los mismos endpoints funcionan para orden_venta ya que usan pedido_id)
}
