// One typed client method per stock-enquiry endpoint (docs/11-BACKEND-PHASE1.md §5.1-5.3, §5.7).
// In-memory Stock Core (lib/api/mock-data.ts) — no backend API calls.
import { PagedResponse } from "@/types/common"
import { LedgerEntry, OnHand, ReorderAlert, ReorderRequisitionResponse, Valuation } from "@/types/stock"
import {
  allocateReqLineId,
  allocateRequisitionId,
  computeOnHand,
  knownStockKeys,
  mockDelay,
  mockItemReorders,
  mockRequisitions,
  mockStockLayers,
  mockStockLedger,
} from "@/lib/api/mock-data"

export interface LedgerQuery {
  itemId?: number
  warehouseId?: number
  from?: string
  to?: string
  page?: number
  pageSize?: number
}

export const stockApi = {
  onHand(itemId: number, warehouseId: number): Promise<OnHand> {
    const computed = computeOnHand(itemId, warehouseId)
    return mockDelay({
      itemId,
      warehouseId,
      ...computed,
      asOf: new Date().toISOString(),
    })
  },

  /** Every item/warehouse pair currently on record — the Enquiry screen's row source. */
  onHandList(): Promise<OnHand[]> {
    const rows = knownStockKeys().map(({ itemId, warehouseId }) => ({
      itemId,
      warehouseId,
      ...computeOnHand(itemId, warehouseId),
      asOf: new Date().toISOString(),
    }))
    return mockDelay(rows)
  },

  ledger(params: LedgerQuery): Promise<PagedResponse<LedgerEntry>> {
    const from = params.from ? new Date(params.from).getTime() : null
    const to = params.to ? new Date(params.to).getTime() : null

    const filtered = mockStockLedger
      .filter((e) => !params.itemId || e.itemId === params.itemId)
      .filter((e) => !params.warehouseId || e.warehouseId === params.warehouseId)
      .filter((e) => from === null || new Date(e.createdAt).getTime() >= from)
      .filter((e) => to === null || new Date(e.createdAt).getTime() <= to)
      .sort((a, b) => b.ledgerId - a.ledgerId)

    const page = params.page ?? 1
    const pageSize = params.pageSize ?? 20
    const start = (page - 1) * pageSize
    const items = filtered.slice(start, start + pageSize)

    return mockDelay({
      items,
      pagination: {
        page,
        pageSize,
        totalItems: filtered.length,
        totalPages: pageSize <= 0 ? 0 : Math.ceil(filtered.length / pageSize),
      },
    })
  },

  valuation(itemId: number, warehouseId: number): Promise<Valuation> {
    const layers = mockStockLayers
      .filter((l) => l.itemId === itemId && l.warehouseId === warehouseId && l.qtyRemaining > 0)
      .sort((a, b) => new Date(a.receiptDate).getTime() - new Date(b.receiptDate).getTime())
      .map((l) => ({
        layerId: l.layerId,
        qtyRemaining: l.qtyRemaining,
        unitCost: l.unitCost,
        value: Math.round(l.qtyRemaining * l.unitCost * 100) / 100,
        receiptDate: l.receiptDate,
      }))

    const totalQty = layers.reduce((sum, l) => sum + l.qtyRemaining, 0)
    const totalValue = Math.round(layers.reduce((sum, l) => sum + l.value, 0) * 100) / 100

    return mockDelay({
      itemId,
      warehouseId,
      layers,
      totalQty,
      totalValue,
      currency: "LKR",
      costingMethod: "FIFO",
    })
  },

  reorderAlerts(warehouseId?: number): Promise<PagedResponse<ReorderAlert>> {
    const items = mockItemReorders
      .filter((r) => !warehouseId || r.warehouseId === warehouseId)
      .map((r) => ({ ...r, available: computeOnHand(r.itemId, r.warehouseId).available }))
      .filter((r) => r.available <= r.reorderPoint)
      .map((r) => ({
        itemId: r.itemId,
        warehouseId: r.warehouseId,
        available: r.available,
        reorderPoint: r.reorderPoint,
        reorderQty: r.reorderQty,
        suggestedRequisitionQty: r.reorderQty,
      }))

    return mockDelay({
      items,
      pagination: { page: 1, pageSize: 20, totalItems: items.length, totalPages: 1 },
    })
  },

  createReorderRequisition(itemId: number, warehouseId: number): Promise<ReorderRequisitionResponse> {
    const setting = mockItemReorders.find((r) => r.itemId === itemId && r.warehouseId === warehouseId)
    const qty = setting?.reorderQty ?? 0
    const requisitionId = allocateRequisitionId()
    const requiredBy = new Date(Date.now() + 14 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10)

    // Genuinely lands in the Requisitions list (§3), not a fabricated response —
    // same "wire mock modules together" posture as GRN confirm → Stock Core.
    mockRequisitions.push({
      requisitionId,
      docNo: `PR-2026-${String(requisitionId).padStart(5, "0")}`,
      status: "Draft",
      requestedBy: 17,
      createdAt: new Date().toISOString(),
      lines: [{ reqLineId: allocateReqLineId(), itemId, qty, requiredBy }],
    })

    return mockDelay({
      requisitionId,
      docNo: `PR-2026-${String(requisitionId).padStart(5, "0")}`,
      itemId,
      warehouseId,
      qty,
      status: "Draft",
    })
  },
}
