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

// Ownership guard for limited roles (FrontendMenu === 'c').
//
// The write below uses the SuperUser service token because c_location is a
// SHARED table (org 0) that a limited role's own token cannot write. To make
// sure a limited user can only rewrite addresses they actually own — not an
// arbitrary c_location id — we first confirm the caller can SEE a
// c_bpartner_location that references this c_location, using the caller's OWN
// org-scoped token. iDempiere only returns records in orgs the role can access,
// so a visible reference proves legitimate ownership. Fail-closed on any error.
const callerOwnsLocation = async (event: any, locationId: any) => {
  const url = `models/c_bpartner_location?$filter=C_Location_ID eq ${locationId}&$select=C_Location_ID,AD_Org_ID&$top=1`

  const check = async (token: any) => {
    const res: any = await fetchHelper(event, url, 'GET', token, null)
    return (res?.records?.length ?? 0) > 0
  }

  try {
    return await check(await getTokenHelper(event))
  } catch {
    try {
      return await check(await refreshTokenHelper(event))
    } catch {
      return false
    }
  }
}

const handleFunc = async (event: any) => {
  let data: any = {}
  const config = useRuntimeConfig()
  const serviceToken = config.api.idempieretoken
  const body = await readBody(event)

  if (!serviceToken) {
    return { status: 500, message: 'Service token not configured' }
  }

  if (!body.id) {
    return { status: 400, message: 'Missing location id' }
  }

  // Only limited roles are gated; staff roles keep unrestricted service-token access.
  const roleCookie = getCookie(event, 'logship_role')
  let menuType: string = 'Menu'
  try {
    const role = roleCookie ? JSON.parse(roleCookie) : null
    menuType = role?.FrontendMenu?.id || role?.FrontendMenu || 'Menu'
  } catch {}

  if (menuType === 'c' && !(await callerOwnsLocation(event, body.id))) {
    return { status: 403, message: 'Access denied for record with id: ' + body.id }
  }

  let requestBody: any = {
    address1: body.address1,
    address2: body.address2,
    city: body.city,
    postal: body.postal,
    tableName: 'C_Location'
  }

  // Add country if provided
  if (body.countryId) {
    requestBody.C_Country_ID = {
      id: body.countryId,
      tableName: 'C_Country'
    }
  }

  const res: any = await $fetch(`${config.api.url}/models/c_location/${body.id}`, {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json',
      Accept: 'application/json',
      Authorization: 'Bearer ' + serviceToken
    },
    body: requestBody
  })

  if(res) {
    data = res
    data['status'] = 200
    data['message'] = ''
  }

  return data
}

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

  try {
    data = await handleFunc(event)
  } catch(err: any) {
    data = errorHandlingHelper(err?.data ?? err, err)
  }

  return data
})
