import getTokenHelper from "../../../utils/getTokenHelper"
import refreshTokenHelper from "../../../utils/refreshTokenHelper"
import fetchHelper from "../../../utils/fetchHelper"

/**
 * Resolves the UI-restriction flags on the logged-in org's linked C_BPartner:
 *  - isHideQty          → hide stock quantities everywhere
 *  - isDisallowExport   → hide/disable all grid export buttons (CSV/Excel/PDF)
 * Returns { hideQty, disallowExport, orgId, bpartnerId } — plus resolved:false
 * when the check itself failed, so the client can fall back to a role-based
 * default instead of treating an outage as "show everything".
 *
 * Same pattern as materials/products/image-permission.get.ts:
 *  - A limited customer role ('c') is denied/filtered on the admin tables
 *    ad_user / ad_org / c_bpartner via REST, so read with the iDempiere
 *    service token (system, role-independent).
 *  - The org cookie is not a reliable source for limited users, so resolve
 *    the org from the user record (ad_user.AD_Org_ID), falling back to the
 *    org cookie when the user record has no usable org.
 */
const truthy = (v: any) =>
  v === true || v === 'Y' || v === 'y' || v === 'true' || v === 'Yes' || v === 1 || v === '1'

// iDempiere OData response casing varies by model, so match the flag keys
// case-insensitively and accept every truthy representation it may return.
const readFlag = (bpartner: any, lowerKey: string): boolean => {
  if (!bpartner || typeof bpartner !== 'object') return false
  for (const k of Object.keys(bpartner)) {
    if (k.toLowerCase() === lowerKey) return truthy(bpartner[k])
  }
  return false
}

const handleFunc = async (event: any, authToken: string | null = null) => {
  const config = useRuntimeConfig()
  // Service token sees every org/column regardless of the caller's role; the
  // limited 'c' token cannot read these admin tables. Fall back to the user
  // token only if the env var is unset.
  const serviceToken = (config.api as any)?.idempieretoken
  const token = serviceToken || authToken || await getTokenHelper(event)
  const userId = getCookie(event, 'logship_user_id')
  const cookieOrgId = getCookie(event, 'logship_organization_id')

  // 1. Resolve the user's own org (reliable for limited roles); fall back to cookie.
  let orgId: any = cookieOrgId
  if (userId) {
    const userRes: any = await fetchHelper(event, `models/ad_user/${userId}?$select=AD_Org_ID`, 'GET', token, null)
    const userOrgId = userRes?.AD_Org_ID?.id
    if (userOrgId && Number(userOrgId) > 0) {
      orgId = userOrgId
    }
  }

  if (!orgId || Number(orgId) <= 0) {
    return { hideQty: false, disallowExport: false, orgId: orgId ? Number(orgId) : null, bpartnerId: null }
  }

  // 2. Pull the org's linked C_BPartner inline via $expand.
  const orgRes: any = await fetchHelper(event, `models/ad_org/${orgId}?$expand=C_BPartner_ID`, 'GET', token, null)
  const bpartner: any = orgRes?.C_BPartner_ID ?? null

  return {
    hideQty: readFlag(bpartner, 'ishideqty'),
    disallowExport: readFlag(bpartner, 'isdisallowexport'),
    orgId: Number(orgId),
    bpartnerId: bpartner?.id ?? null
  }
}

export default defineEventHandler(async (event) => {
  let data: any = { hideQty: false, disallowExport: false, resolved: false }

  try {
    data = await handleFunc(event)
  } catch (err: any) {
    try {
      const authToken: any = await refreshTokenHelper(event)
      data = await handleFunc(event, authToken)
    } catch (error: any) {
      // Check failed — signal it so the client keeps its role-based default
      // (staff unrestricted, limited customers restricted) instead of flashing.
      data = { hideQty: false, disallowExport: false, resolved: false }
    }
  }

  return data
})
