import { ItemLotTraceLocationBlock, ItemLotTraceResponse } from "@/app/api/itemTracing";

import {

  buildTraceGraphNodes,

  TraceGraphBuildScope,

  TraceGraphDetailLabels,

  TraceGraphNode,

} from "./buildTraceGraphNodes";

import {

  buildExtendedTraceGraphNodes,

  ExtendedTraceGraphLabels,

} from "./buildExtendedTraceGraphNodes";



export const blockWarehouseCode = (block: ItemLotTraceLocationBlock): string =>

  block.warehouseLines

    .map((w) => w.warehouseCode)

    .filter(Boolean)

    .join(" / ") || `Lot #${block.inventoryLotId}`;



const blockToTraceResponse = (block: ItemLotTraceLocationBlock): ItemLotTraceResponse => {

  const uom = block.uom ?? "";

  return {

    lot: {

      inventoryLotId: block.inventoryLotId,

      lotNo: block.lotNo,

      itemId: 0,

      itemCode: block.itemCode,

      itemName: block.itemName ?? "",

      expiryDate: block.expiryDate ?? null,

      productionDate: block.productionDate ?? null,

      stockInDate: block.stockInDate ?? null,

      uom,

      primaryStockInLineId: block.stockInLineId,

    },

    warehouseLines: block.warehouseLines,

    origins: block.origins,

    purchaseEvents: block.purchaseEvents ?? [],

    qcResults: block.qcResults ?? [],

    putawayEvents: block.putawayEvents ?? [],

    movements: block.movements ?? [],

    outboundUsage: block.outboundUsage ?? [],

    stockTakeEvents: block.stockTakeEvents ?? [],

    adjustments: block.adjustments ?? [],

    transfers: block.transfers ?? [],

    bomTrace: { direction: "UNKNOWN", upstream: [], downstream: [], bomRecipe: [] },

    joPrelude: null,

    productionSteps: [],

    byproductLots: [],

    openMovements: block.openMovements ?? [],

    failEvents: block.failEvents ?? [],

    doDeliveries: block.doDeliveries ?? [],

    replenishmentEvents: block.replenishmentEvents ?? [],

    returnEvents: block.returnEvents ?? [],

    lotRelations: [],

    alternateLocations: [],

    locationBlocks: [],

    traceGraph: null,

  };

};



export const buildLocationBlockGraphNodes = (

  block: ItemLotTraceLocationBlock,

  labels: TraceGraphDetailLabels & ExtendedTraceGraphLabels,

): TraceGraphNode[] => {

  const wh = blockWarehouseCode(block);

  const scope: TraceGraphBuildScope = {
    idPrefix: `loc-${block.inventoryLotId}-`,
    locationBlockKeys: true,
    inventoryLotId: block.inventoryLotId,
    defaultWarehouseCode: wh,
    mergedMultiLocation: true,
  };

  const synthetic = blockToTraceResponse(block);

  const fgNodes = buildTraceGraphNodes(synthetic, labels, scope);

  const extNodes =

    labels.nodeOpen && labels.nodeFail && labels.nodeDoOut

      ? buildExtendedTraceGraphNodes(synthetic, labels, scope)

      : [];



  return [...fgNodes, ...extNodes].sort((a, b) => {

    if (a.sortKey !== b.sortKey) return a.sortKey - b.sortKey;

    return a.id.localeCompare(b.id);

  });

};



export const buildAllLocationBlockGraphNodes = (

  blocks: ItemLotTraceLocationBlock[],

  labels: TraceGraphDetailLabels & ExtendedTraceGraphLabels,

): TraceGraphNode[] =>

  (blocks ?? []).flatMap((block) => buildLocationBlockGraphNodes(block, labels));

