import { string } from 'alga-js'
import refreshTokenHelper from "../../../utils/refreshTokenHelper"
import forceLogoutHelper from "../../../utils/forceLogoutHelper"
import errorHandlingHelper from "../../../utils/errorHandlingHelper"
import fetchHelper from "../../../utils/fetchHelper"
import { fetchProductsWithStorage } from '../../../utils/productStorageHelper'
import getReturnLocatorIds from '../../../utils/returnLocatorHelper'

const handleFunc = async (event: any, authToken: any = null) => {
  let data: any = { records: [], 'row-count': 0 }
  const token = authToken ?? await getTokenHelper(event)
  const query = getQuery(event)
  const orgId = query?.org_id as string

  if (!orgId) {
    return { status: 400, message: 'Organization ID is required', records: [], 'row-count': 0 }
  }

  // Build filter for products owned by organization
  const orgFilter = string.urlEncode(`AD_Org_ID eq ${orgId} and IsActive eq true`)

  // Return locators (locator type with all IsAvailableFor* flags = false) across every
  // org — stock of this org's products may sit in another org's warehouse. Cached in
  // the helper; fail-soft (empty set → nothing is flagged as return stock).
  const returnLocatorIds = await getReturnLocatorIds(event, token, null)

  // Fetch products with storage data
  const res: any = await fetchProductsWithStorage(
    event,
    token,
    `models/m_product?$select=${string.urlEncode('M_Product_ID,Name,SKU,UPC,Value,mpn,AD_Org_ID')}&$expand=AD_Org_ID($select=Name)&$filter=${orgFilter}&$orderby=${string.urlEncode('Name asc')}&$top=5000`
  )

  if (res?.records) {
    // Transform records to include aggregated QtyOnHand
    const transformedRecords = res.records.map((product: any) => {
      const storages = product?.M_Storage || []
      let totalQtyOnHand = 0
      // Portion of the total that sits on return (non-shippable) locators
      let returnQtyOnHand = 0

      if (Array.isArray(storages)) {
        for (const storage of storages) {
          const qty = Number(storage?.QtyOnHand || 0)
          totalQtyOnHand += qty
          const locatorId = Number(storage?.M_Locator_ID?.id ?? storage?.M_Locator_ID)
          if (Number.isFinite(locatorId) && returnLocatorIds.has(locatorId)) {
            returnQtyOnHand += qty
          }
        }
      }

      return {
        id: product.id || product.M_Product_ID,
        productId: product.M_Product_ID,
        name: product.Name || '',
        sku: product.SKU || '',
        ean: product.UPC || '',
        value: product.Value || '',
        mpn: product.mpn || '',
        qtyOnHand: totalQtyOnHand,
        returnQtyOnHand,
        organization: product.AD_Org_ID?.Name || '',
        organizationId: product.AD_Org_ID?.id || orgId
      }
    })

    data = {
      status: 200,
      records: transformedRecords,
      'row-count': transformedRecords.length
    }
  }

  return data
}

export default defineEventHandler(async (event) => {
  let data: any = {}

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

  return data
})