/**
 * 庫存計算相關工具函式
 */

import { WarehouseInventory, WarehouseStats, SafetyStockSetting, SafetyStockStatus } from "../types/warehouse";

/**
 * 計算倉庫的總庫存數量
 */
export const calculateTotalQuantity = (
  inventories: WarehouseInventory[],
  warehouseId: string
): number => {
  return inventories
    .filter((inv) => inv.warehouseId === warehouseId)
    .reduce((sum, inv) => sum + inv.quantity, 0);
};

/**
 * 按商品分組計算總庫存
 */
export const calculateProductTotalStock = (
  inventories: WarehouseInventory[],
  productId: string
): number => {
  return inventories
    .filter((inv) => inv.productId === productId)
    .reduce((sum, inv) => sum + inv.quantity, 0);
};

/**
 * 計算安全庫存狀態
 */
export const getSafetyStockStatus = (
  currentStock: number,
  safetyStock: number | null | undefined
): SafetyStockStatus => {
  if (!safetyStock || safetyStock === 0) return "正常";
  if (currentStock < safetyStock) return "低於";
  return "正常";
};

/**
 * 檢查商品是否低於安全庫存
 */
export const isProductLowStock = (
  inventories: WarehouseInventory[],
  productId: string,
  safetyStockSettings: SafetyStockSetting[]
): boolean => {
  const setting = safetyStockSettings.find((s) => s.productId === productId);
  if (!setting) return false;

  const totalStock = calculateProductTotalStock(inventories, productId);
  return totalStock < setting.safetyStock;
};

/**
 * 計算低庫存警告數量（按商品計算）
 */
export const calculateLowStockCount = (
  inventories: WarehouseInventory[],
  warehouseId: string,
  safetyStockSettings: SafetyStockSetting[]
): number => {
  // 取得該倉庫的所有庫存
  const warehouseInventories = inventories.filter(
    (inv) => String(inv.warehouseId) === String(warehouseId)
  );

  // 取得該倉庫的安全庫存設定
  const warehouseSettings = safetyStockSettings.filter(
    (s) => String(s.warehouseId) === String(warehouseId)
  );

  // 計算有多少商品低於安全庫存
  let lowStockCount = 0;
  warehouseSettings.forEach((setting) => {
    // 找出該設定對應的商品庫存
    // 注意：這裡假設一個商品在同一個倉庫只有一種庫存紀錄 (warehouse_inventory table)
    // 如果有批號區分，則需要加總所有該商品的數量
    const productTotalStock = warehouseInventories
      .filter(inv => String(inv.productId) === String(setting.productId))
      .reduce((sum, inv) => sum + inv.quantity, 0);

    // 只有當安全庫存設定存在時才進行判斷 (後端已過濾掉 null)
    // 若設定為 0，則表示允許庫存為 0，不會觸發警告 (除非庫存為負)
    if (productTotalStock < setting.safetyStock) {
      lowStockCount++;
    }
  });

  return lowStockCount;
};

/**
 * 計算待撥補需求數量（按商品計算）
 */
export const calculateReplenishmentNeeded = (
  inventories: WarehouseInventory[],
  warehouseId: string,
  safetyStockSettings: SafetyStockSetting[]
): number => {
  // 取得該倉庫的所有庫存
  const warehouseInventories = inventories.filter(
    (inv) => inv.warehouseId === warehouseId
  );

  // 取得該倉庫的安全庫存設定
  const warehouseSettings = safetyStockSettings.filter(
    (s) => s.warehouseId === warehouseId
  );

  // 計算需要撥補的總量
  let replenishmentNeeded = 0;
  warehouseSettings.forEach((setting) => {
    const productTotalStock = calculateProductTotalStock(
      warehouseInventories,
      setting.productId
    );
    if (productTotalStock < setting.safetyStock) {
      replenishmentNeeded += setting.safetyStock - productTotalStock;
    }
  });

  return replenishmentNeeded;
};

/**
 * 計算倉庫統計資訊
 */
export const calculateWarehouseStats = (
  inventories: WarehouseInventory[],
  warehouseId: string,
  safetyStockSettings: SafetyStockSetting[]
): WarehouseStats => {
  return {
    totalQuantity: calculateTotalQuantity(inventories, warehouseId),
    lowStockCount: calculateLowStockCount(inventories, warehouseId, safetyStockSettings),
    replenishmentNeeded: calculateReplenishmentNeeded(inventories, warehouseId, safetyStockSettings),
  };
};

/**
 * 檢查倉庫是否有庫存警告
 */
export const hasWarehouseWarning = (
  inventories: WarehouseInventory[],
  warehouseId: string,
  safetyStockSettings: SafetyStockSetting[]
): boolean => {
  return calculateLowStockCount(inventories, warehouseId, safetyStockSettings) > 0;
};

/**
 * 過濾倉庫的庫存
 */
export const filterWarehouseInventories = (
  inventories: WarehouseInventory[],
  warehouseId: string
): WarehouseInventory[] => {
  return inventories.filter((inv) => inv.warehouseId === warehouseId);
};