// "Wastage" is not a distinct document type in docs/10-BACKEND-PHASE1.md or the
// SRS — stock write-offs (damage, theft/loss, expiry) are modeled as Stock
// Adjustments with a mandatory reason code (FR-STK-07), and the reason-code seed
// list (docs/8.3 / docs/11 §6) already includes Damage / Theft-Loss / Expiry
// Write-off. This module is a frontend-only lens: it reuses stockAdjustmentsApi
// and the shared mock Stock Core, filtered to loss-type reason codes and
// flattened to per-line records for a focused "record wastage" flow and report.
// No new backend concept, no new mock store.
import { stockAdjustmentsApi } from "@/lib/api/stock-adjustments"
import { mockDelay, mockReasonCodes, mockStockAdjustments, mockStockLedger } from "@/lib/api/mock-data"
import { StockAdjustment } from "@/types/stock"

/** Reason-code strings treated as "wastage" (loss-type) causes, per docs/8.3. */
const WASTAGE_CODES = new Set(["DMG", "LOSS", "EXPWO"])

export function wastageReasonCodeIds(): number[] {
  return mockReasonCodes.filter((r) => WASTAGE_CODES.has(r.code)).map((r) => r.reasonCodeId)
}

export interface WastageRecord {
  adjustmentId: number
  adjLineId: number
  docNo: string
  createdAt: string
  warehouseId: number
  itemId: number
  binId: number | null
  reasonCodeId: number
  /** Positive quantity wasted (the underlying adjustment line is a negative qtyDelta). */
  qty: number
  /** FIFO cost of the wasted quantity, summed from the matching outbound ledger entries. */
  value: number
}

export interface ListWastageParams {
  warehouseId?: number
  reasonCodeId?: number
}

export interface RecordWastageInput {
  warehouseId: number
  itemId: number
  binId?: number | null
  qty: number
  reasonCodeId: number
}

export const wastageApi = {
  list(params: ListWastageParams = {}): Promise<WastageRecord[]> {
    const wastageIds = new Set(wastageReasonCodeIds())
    const records: WastageRecord[] = []

    for (const adj of mockStockAdjustments) {
      if (!wastageIds.has(adj.reasonCodeId)) continue
      if (params.warehouseId && adj.warehouseId !== params.warehouseId) continue
      if (params.reasonCodeId && adj.reasonCodeId !== params.reasonCodeId) continue

      for (const line of adj.lines) {
        if (line.qtyDelta >= 0) continue // wastage is always a decrease

        const value = mockStockLedger
          .filter(
            (l) =>
              l.sourceDocType === "Adjustment" &&
              l.sourceDocId === adj.adjustmentId &&
              l.itemId === line.itemId &&
              l.direction === "Out"
          )
          .reduce((sum, l) => sum + l.value, 0)

        records.push({
          adjustmentId: adj.adjustmentId,
          adjLineId: line.adjLineId,
          docNo: adj.docNo,
          createdAt: adj.createdAt,
          warehouseId: adj.warehouseId,
          itemId: line.itemId,
          binId: line.binId,
          reasonCodeId: adj.reasonCodeId,
          qty: Math.abs(line.qtyDelta),
          value: Math.round(value * 100) / 100,
        })
      }
    }

    records.sort((a, b) => b.adjustmentId - a.adjustmentId)
    return mockDelay(records)
  },

  /** Records wastage as a single-line, negative-qtyDelta stock adjustment (FR-STK-07). */
  record(input: RecordWastageInput): Promise<StockAdjustment> {
    return stockAdjustmentsApi.create({
      warehouseId: input.warehouseId,
      reasonCodeId: input.reasonCodeId,
      lines: [{ itemId: input.itemId, binId: input.binId ?? null, qtyDelta: -Math.abs(input.qty) }],
    })
  },
}
