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

// Sums QtyOnHand from a product's M_Storage rows, excluding storages that sit
// on "return" locators (M_LocatorType with all three IsAvailableFor* flags = false).
const sumSellableQty = (storages: any[], returnLocatorIds: Set<number>) => {
  let qtyOnHand = 0
  let returnQtyOnHand = 0
  if (!Array.isArray(storages)) return { qtyOnHand, returnQtyOnHand }
  for (const row of storages) {
    const qty = Number(row?.QtyOnHand || 0)
    const locator = row?.M_Locator_ID
    const locatorId = locator?.id ?? locator
    const isReturn =
      locatorId !== undefined && locatorId !== null && returnLocatorIds.has(Number(locatorId))
    if (isReturn) {
      returnQtyOnHand += qty
    } else {
      qtyOnHand += qty
    }
  }
  return { qtyOnHand, returnQtyOnHand }
}

const handleFunc = async (event: any, authToken: any = null) => {
  const token = authToken ?? await getTokenHelper(event)
  const query = getQuery(event)
  const jfsku = (query?.jfsku as string)?.trim()
  const merchantSku = (query?.merchantSku as string)?.trim()

  if(!jfsku && !merchantSku) {
    return { status: 400, message: 'jfsku or merchantSku is required' }
  }

  try {
    let product: any = null
    let storages: any[] = []

    const productSelect = string.urlEncode('m_product_id,Name,SKU,jfsku,AD_Org_ID')
    const storageExpand = string.urlEncode('M_Storage($expand=M_Locator_ID)')

    if(jfsku) {
      const escaped = jfsku.replace(/'/g, "''")
      const filter = string.urlEncode(`jfsku eq '${escaped}'`)
      const res: any = await fetchHelper(
        event,
        `models/m_product?$select=${productSelect}&$expand=${storageExpand}&$filter=${filter}`,
        'GET',
        token,
        null
      )
      if(res?.records?.length) {
        product = res.records[0]
        storages = product?.M_Storage || []
      }

      // Last-resort fallback: some installations used jsfsku column; try only if strict jfsku failed
      if(!product) {
        const filter2 = string.urlEncode(`jsfsku eq '${escaped}'`)
        const res2: any = await fetchHelper(
          event,
          `models/m_product?$select=${string.urlEncode('m_product_id,Name,SKU,jsfsku,AD_Org_ID')}&$expand=${storageExpand}&$filter=${filter2}`,
          'GET',
          token,
          null
        )
        if(res2?.records?.length) {
          product = res2.records[0]
          storages = product?.M_Storage || []
        }
      }
    }

    // Fallback by merchantSku (SKU) if provided and nothing matched above
    if(!product && merchantSku) {
      const escapedSku = merchantSku.replace(/'/g, "''")
      const res3: any = await fetchHelper(
        event,
        `models/m_product?$select=${productSelect}&$expand=${storageExpand}&$filter=${string.urlEncode(`SKU eq '${escapedSku}'`)}`,
        'GET',
        token,
        null
      )
      if(res3?.records?.length) {
        product = res3.records[0]
        storages = product?.M_Storage || []
      }
    }

    if(!product) {
      return { status: 404, message: 'Product not found', jfsku, merchantSku, qtyOnHand: 0, returnQtyOnHand: 0 }
    }

    const productOrgId = product?.AD_Org_ID?.id ?? product?.AD_Org_ID ?? null
    const returnLocatorIds = await getReturnLocatorIds(event, token, productOrgId)
    const { qtyOnHand, returnQtyOnHand } = sumSellableQty(storages, returnLocatorIds)

    return {
      status: 200,
      productId: Number(product?.m_product_id || product?.id),
      jfsku: product?.jfsku || jfsku || product?.jsfsku || null,
      merchantSku: product?.SKU || merchantSku || null,
      qtyOnHand,        // excludes return-locator stock
      returnQtyOnHand   // stock on return-only locators (informational)
    }
  } catch (err: any) {
    const data = errorHandlingHelper(err?.data ?? err, err?.data ?? err)
    return { status: Number(data?.status || 500), message: data?.message || 'Failed to get qty on hand' }
  }
}

export default defineEventHandler(async (event) => {
  try {
    return await handleFunc(event)
  } catch (err: any) {
    try {
      const authToken = await refreshTokenHelper(event)
      return await handleFunc(event, authToken)
    } catch (error: any) {
      const data = errorHandlingHelper(err?.data ?? err, error?.data ?? error)
      if([401, 402, 403, 407].includes(Number(data.status))) {
        //@ts-ignore
        setCookie(event, 'user', null)
      }
      return data
    }
  }
})
