export interface ItemLotTraceLotInfo {
  inventoryLotId: number;
  lotNo: string;
  itemId: number;
  itemCode: string;
  itemName: string;
  expiryDate: string | null;
  productionDate: string | null;
  stockInDate: string | null;
  uom: string;
  primaryStockInLineId: number | null;
}

export interface ItemLotTraceWarehouseLine {
  inventoryLotLineId: number;
  warehouseCode: string;
  inQty: number;
  outQty: number;
  issueQty: number;
  status: string;
  availableQty: number;
}

export interface ItemLotTraceAlternateLocation {
  inventoryLotId: number;
  stockInLineId: number | null;
  inventoryLotLineId: number;
  warehouseCode: string;
  availableQty: number;
}

/**
 * Per-location lifecycle trace block for one alternate inventory_lot
 * sharing the same lotNo+itemId. Contains only location-scoped dimensions.
 * Lot-level dimensions (BOM, JO prelude, production, byproducts, lot relations)
 * are NOT included — they're at the top level of ItemLotTraceResponse.
 */
export interface ItemLotTraceLocationBlock {
  inventoryLotId: number;
  lotNo: string;
  itemCode: string;
  itemName?: string;
  uom?: string;
  expiryDate?: string | null;
  productionDate?: string | null;
  stockInDate?: string | null;
  stockInLineId: number | null;
  warehouseLines: ItemLotTraceWarehouseLine[];
  origins: ItemLotTraceOrigin[];
  purchaseEvents?: ItemLotTracePurchaseEvent[];
  qcResults: ItemLotTraceQcResult[];
  putawayEvents: ItemLotTracePutawayEvent[];
  movements: ItemLotTraceMovement[];
  outboundUsage: ItemLotTraceOutboundUsage[];
  stockTakeEvents: ItemLotTraceStockTakeEvent[];
  adjustments: ItemLotTraceAdjustment[];
  transfers: ItemLotTraceTransfer[];
  openMovements: ItemLotTraceOpenMovement[];
  failEvents: ItemLotTraceFailEvent[];
  doDeliveries: ItemLotTraceDoDelivery[];
  replenishmentEvents?: ItemLotTraceReplenishmentEvent[];
  returnEvents: ItemLotTraceReturnEvent[];
}

export interface ItemLotTraceReplenishmentEvent {
  replenishmentId: number;
  replenishmentCode: string;
  sourceDoCode: string;
  sourceDoId: number | null;
  shopCode: string;
  shopName: string;
  itemNo: string;
  itemName: string;
  reason: string;
  replenishQty: number;
  handler: string;
  timestamp: string | null;
  pickOrderLineId: number | null;
  stockOutLineId: number | null;
}

export interface ItemLotTraceOrigin {
  stockInLineId: number;
  type: string;
  refCode: string;
  refId: number | null;
  supplierCode: string;
  supplierName: string;
  dnNo: string;
  receiptDate: string | null;
  acceptedQty: number;
  status: string;
}

export interface ItemLotTracePurchaseEvent {
  purchaseOrderLineId: number;
  purchaseOrderId: number | null;
  purchaseOrderCode: string;
  itemCode: string;
  itemName: string;
  orderQty: number;
  putAwayQty: number;
  purchaseUnit: string;
  supplierCode: string;
  supplierName: string;
  orderDate: string | null;
  status: string;
}

export interface ItemLotTraceQcResult {
  stockInLineId: number;
  qcPassed: boolean;
  failQty: number;
  acceptedQty: number;
  remarks: string;
  handledBy: string;
  created: string | null;
  qcItemCode?: string;
  qcItemName?: string;
  qcItemDescription?: string;
  qcType?: string;
}

export interface ItemLotTraceMovement {
  direction: string;
  qty: number;
  movementType: string;
  refType: string;
  refCode: string;
  refId: number | null;
  warehouseCode: string;
  handledBy: string;
  timestamp: string | null;
  remarks: string;
  pickConsoCode?: string;
  outboundTicketNo?: string;
  deliveryOrderPickOrderId?: number | null;
  relationshipId?: number | null;
  doOutboundIsExtra?: boolean;
  doOutboundIsReplenish?: boolean;
  doOutboundQtyChanged?: boolean;
  processingStatus?: string;
  matchStatus?: string;
}

export interface ItemLotTracePutawayEvent {
  inventoryLotLineId: number;
  stockInLineId: number | null;
  warehouseCode: string;
  qty: number;
  handledBy: string;
  timestamp: string | null;
  refType: string;
  refCode: string;
  refId: number | null;
  status?: string;
}

export interface ItemLotTraceOutboundUsage {
  stockOutLineId: number;
  qty: number;
  pickOrderCode: string;
  pickOrderId: number | null;
  consoCode: string;
  jobOrderCode: string;
  jobOrderId: number | null;
  deliveryOrderCode: string;
  handler: string;
  timestamp: string | null;
  usageType: string;
}

