import { string } from 'alga-js'
import refreshTokenHelper from "../../utils/refreshTokenHelper"
import forceLogoutHelper from "../../utils/forceLogoutHelper"
import errorHandlingHelper from "../../utils/errorHandlingHelper"
import getTokenHelper from "../../utils/getTokenHelper"
import { odataQuote } from "../../utils/odataHelper"

const handleFunc = async (event: any, authToken: any = null) => {
  const token = authToken ?? await getTokenHelper(event)
  const body = await readBody(event)
  const locatorValue = body?.locatorValue || ''

  if (!locatorValue) {
    throw createError({
      statusCode: 400,
      statusMessage: 'Locator value is required'
    })
  }

  // Step 1: Find all locators matching the value (across organizations)
  const locatorFilter = string.urlEncode(`Value eq '${odataQuote(locatorValue)}' AND IsActive eq true`)
  const locatorsRes: any = await event.context.fetch(
    `models/m_locator?$filter=${locatorFilter}`,
    'GET',
    token,
    null
  )

  if (!locatorsRes?.records || locatorsRes.records.length === 0) {
    throw createError({
      statusCode: 404,
      statusMessage: 'Locator not found'
    })
  }

  const locators = locatorsRes.records

  // Use a map to group articles by productId + orgId (unique key)
  const articleMap: Map<string, any> = new Map()

  // Step 2: ONE storage query for all matching locators (was one query per
  // locator), with an explicit $top — without it iDempiere's default page
  // size silently truncated high-SKU locators.
  const locatorById = new Map(locators.map((l: any) => [Number(l.id), l]))
  const storageFilter = string.urlEncode(
    '(' + locators.map((l: any) => `M_Locator_ID eq ${Number(l.id)}`).join(' OR ') + ') AND QtyOnHand gt 0'
  )
  const storageRes: any = await event.context.fetch(
    `models/M_StorageOnHand?$filter=${storageFilter}&$expand=${string.urlEncode('M_Product_ID')}&$top=5000`,
    'GET',
    token,
    null
  )

  {
    if (storageRes?.records && storageRes.records.length > 0) {
      for (const storage of storageRes.records) {
        const locator = locatorById.get(Number(storage.M_Locator_ID?.id ?? storage.M_Locator_ID))
        if (!locator) continue
        const locatorId = locator.id
        const orgId = locator.AD_Org_ID?.id || locator.AD_Org_ID
        const orgName = locator.AD_Org_ID?.identifier || locator.AD_Org_ID?.Name || 'Unknown'
        const warehouseId = locator.M_Warehouse_ID?.id || locator.M_Warehouse_ID
        const warehouseName = locator.M_Warehouse_ID?.identifier || locator.M_Warehouse_ID?.Name || 'Unknown'
        const product = storage.M_Product_ID || {}
        const qtyOnHand = Number(storage.QtyOnHand) || 0

        if (qtyOnHand > 0 && product.id) {
          // Create unique key: productId + orgId
          const key = `${product.id}-${orgId}`

          if (articleMap.has(key)) {
            // Sum up the quantity
            const existing = articleMap.get(key)
            existing.qtyOnHand += qtyOnHand
          } else {
            // Add new article entry
            articleMap.set(key, {
              // Product info
              productId: product.id,
              productName: product.Name || 'Unknown Product',
              productValue: product.Value || '',
              productSKU: product.SKU || '',
              productMPN: product.mpn || product.MPN || '',
              productUPC: product.UPC || '',
              productWeight: product.Weight || 0,
              // Strapi info for image
              strapiProductDocumentId: product.Strapi_Product_documentId || null,
              // Quantity (will be summed)
              qtyOnHand: qtyOnHand,
              // Locator info
              locatorId: locatorId,
              locatorValue: locator.Value || '',
              // Organization info
              orgId: orgId,
              orgName: orgName,
              // Warehouse info
              warehouseId: warehouseId,
              warehouseName: warehouseName
            })
          }
        }
      }
    }
  }

  // Convert map to array
  const articles = Array.from(articleMap.values())

  // Sort by organization name, then by product name
  articles.sort((a, b) => {
    if (a.orgName !== b.orgName) {
      return a.orgName.localeCompare(b.orgName)
    }
    return a.productName.localeCompare(b.productName)
  })

  return {
    locatorValue: locatorValue,
    totalArticles: articles.length,
    articles: articles
  }
}

export default defineEventHandler(async (event) => {
  // Auth-only retry: a business 404 no longer triggers a token refresh.
  return await withAuthRetry(event, handleFunc)
})
