// Inventory Trigger System
// Auto-reorder when stock hits threshold

import prisma from '@/lib/db';
import { logSimpleAction } from './agent-logger';

export interface InventoryCheckResult {
  productId: string;
  productName: string;
  currentStock: number;
  threshold: number;
  alertCreated: boolean;
  reorderTriggered: boolean;
}

export interface ReorderSuggestion {
  productId: string;
  productName: string;
  sku: string;
  currentStock: number;
  reorderLevel: number;
  suggestedQuantity: number;
  estimatedCost: number;
  priority: 'low' | 'normal' | 'high' | 'critical';
  vendorId?: string;
  vendorName?: string;
}

// Check all inventory and trigger alerts for low stock
export async function checkInventoryLevels(): Promise<InventoryCheckResult[]> {
  const results: InventoryCheckResult[] = [];
  
  // Get all active products
  const products = await prisma.product.findMany({
    where: { isActive: true },
  });
  
  for (const product of products) {
    // Get inventory items for this product
    const inventoryItems = await prisma.inventoryItem.findMany({
      where: { productId: product.id },
    });
    
    const totalStock = inventoryItems.reduce((sum: number, inv: { availableQty: number }) => sum + inv.availableQty, 0);
    
    if (totalStock <= product.reorderLevel) {
      // Check if alert already exists
      const existingAlert = await prisma.inventoryAlert.findFirst({
        where: {
          productId: product.id,
          status: { in: ['pending', 'ordered'] },
        },
      });
      
      if (!existingAlert) {
        // Determine priority based on stock level
        let priority = 'normal';
        if (totalStock === 0) priority = 'critical';
        else if (totalStock <= product.reorderLevel * 0.25) priority = 'high';
        else if (totalStock <= product.reorderLevel * 0.5) priority = 'normal';
        else priority = 'low';
        
        // Create inventory alert
        await prisma.inventoryAlert.create({
          data: {
            productId: product.id,
            productName: product.name,
            currentStock: totalStock,
            threshold: product.reorderLevel,
            reorderQty: product.reorderQuantity,
            priority,
          },
        });
        
        // Log agent action
        await logSimpleAction({
          actionType: 'detect_anomaly',
          targetEntity: 'InventoryAlert',
          targetId: product.id,
          input: { product: product.name, currentStock: totalStock, reorderLevel: product.reorderLevel },
          output: { alertCreated: true, priority },
          confidence: 1.0,
          anomalyDetected: priority === 'critical' || priority === 'high',
          anomalyType: priority === 'critical' ? 'out_of_stock' : priority === 'high' ? 'low_stock' : undefined,
        });
        
        results.push({
          productId: product.id,
          productName: product.name,
          currentStock: totalStock,
          threshold: product.reorderLevel,
          alertCreated: true,
          reorderTriggered: false,
        });
      }
    }
  }
  
  return results;
}

// Get pending reorder suggestions
export async function getReorderSuggestions(): Promise<ReorderSuggestion[]> {
  const alerts = await prisma.inventoryAlert.findMany({
    where: { status: 'pending' },
    orderBy: [
      { priority: 'desc' },
      { triggeredAt: 'asc' },
    ],
  });
  
  const suggestions: ReorderSuggestion[] = [];
  
  for (const alert of alerts) {
    const product = await prisma.product.findUnique({
      where: { id: alert.productId },
    });
    
    if (product) {
      let vendor = null;
      if (product.supplierId) {
        vendor = await prisma.vendor.findUnique({
          where: { id: product.supplierId },
        });
      }
      
      suggestions.push({
        productId: alert.productId,
        productName: alert.productName,
        sku: product.sku,
        currentStock: alert.currentStock,
        reorderLevel: alert.threshold,
        suggestedQuantity: alert.reorderQty,
        estimatedCost: product.costPrice * alert.reorderQty,
        priority: alert.priority as 'low' | 'normal' | 'high' | 'critical',
        vendorId: product.supplierId || undefined,
        vendorName: vendor?.name,
      });
    }
  }
  
  return suggestions;
}