export interface ItemLotTraceStockTakeRecordDetail {
  stockTakeLineId: number;
  bookQty: number;
  pickerFirstQty?: number | null;
  pickerFirstBadQty?: number | null;
  pickerSecondQty?: number | null;
  pickerSecondBadQty?: number | null;
  approverQty?: number | null;
  approverBadQty?: number | null;
  stockTakerName?: string | null;
  approverName?: string | null;
  stockTakeStartTime?: string | null;
  stockTakeEndTime?: string | null;
  approverTime?: string | null;
  recordStatus?: string | null;
  lastSelect?: number | null;
  varianceQty?: number | null;
}

export interface ItemLotTraceStockTakeEvent {
  stockTakeCode: string;
  lotNo?: string;
  itemCode?: string;
  itemName?: string;
  warehouseCode?: string;
  stockTakeSection?: string;
  stockTakeRoundId?: number | null;
  stockTakeRoundName?: string;
  varianceQty: number;
  beforeQty: number;
  afterQty?: number | null;
  approver: string;
  timestamp: string | null;
  recordDetail?: ItemLotTraceStockTakeRecordDetail | null;
}

export interface ItemLotTraceAdjustment {
  adjustmentType: string;
  direction: string;
  qty: number;
  reason: string;
  handledBy: string;
  timestamp: string | null;
  refCode: string;
  warehouseCode?: string;
}

export interface ItemLotTraceTransfer {
  fromWarehouse: string;
  toWarehouse: string;
  qty: number;
  transferCode: string;
  timestamp: string | null;
}

export interface ItemLotTraceBomDownstream {
  jobOrderCode: string;
  jobOrderId: number | null;
  finishedItemCode: string;
  finishedLotNo: string;
  finishedStockInLineId: number | null;
  fgQty: number;
  fgUom?: string;
  materialQtyUsed: number;
}

export interface ItemLotTraceBomUpstream {
  jobOrderCode: string;
  jobOrderId: number | null;
  materialItemCode: string;
  materialLotNo: string;
  materialStockInLineId: number | null;
  materialQty: number;
  bomQtyPerUnit: number | null;
}

export interface ItemLotTraceBomRecipeLine {
  materialItemCode: string;
  materialItemName: string;
  qtyPerUnit: number;
  uom: string;
  bomProcessId?: number | null;
  bomProcessSeqNo?: number | null;
  assignedStepName?: string;
}

export interface ItemLotTraceStepMaterialRef {
  materialItemCode: string;
  materialItemName: string;
  qtyPerUnit: number;
  uom: string;
}

export interface ItemLotTraceBomTrace {
  direction: string;
  downstream: ItemLotTraceBomDownstream[];
  upstream: ItemLotTraceBomUpstream[];
  bomRecipe: ItemLotTraceBomRecipeLine[];
}

export interface ItemLotTraceJoContext {
  jobOrderId: number;
  jobOrderCode: string;
  planStart: string | null;
  /** Earliest jo_pick_order.created for this JO. */
  createdAt?: string | null;
  reqQty: number;
  status: string;
}

export interface ItemLotTraceJoPickLine {
  pickOrderLineId: number;
  itemCode: string;
  itemName: string;
  requiredQty: number;
  pickedQty: number;
  status: string;
}

export interface ItemLotTraceJoPickOrder {
  pickOrderId: number;
  pickOrderCode: string;
  consoCode: string;
  status: string;
  targetDate: string | null;
  completeDate: string | null;
  releasedDate: string | null;
  lines: ItemLotTraceJoPickLine[];
}

export interface ItemLotTraceMaterialInput {
  jobOrderCode: string;
  jobOrderId: number | null;
  materialItemCode: string;
  materialItemName: string;
  materialLotNo: string;
  materialStockInLineId: number | null;
  materialInventoryLotId: number | null;
  materialQty: number;
  materialUom?: string;
  bomQtyPerUnit: number | null;
  bomProcessId?: number | null;
  bomProcessSeqNo?: number | null;
  assignedStepName?: string;
  pickOrderCode: string;
  pickOrderId: number | null;
  consoCode: string;
  pickedAt: string | null;
  processingStatus?: string;
  matchStatus?: string;
  stockInOrigin: ItemLotTraceOrigin | null;
  purchaseEvents?: ItemLotTracePurchaseEvent[];
  qcResults: ItemLotTraceQcResult[];
  putawayEvents: ItemLotTracePutawayEvent[];
  /** When this material was produced by another JO, its upstream pick/prelude chain. */
  nestedJoPrelude?: ItemLotTraceJoPrelude | null;
  /** Production steps from the JO that produced this material lot. */
  productionSteps?: ItemLotTraceProductionStep[];
}

export interface ItemLotTraceJoPrelude {
  jobOrder: ItemLotTraceJoContext;
  pickOrders: ItemLotTraceJoPickOrder[];
  materialInputs: ItemLotTraceMaterialInput[];
}

