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

// Full per-product detail for the Qty-Fix tool.
//  - `locators`          : the MOVABLE on-hand stock (qty > 0, excluding return
//                          locators) — these are the lines that get zeroed/added.
//  - `returnQtyOnHand`   : return-locator stock, reported only (never moved).
//  - `availableLocators` : every active locator in the org (default first) so the
//                          target side can pick where the qty should land.
const handleFunc = async (event: any, authToken: any = null) => {
  const token = authToken ?? await getTokenHelper(event)
  const query = getQuery(event)
  const productId = query?.product_id as string
  const orgId = query?.org_id as string

  if (!productId || !orgId) {
    return { status: 400, message: 'product_id and org_id are required' }
  }

  const prodRes: any = await fetchHelper(event, `models/m_product/${productId}`, 'GET', token, null)
  if (!prodRes || !prodRes.id) {
    return { status: 404, message: 'Product not found' }
  }

  const returnLocatorIds = await getReturnLocatorIds(event, token, orgId)

  const storagesRes: any = await fetchHelper(
    event,
    `models/m_storage?$filter=${string.urlEncode('M_Product_ID eq ' + productId)}&$expand=M_Locator_ID&$top=1000`,
    'GET',
    token,
    null
  )
  const storages = Array.isArray(storagesRes?.records) ? storagesRes.records : []

  const locatorMap: Record<string, any> = {}
  let qtyOnHand = 0
  let returnQtyOnHand = 0

  for (const s of storages) {
    const qty = Number(s?.QtyOnHand ?? 0)
    if (!qty) continue
    const loc = s?.M_Locator_ID || {}
    const locId = loc?.id ?? loc
    const isReturn = locId !== undefined && locId !== null && returnLocatorIds.has(Number(locId))
    if (isReturn) {
      // Return stock is reported but NOT part of the movable on-hand list.
      returnQtyOnHand += qty
      continue
    }
    qtyOnHand += qty
    const whId = loc?.M_Warehouse_ID?.id ?? loc?.M_Warehouse_ID ?? null
    const code = (loc?.X || loc?.Y || loc?.Z)
      ? [loc.X, loc.Y, loc.Z].filter(Boolean).join(' - ')
      : (loc?.Value || loc?.identifier || String(locId))
    if (!locatorMap[locId]) {
      locatorMap[locId] = { locatorId: locId, code, warehouseId: whId, qtyOnHand: 0 }
    }
    locatorMap[locId].qtyOnHand += qty
  }

  const locators = Object.values(locatorMap).sort((a: any, b: any) => b.qtyOnHand - a.qtyOnHand)

  const availRes: any = await fetchHelper(
    event,
    `models/m_locator?$filter=${string.urlEncode('AD_Org_ID eq ' + orgId + ' AND IsActive eq true')}&$orderby=${string.urlEncode('IsDefault desc, PriorityNo desc')}&$top=5000`,
    'GET',
    token,
    null
  )
  const availableLocators = (availRes?.records || []).map((loc: any) => ({
    id: loc.id,
    code: (loc.X || loc.Y || loc.Z)
      ? [loc.X, loc.Y, loc.Z].filter(Boolean).join(' - ')
      : (loc.Value || loc.identifier || loc.Name || String(loc.id)),
    warehouseId: loc.M_Warehouse_ID?.id ?? loc.M_Warehouse_ID ?? null,
    isDefault: loc.IsDefault === true || loc.IsDefault === 'Y',
    priorityNo: loc.PriorityNo ?? null,
    isReturn: returnLocatorIds.has(Number(loc.id))
  }))

  return {
    status: 200,
    product: {
      id: prodRes.id,
      Name: prodRes.Name,
      Value: prodRes.Value,
      SKU: prodRes.SKU,
      UPC: prodRes.UPC,
      MPN: prodRes.mpn || null,
      isJtlBom: (prodRes.isJtlBom ?? prodRes.IsJtlBom) === true || (prodRes.isJtlBom ?? prodRes.IsJtlBom) === 'Y'
    },
    qtyOnHand,
    returnQtyOnHand,
    locators,
    availableLocators
  }
}

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
})
