import fetchHelper from "../../../utils/fetchHelper"
import getTokenHelper from "../../../utils/getTokenHelper"
import refreshTokenHelper from "../../../utils/refreshTokenHelper"
import errorHandlingHelper from "../../../utils/errorHandlingHelper"

/**
 * Live stock quantities for a set of products — used to asynchronously enrich
 * search results AFTER they render (stock is volatile, so it is NOT held in ES).
 * Also returns a combined `isBom` flag (standard IsBOM OR custom isJtlBom), since
 * those flags are not in the ES product index.
 *
 * POST /api/materials/products/quantities   body: { ids: number[] }
 * -> { quantities: { <m_product_id>: { qtyonhand, qtyreserved, qtyordered, qtyavailable, isBom } } }
 */
const num = (v: any) => (typeof v === 'number' ? v : parseFloat(v) || 0)

const handleFunc = async (event: any, ids: number[], authToken: string | null = null) => {
  const token = authToken ?? await getTokenHelper(event)
  const filter = '(' + ids.map(id => `M_Product_ID eq ${id}`).join(' or ') + ')'
  const storageUrl = `models/m_storage?$filter=${filter}&$expand=M_Locator_ID&$select=M_Product_ID,QtyOnHand,QtyReserved,QtyOrdered`
  // NB: isJtlBom is a lowercase-first custom column — PascalCase 'IsJtlBom' is rejected by $select.
  const productUrl = `models/m_product?$filter=${filter}&$select=M_Product_ID,IsBOM,isJtlBom`
  const [res, prodRes]: any = await Promise.all([
    fetchHelper(event, storageUrl, 'GET', token, null),
    // best-effort: a bom-fetch failure must never break the (critical) quantities
    fetchHelper(event, productUrl, 'GET', token, null).catch(() => null)
  ])

  const q: Record<number, any> = {}
  for (const id of ids) q[id] = { qtyonhand: 0, qtyreserved: 0, qtyordered: 0, qtyavailable: 0, isBom: false }
  for (const row of (res?.records || [])) {
    const pid = row?.M_Product_ID?.id ?? row?.M_Product_ID
    if (pid == null || !q[pid]) continue
    q[pid].qtyonhand  += num(row.QtyOnHand)
    q[pid].qtyreserved += num(row.QtyReserved)
    q[pid].qtyordered += num(row.QtyOrdered)
  }
  for (const row of (prodRes?.records || [])) {
    const pid = row?.id ?? row?.M_Product_ID?.id ?? row?.M_Product_ID
    if (pid == null || !q[pid]) continue
    q[pid].isBom = row.IsBOM === true || row.IsBOM === 'Y' || row.isJtlBom === true || row.isJtlBom === 'Y'
  }
  for (const id of ids) q[id].qtyavailable = q[id].qtyonhand - q[id].qtyreserved
  return { quantities: q }
}

export default defineEventHandler(async (event) => {
  const body = await readBody(event)
  const ids: number[] = Array.from(new Set((body?.ids || []).map((x: any) => Number(x)).filter(Boolean)))
  if (!ids.length) return { quantities: {} }

  let data: any = {}
  try {
    data = await handleFunc(event, ids)
  } catch (err: any) {
    try {
      const authToken = await refreshTokenHelper(event)
      data = await handleFunc(event, ids, authToken)
    } catch (error: any) {
      data = errorHandlingHelper(err?.data ?? err, error?.data ?? error)
    }
  }
  return data
})
