import { createError } from 'h3'
import refreshTokenHelper from './refreshTokenHelper'
import forceLogoutHelper from './forceLogoutHelper'
import errorHandlingHelper from './errorHandlingHelper'

// Standard route wrapper around the per-route handleFunc.
//
// Retries with a refreshed token ONLY on 401/403 (expired/invalid token) —
// any other error is re-thrown untouched. The copy-pasted try/catch it
// replaces retried on ANY error, so a routine business 404 (e.g. an unknown
// barcode scan) triggered a full token refresh (up to 6 iDempiere calls + a
// sqlite write) before failing again with the same 404.
//
// On a genuine auth failure that the refreshed retry also cannot recover,
// this logs the user out (forceLogoutHelper) and throws — never returns an
// error object as an HTTP 200 body.
const withAuthRetry = async (
  event: any,
  handleFunc: (event: any, authToken?: any) => Promise<any>
) => {
  try {
    return await handleFunc(event)
  } catch (err: any) {
    const status = Number(err?.statusCode ?? err?.status ?? err?.response?.status)
    if (status !== 401 && status !== 403) throw err
    try {
      const authToken: any = await refreshTokenHelper(event)
      return await handleFunc(event, authToken)
    } catch (error: any) {
      const data = errorHandlingHelper(err?.data ?? err, error?.data ?? error)
      forceLogoutHelper(event, data)
      throw createError({
        statusCode: error?.statusCode || err?.statusCode || 500,
        statusMessage: error?.statusMessage || err?.statusMessage || 'Request failed',
        data
      })
    }
  }
}

export default withAuthRetry
