import { Controller, Get, Post, Put, Delete, Param, Body, UseGuards, Query, UseInterceptors, UploadedFile } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiConsumes, ApiBody } from '@nestjs/swagger';
import { InventoryService } from '../services/inventory.service';
import { CreateMaterialDto, UpdateMaterialDto, CreateSupplierDto, UpdateSupplierDto } from '../dto/inventory.dto';
import { Permissions } from '../auth/decorators/permissions.decorator';
import { RbacGuard } from '../auth/guards/rbac.guard';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { BadRequestException } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';

@ApiTags('Inventory')
@Controller('inventory')
@UseGuards(JwtAuthGuard, RbacGuard)
export class InventoryController {
  constructor(private readonly inventoryService: InventoryService) {}

  @Get('materials')
  @ApiOperation({ summary: 'Get all materials' })
  @ApiResponse({ status: 200, description: 'Returns list of materials' })
  @Permissions('manager:inventory', 'admin:inventory', 'worker:inventory')
  async getMaterials(@Query() query: any) {
    return this.inventoryService.getMaterials(query);
  }

  @Get('materials/:id')
  @ApiOperation({ summary: 'Get material by ID' })
  @ApiResponse({ status: 200, description: 'Returns material details' })
  @Permissions('manager:inventory', 'admin:inventory', 'worker:inventory')
  async getMaterial(@Param('id') id: string) {
    return this.inventoryService.getMaterial(id);
  }

  @Post('materials')
  @ApiOperation({ summary: 'Create new material' })
  @ApiResponse({ status: 201, description: 'Material created successfully' })
  @Permissions('manager:inventory', 'admin:inventory')
  async createMaterial(@Body() createMaterialDto: CreateMaterialDto) {
    return this.inventoryService.createMaterial(createMaterialDto);
  }

  @Put('materials/:id')
  @ApiOperation({ summary: 'Update material' })
  @ApiResponse({ status: 200, description: 'Material updated successfully' })
  @Permissions('manager:inventory', 'admin:inventory')
  async updateMaterial(
    @Param('id') id: string,
    @Body() updateMaterialDto: UpdateMaterialDto,
  ) {
    return this.inventoryService.updateMaterial(id, updateMaterialDto);
  }

  @Delete('materials/:id')
  @ApiOperation({ summary: 'Delete material' })
  @ApiResponse({ status: 200, description: 'Material deleted successfully' })
  @Permissions('admin:inventory')
  async deleteMaterial(@Param('id') id: string) {
    return this.inventoryService.deleteMaterial(id);
  }

  @Post('materials/import')
  @ApiOperation({ summary: 'Bulk import materials from Excel/CSV' })
  @ApiConsumes('multipart/form-data')
  @ApiBody({
    schema: {
      type: 'object',
      properties: {
        file: {
          type: 'string',
          format: 'binary',
        },
      },
    },
  })
  @ApiResponse({ status: 201, description: 'Materials imported successfully' })
  @ApiResponse({ status: 400, description: 'Invalid file type or data' })
  @Permissions('admin:inventory', 'manager:inventory')
  @UseInterceptors(FileInterceptor('file'))
  async importMaterials(@UploadedFile() file: Express.Multer.File) {
    if (!file) {
      throw new BadRequestException('No file uploaded');
    }
    return this.inventoryService.importMaterialsFromExcel(file);
  }

  @Get('suppliers')
  @ApiOperation({ summary: 'Get all suppliers' })
  @ApiResponse({ status: 200, description: 'Returns list of suppliers' })
  @Permissions('manager:inventory', 'admin:inventory', 'worker:inventory')
  async getSuppliers(@Query() query: any) {
    return this.inventoryService.getSuppliers(query);
  }

  @Get('suppliers/:id')
  @ApiOperation({ summary: 'Get supplier by ID' })
  @ApiResponse({ status: 200, description: 'Returns supplier details' })
  @Permissions('manager:inventory', 'admin:inventory', 'worker:inventory')
  async getSupplier(@Param('id') id: string) {
    return this.inventoryService.getSupplier(id);
  }

  @Post('suppliers')
  @ApiOperation({ summary: 'Create new supplier' })
  @ApiResponse({ status: 201, description: 'Supplier created successfully' })
  @Permissions('manager:inventory', 'admin:inventory')
  async createSupplier(@Body() createSupplierDto: CreateSupplierDto) {
    return this.inventoryService.createSupplier(createSupplierDto);
  }

  @Put('suppliers/:id')
  @ApiOperation({ summary: 'Update supplier' })
  @ApiResponse({ status: 200, description: 'Supplier updated successfully' })
  @Permissions('manager:inventory', 'admin:inventory')
  async updateSupplier(
    @Param('id') id: string,
    @Body() updateSupplierDto: UpdateSupplierDto,
  ) {
    return this.inventoryService.updateSupplier(id, updateSupplierDto);
  }

  @Delete('suppliers/:id')
  @ApiOperation({ summary: 'Delete supplier' })
  @ApiResponse({ status: 200, description: 'Supplier deleted successfully' })
  @Permissions('admin:inventory')
  async deleteSupplier(@Param('id') id: string) {
    return this.inventoryService.deleteSupplier(id);
  }

  @Get('stock-movements')
  @ApiOperation({ summary: 'Get stock movements' })
  @ApiResponse({ status: 200, description: 'Returns stock movements' })
  @Permissions('manager:inventory', 'admin:inventory', 'worker:inventory')
  async getStockMovements(@Query() query: any) {
    return this.inventoryService.getStockMovements(query);
  }

  @Post('stock-movements')
  @ApiOperation({ summary: 'Create stock movement' })
  @ApiResponse({ status: 201, description: 'Stock movement created successfully' })
  @Permissions('manager:inventory', 'admin:inventory')
  async createStockMovement(@Body() body: any) {
    return this.inventoryService.createStockMovement(body);
  }

  @Get('low-stock')
  @ApiOperation({ summary: 'Get low stock items' })
  @ApiResponse({ status: 200, description: 'Returns low stock items' })
  @Permissions('manager:inventory', 'admin:inventory', 'worker:inventory')
  async getLowStockItems() {
    return this.inventoryService.getLowStockItems();
  }

  @Get('analytics')
  @ApiOperation({ summary: 'Get inventory analytics' })
  @ApiResponse({ status: 200, description: 'Returns inventory analytics' })
  @Permissions('manager:inventory', 'admin:inventory')
  async getAnalytics() {
    return this.inventoryService.getAnalytics();
  }
} 