function normalizeWarehouseType(row) {
  return String(row?.warehouse_type || "").toUpperCase();
}

function numericValue(value) {
  const num = Number(value || 0);
  return Number.isFinite(num) ? num : 0;
}

function hasAvailableStock(row, weightOnly) {
  if (weightOnly) {
    return numericValue(row.weight_available_kg) > 0;
  }
  return numericValue(row.qty_available) > 0 || numericValue(row.weight_available_kg) > 0;
}

function mergeMeasureBasis(current, next) {
  const normalizedCurrent = String(current || "").toUpperCase();
  const normalizedNext = String(next || "").toUpperCase();
  if (!normalizedCurrent) {
    return normalizedNext;
  }
  if (!normalizedNext || normalizedCurrent === normalizedNext) {
    return normalizedCurrent;
  }
  return "MIXED";
}

function isWeightOnlyTab(tab) {
  return ["raw", "auxiliary", "scrap"].includes(String(tab || ""));
}

function normalizeText(value) {
  return String(value || "").trim();
}

function operationDisplayName(operation) {
  const seqNoText = normalizeText(operation?.seq_no);
  const operationName = normalizeText(operation?.operation_name);
  const stampingMethod = normalizeText(operation?.stamping_method || operation?.stampingMethod);
  const fallbackName = operationName && operationName !== seqNoText ? operationName : "";
  return stampingMethod || fallbackName;
}

export function buildProductOperationOptions(processRoutes = []) {
  return processRoutes
    .filter((route) => String(route.status || "").toUpperCase() === "ACTIVE")
    .flatMap((route) =>
      (route.operations || [])
        .filter((operation) => String(operation.status || "").toUpperCase() === "ACTIVE")
        .map((operation) => {
          const seqNo = Number(operation.seq_no || 0);
          const displayName = operationDisplayName(operation);
          const operationLabel = `第${seqNo}道${displayName ? ` ${displayName}` : ""}`;
          return {
            option_key: `${Number(route.product_item_id)}::${Number(operation.route_operation_id)}`,
            item_id: Number(route.product_item_id),
            item_code: route.product_code || "",
            item_name: route.product_name || "",
            version_no: route.version_no || "",
            route_id: Number(route.route_id),
            source_doc_id: Number(route.route_id),
            route_operation_id: Number(operation.route_operation_id),
            source_line_id: Number(operation.route_operation_id),
            seq_no: seqNo,
            operation_name: operation.operation_name || operation.process_name || "",
            stamping_method: operation.stamping_method || "",
            operation_label: operationLabel,
            source_material_summary: `产品：${route.product_name || "-"}；已完成工序：${operationLabel}`
          };
        })
    )
    .sort((left, right) => {
      const codeOrder = String(left.item_code || "").localeCompare(String(right.item_code || ""), "zh-CN", { numeric: true });
      return codeOrder || Number(left.seq_no || 0) - Number(right.seq_no || 0);
    });
}

export function buildOutboundItemOptions({ balances = [], warehouseId = "", warehouseType = "", activeInventoryTab = "" } = {}) {
  const normalizedWarehouseType = String(warehouseType || "").toUpperCase();
  const selectedWarehouseId = Number(warehouseId || 0);
  const weightOnly = isWeightOnlyTab(activeInventoryTab) || ["RAW", "AUX", "SCRAP"].includes(normalizedWarehouseType);
  const groupByOperation = activeInventoryTab === "semi" || normalizedWarehouseType === "SEMI";
  const optionMap = new Map();

  balances
    .filter((row) => {
      if (selectedWarehouseId && Number(row.warehouse_id || 0) !== selectedWarehouseId) {
        return false;
      }
      if (!selectedWarehouseId && normalizedWarehouseType && normalizeWarehouseType(row) !== normalizedWarehouseType) {
        return false;
      }
      return hasAvailableStock(row, weightOnly);
    })
    .forEach((row) => {
      const itemId = Number(row.item_id || 0);
      if (!itemId) {
        return;
      }
      const optionKey = groupByOperation ? `${itemId}::${Number(row.source_line_id || 0)}` : itemId;
      const current = optionMap.get(optionKey);
      if (!current) {
        optionMap.set(optionKey, {
          option_key: groupByOperation ? String(row.option_key || optionKey) : String(row.option_key || itemId),
          item_id: itemId,
          item_code: row.item_code || "",
          item_name: row.item_name || "",
          version_no: row.version_no || "",
          source_line_id: row.source_line_id || null,
          route_operation_id: row.source_line_id || row.route_operation_id || null,
          route_id: row.source_doc_id || row.route_id || null,
          operation_label: row.operation_label || row.source_material_summary || "",
          qty_available: numericValue(row.qty_available),
          weight_available_kg: numericValue(row.weight_available_kg),
          measure_basis: String(row.measure_basis || "").toUpperCase(),
          avg_unit_cost: numericValue(row.avg_unit_cost),
          warehouse_id: row.warehouse_id,
          warehouse_type: row.warehouse_type
        });
        return;
      }
      current.qty_available += numericValue(row.qty_available);
      current.weight_available_kg += numericValue(row.weight_available_kg);
      current.measure_basis = mergeMeasureBasis(current.measure_basis, row.measure_basis);
      const currentWeight = numericValue(current.weight_available_kg);
      const rowWeight = numericValue(row.weight_available_kg);
      if (rowWeight > 0 && currentWeight > 0) {
        current.avg_unit_cost =
          (numericValue(current.avg_unit_cost) * (currentWeight - rowWeight) + numericValue(row.avg_unit_cost) * rowWeight) / currentWeight;
      }
    });

  return Array.from(optionMap.values()).sort((left, right) => {
    const codeOrder = String(left.item_code || "").localeCompare(String(right.item_code || ""), "zh-CN", { numeric: true });
    return (
      codeOrder ||
      String(left.item_name || "").localeCompare(String(right.item_name || ""), "zh-CN", { numeric: true }) ||
      Number(left.source_line_id || 0) - Number(right.source_line_id || 0)
    );
  });
}

export function buildGenericItemOptions({
  direction = "in",
  activeInventoryTab = "raw",
  activeWarehouseType = "",
  warehouseId = "",
  balances = [],
  materials = [],
  products = [],
  productOperations = []
} = {}) {
  if (String(direction || "").toLowerCase() === "out") {
    return buildOutboundItemOptions({
      balances,
      warehouseId,
      warehouseType: activeWarehouseType,
      activeInventoryTab
    });
  }
  if (activeInventoryTab === "semi" || String(activeWarehouseType || "").toUpperCase() === "SEMI") {
    return productOperations;
  }
  if (activeInventoryTab === "scrap" || String(activeWarehouseType || "").toUpperCase() === "SCRAP") {
    return [...materials, ...products];
  }
  if (["raw", "auxiliary"].includes(activeInventoryTab)) {
    return materials;
  }
  if (activeInventoryTab === "return" || String(activeWarehouseType || "").toUpperCase() === "RETURN") {
    return products;
  }
  return products;
}
