// Per-product aggregate of tracked stock for the products-v2 grid overlay:
// { [productId]: { serialCount, chargeCount, trackedQty, nextMhd, expiredQty, expiringQty } }.
// One bounded m_storageonhand sweep (ASI > 0, stock > 0) per org + chunked ASI
// lookups; cached 60 s per org. `?orgId=` optional (default: session org).
import getTokenHelper from "../../utils/getTokenHelper"
import fetchHelper from "../../utils/fetchHelper"
import withAuthRetry from "../../utils/withAuthRetry"
import { fetchAsis, daysUntil } from "../../utils/attributeTracking"

const enc = encodeURIComponent
const TTL_MS = 60_000
const TOP = 5000
const g = globalThis as any
const cache: Map<string, { at: number; data: any }> = g.__logshipTrackingOverview ?? (g.__logshipTrackingOverview = new Map())

const handleFunc = async (event: any, authToken: any = null) => {
  const token = authToken ?? await getTokenHelper(event)
  const query = getQuery(event)
  const orgId = Number(query.orgId || getCookie(event, 'logship_organization_id')) || 0
  const key = `${getCookie(event, 'logship_client_id')}:${getCookie(event, 'logship_role_id')}:${orgId}`
  const hit = cache.get(key)
  if (hit && Date.now() - hit.at < TTL_MS && !query.refresh) return hit.data

  const filter = [orgId ? `AD_Org_ID eq ${orgId}` : '', 'QtyOnHand gt 0', 'M_AttributeSetInstance_ID gt 0'].filter(Boolean).join(' AND ')
  const res: any = await fetchHelper(event,
    `models/m_storageonhand?$filter=${enc(filter)}&$orderby=${enc('M_Product_ID asc')}&$top=${TOP}`, 'GET', token, null)
  const rows: any[] = res?.records ?? []
  const asis = await fetchAsis(event, token, rows.map((r) => Number(r?.M_AttributeSetInstance_ID?.id ?? r?.M_AttributeSetInstance_ID) || 0))

  const products: Record<string, any> = {}
  for (const r of rows) {
    const pid = Number(r?.M_Product_ID?.id ?? r?.M_Product_ID) || 0
    const asi = asis.get(Number(r?.M_AttributeSetInstance_ID?.id ?? r?.M_AttributeSetInstance_ID) || 0)
    if (!pid || !asi) continue
    const qty = Number(r?.QtyOnHand ?? 0)
    const p = products[pid] ??= { serialCount: 0, chargeCount: 0, chargeAsis: new Set<number>(), trackedQty: 0, nextMhd: '', expiredQty: 0, expiringQty: 0 }
    p.trackedQty += qty
    if (asi.serNo) p.serialCount += 1
    else if (asi.lot || asi.mhd) p.chargeAsis.add(asi.id)
    if (asi.mhd) {
      const d = daysUntil(asi.mhd)
      if (d !== null && d < 0) p.expiredQty += qty
      else if (d !== null && d <= 30) p.expiringQty += qty
      if (!p.nextMhd || asi.mhd < p.nextMhd) p.nextMhd = asi.mhd
    }
  }
  for (const p of Object.values(products)) { p.chargeCount = p.chargeAsis.size; delete p.chargeAsis }

  const data = { status: 200, orgId, products, truncated: rows.length >= TOP, rowCount: rows.length }
  cache.set(key, { at: Date.now(), data })
  return data
}

export default defineEventHandler(async (event) => withAuthRetry(event, handleFunc))