export interface ItemLotTraceProductionStep {
  processLineId: number;
  stepName: string;
  description: string;
  equipmentCode: string;
  equipmentName: string;
  operatorName: string;
  startTime: string | null;
  endTime: string | null;
  outputQty: number;
  scrapQty: number;
  defectQty: number;
  status: string;
  seqNo: number | null;
  bomProcessId?: number | null;
  stepMaterials?: ItemLotTraceStepMaterialRef[];
}

/** Sibling byproduct lot from the same job order (independent item/lot, traceable). */
export interface ItemLotTraceByproductLot {
  inventoryLotId: number | null;
  stockInLineId: number | null;
  lotNo: string;
  itemCode: string;
  itemName: string;
  qty: number;
  uom: string;
  processStepName: string;
  producedAt: string | null;
  jobOrderCode: string;
  jobOrderId: number | null;
}

export interface ItemLotTraceOpenMovement {
  stockInLineId: number;
  qty: number;
  warehouseCode: string;
  refCode: string;
  handledBy: string;
  timestamp: string | null;
  remarks: string;
}

export interface ItemLotTraceFailEvent {
  failId: number;
  failType: string;
  category: string;
  qty: number;
  handlerName: string;
  recordDate: string | null;
  pickOrderCode: string;
  pickOrderId: number | null;
}

export interface ItemLotTraceDoDelivery {
  stockOutLineId: number;
  qty: number;
  pickOrderCode: string;
  pickOrderId: number | null;
  consoCode: string;
  ticketNo?: string;
  deliveryOrderCode: string;
  deliveryOrderId: number | null;
  shopCode?: string;
  shopName?: string;
  handler: string;
  timestamp: string | null;
  releaseType?: string | null;
  deliveryOrderPickOrderId?: number | null;
  relationshipId?: number | null;
  deliveryNoteCode?: string;
  doPickOrderRecordId?: number | null;
  isExtra?: boolean;
  isReplenish?: boolean;
  /** True when pick_order_line.qty ≠ SUM(stock_out_line.qty) for that line (改數). */
  qtyChanged?: boolean;
}

export interface ItemLotTraceReturnEvent {
  stockOutLineId: number;
  qty: number;
  refCode: string;
  movementType: string;
  warehouseCode: string;
  handler: string;
  timestamp: string | null;
  remarks: string;
}

export interface ItemLotTraceLotRelation {
  relationType: string;
  inventoryLotId: number | null;
  lotNo: string;
  itemCode: string;
  itemName: string;
  qty: number;
  productLotNo: string;
  timestamp: string | null;
}

export interface ItemLotTraceGraphEdge {
  fromKey: string;
  toKey: string;
  kind?: string;
}

export interface ItemLotTraceGraphNodeRef {
  key: string;
  kind: string;
  scopeKey?: string | null;
  refCode?: string | null;
  traceLotNo?: string | null;
  traceItemCode?: string | null;
  /** Warehouse code for multi-location visual differentiation. */
  warehouseCode?: string | null;
}

export interface ItemLotTraceGraph {
  nodes: ItemLotTraceGraphNodeRef[];
  edges: ItemLotTraceGraphEdge[];
}

export interface ItemLotTraceResponse {
  lot: ItemLotTraceLotInfo;
  warehouseLines: ItemLotTraceWarehouseLine[];
  origins: ItemLotTraceOrigin[];
  purchaseEvents?: ItemLotTracePurchaseEvent[];
  qcResults: ItemLotTraceQcResult[];
  putawayEvents: ItemLotTracePutawayEvent[];
  movements: ItemLotTraceMovement[];
  outboundUsage: ItemLotTraceOutboundUsage[];
  stockTakeEvents: ItemLotTraceStockTakeEvent[];
  adjustments: ItemLotTraceAdjustment[];
  transfers: ItemLotTraceTransfer[];
  bomTrace: ItemLotTraceBomTrace;
  joPrelude: ItemLotTraceJoPrelude | null;
  productionSteps: ItemLotTraceProductionStep[];
  byproductLots: ItemLotTraceByproductLot[];
  openMovements: ItemLotTraceOpenMovement[];
  failEvents: ItemLotTraceFailEvent[];
  doDeliveries: ItemLotTraceDoDelivery[];
  replenishmentEvents?: ItemLotTraceReplenishmentEvent[];
  returnEvents: ItemLotTraceReturnEvent[];
  lotRelations: ItemLotTraceLotRelation[];
  alternateLocations: ItemLotTraceAlternateLocation[];
  /** Per-location full trace blocks for alternate inventory_lot rows sharing same lotNo+itemId.
   * Empty when there is only one location for this lot. */
  locationBlocks?: ItemLotTraceLocationBlock[];
  traceGraph?: ItemLotTraceGraph | null;
}

export interface ItemLotTraceParams {
  stockInLineId?: number;
  inventoryLotLineId?: number;
  lotNo?: string;
  itemId?: number;
  itemCode?: string;
}
