const ACTIVE_STOCKTAKE_STATUSES = new Set(["LOCKED", "EXPORTED", "IMPORTED"]);
const STOCKTAKE_SUMMARY_COUNT_KEYS = [
  "match_count",
  "gain_count",
  "loss_count",
  "new_lot_count",
  "missing_count",
  "error_count"
];

export function normalizeStocktakeStatus(status) {
  return String(status || "").trim().toUpperCase();
}

export function stocktakeSummaryLineCount(summary = {}) {
  return STOCKTAKE_SUMMARY_COUNT_KEYS.reduce((total, key) => total + Number(summary?.[key] || 0), 0);
}

export function isEmptyStocktakeRead(stocktake) {
  const summary = stocktake?.summary;
  const hasKnownSummaryCount =
    summary &&
    typeof summary === "object" &&
    STOCKTAKE_SUMMARY_COUNT_KEYS.some((key) => Object.prototype.hasOwnProperty.call(summary, key));
  return Boolean(hasKnownSummaryCount) && stocktakeSummaryLineCount(summary) === 0;
}

export function canContinueStocktake(row) {
  return ACTIVE_STOCKTAKE_STATUSES.has(normalizeStocktakeStatus(row?.status));
}

export function nextStocktakePanel(stocktake) {
  const status = normalizeStocktakeStatus(stocktake?.status);
  if (!stocktake) return "overview";
  if (status === "LOCKED") return "export";
  if (status === "EXPORTED") return isEmptyStocktakeRead(stocktake) ? "diff" : "import";
  if (status === "IMPORTED") return "diff";
  return "history";
}

export function findActiveStocktakeForWarehouse(historyRows = [], warehouseId) {
  const id = Number(warehouseId || 0);
  if (!id) return null;
  return (
    historyRows.find(
      (row) =>
        canContinueStocktake(row) &&
        Array.isArray(row.warehouses) &&
        row.warehouses.some((warehouse) => Number(warehouse.warehouse_id) === id)
    ) || null
  );
}

export function stocktakeBelongsToWarehouse(row, warehouseId) {
  const id = Number(warehouseId || 0);
  if (!id || !Array.isArray(row?.warehouses)) return false;
  return row.warehouses.some((warehouse) => Number(warehouse.warehouse_id) === id);
}

export function filterStocktakesForWarehouse(historyRows = [], warehouseId) {
  return historyRows.filter((row) => stocktakeBelongsToWarehouse(row, warehouseId));
}

export function findOnlyActiveStocktake(historyRows = []) {
  const rows = historyRows.filter((row) => canContinueStocktake(row));
  return rows.length === 1 ? rows[0] : null;
}

export function hasBlockingDiffErrors(lines = []) {
  return lines.some((line) => String(line?.row_status || "").toUpperCase() === "ERROR");
}

export function hasStocktakeDiff(line) {
  const diffType = normalizeStocktakeStatus(line?.diff_type || "MATCH");
  return diffType !== "MATCH" || String(line?.row_status || "").toUpperCase() === "ERROR";
}

export function splitDiffLines(lines = [], filter = "ALL") {
  const normalizedFilter = normalizeStocktakeStatus(filter || "ALL");
  return [...lines]
    .filter((line) => {
      if (normalizedFilter === "ERROR") return String(line?.row_status || "").toUpperCase() === "ERROR";
      if (normalizedFilter === "DIFF") return hasStocktakeDiff(line);
      return true;
    })
    .sort((left, right) => {
      const leftError = String(left?.row_status || "").toUpperCase() === "ERROR" ? 0 : 1;
      const rightError = String(right?.row_status || "").toUpperCase() === "ERROR" ? 0 : 1;
      if (leftError !== rightError) return leftError - rightError;
      const leftMatch = normalizeStocktakeStatus(left?.diff_type) === "MATCH" ? 1 : 0;
      const rightMatch = normalizeStocktakeStatus(right?.diff_type) === "MATCH" ? 1 : 0;
      if (leftMatch !== rightMatch) return leftMatch - rightMatch;
      return Number(left?.line_no || left?.id || 0) - Number(right?.line_no || right?.id || 0);
    });
}

export function diffTone(line) {
  if (String(line?.row_status || "").toUpperCase() === "ERROR") return "error";
  const diffType = normalizeStocktakeStatus(line?.diff_type || "MATCH");
  if (diffType === "GAIN") return "gain";
  if (diffType === "LOSS") return "loss";
  if (diffType === "NEW_LOT") return "new";
  if (diffType === "MISSING") return "missing";
  return "match";
}

export function warehouseStocktakeStatus(warehouse, historyRows = []) {
  const activeStocktake = findActiveStocktakeForWarehouse(historyRows, warehouse?.id);
  const status = normalizeStocktakeStatus(activeStocktake?.status);
  return {
    locked: Boolean(activeStocktake),
    activeStocktake,
    status,
    label:
      {
        LOCKED: "盘库中",
        EXPORTED: "已导出待导入",
        IMPORTED: "已导入待确认"
      }[status] || "可盘库"
  };
}