// Auto-reorder based on configured thresholds (for fully autonomous mode)
export async function processAutoReorders(): Promise<{
  ordersCreated: number;
  totalValue: number;
  details: { productName: string; quantity: number; vendor: string }[];
}> {
  const suggestions = await getReorderSuggestions();
  const criticalAndHigh = suggestions.filter(s => s.priority === 'critical' || s.priority === 'high');
  
  const details: { productName: string; quantity: number; vendor: string }[] = [];
  let totalValue = 0;
  
  for (const suggestion of criticalAndHigh) {
    // Update alert status to 'ordered'
    await prisma.inventoryAlert.updateMany({
      where: {
        productId: suggestion.productId,
        status: 'pending',
      },
      data: {
        status: 'ordered',
        orderedAt: new Date(),
        notes: `Auto-reorder triggered for ${suggestion.suggestedQuantity} units`,
      },
    });
    
    // Create stock movement record (incoming expected)
    await prisma.stockMovement.create({
      data: {
        productId: suggestion.productId,
        type: 'reorder_placed',
        quantity: suggestion.suggestedQuantity,
        reference: `AUTO-REORDER-${Date.now()}`,
        reason: `Auto-reorder: Stock at ${suggestion.currentStock}, threshold ${suggestion.reorderLevel}`,
        cost: suggestion.estimatedCost,
        performedBy: 'InventoryAgent',
      },
    });
    
    // Log agent action
    await logSimpleAction({
      actionType: 'update_inventory',
      targetEntity: 'Product',
      targetId: suggestion.productId,
      input: { suggestion },
      output: { ordered: true, quantity: suggestion.suggestedQuantity },
      confidence: 0.95,
      anomalyDetected: false,
    });
    
    details.push({
      productName: suggestion.productName,
      quantity: suggestion.suggestedQuantity,
      vendor: suggestion.vendorName || 'Unknown',
    });
    
    totalValue += suggestion.estimatedCost;
  }
  
  return {
    ordersCreated: details.length,
    totalValue,
    details,
  };
}

// Mark alert as fulfilled (stock received)
export async function fulfillInventoryAlert(
  alertId: string,
  actualQuantity: number
): Promise<void> {
  const alert = await prisma.inventoryAlert.findUnique({
    where: { id: alertId },
  });
  
  if (!alert) throw new Error(`Alert ${alertId} not found`);
  
  // Update the inventory
  await prisma.inventoryItem.updateMany({
    where: { productId: alert.productId },
    data: {
      quantity: { increment: actualQuantity },
      availableQty: { increment: actualQuantity },
      lastRestocked: new Date(),
    },
  });
  
  // Update alert
  await prisma.inventoryAlert.update({
    where: { id: alertId },
    data: {
      status: 'fulfilled',
      fulfilledAt: new Date(),
      notes: `Received ${actualQuantity} units`,
    },
  });
  
  // Create stock movement
  await prisma.stockMovement.create({
    data: {
      productId: alert.productId,
      type: 'restock',
      quantity: actualQuantity,
      toLocation: 'main-warehouse',
      reference: `FULFILL-${alertId}`,
      reason: 'Reorder fulfilled',
      performedBy: 'InventoryAgent',
    },
  });
  
  await logSimpleAction({
    actionType: 'update_inventory',
    targetEntity: 'InventoryAlert',
    targetId: alertId,
    input: { alertId, actualQuantity },
    output: { fulfilled: true },
    confidence: 1.0,
    anomalyDetected: false,
  });
}

// Get inventory stats
export async function getInventoryStats(): Promise<{
  totalProducts: number;
  lowStock: number;
  outOfStock: number;
  pendingAlerts: number;
  orderedAlerts: number;
  recentMovements: number;
}> {
  const [products, lowStockItems, outOfStockItems, pendingAlerts, orderedAlerts, recentMovements] = await Promise.all([
    prisma.product.count({ where: { isActive: true } }),
    prisma.inventoryAlert.count({ where: { status: 'pending', priority: { in: ['low', 'normal'] } } }),
    prisma.inventoryAlert.count({ where: { status: 'pending', priority: { in: ['high', 'critical'] } } }),
    prisma.inventoryAlert.count({ where: { status: 'pending' } }),
    prisma.inventoryAlert.count({ where: { status: 'ordered' } }),
    prisma.stockMovement.count({
      where: { createdAt: { gte: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000) } },
    }),
  ]);
  
  return {
    totalProducts: products,
    lowStock: lowStockItems,
    outOfStock: outOfStockItems,
    pendingAlerts,
    orderedAlerts,
    recentMovements,
  };
}
