<cfsetting showdebugoutput="false">
<cfsetting enablecfoutputonly="true">

<cfcontent type="application/json; charset=utf-8" reset="true">
<cfheader name="Cache-Control" value="no-store">

<cfscript>
function apiAbort(obj) {
  writeOutput(serializeJSON(obj));
  abort;
}

function readJsonBody() {
  raw = toString(getHttpRequestData().content);
  if (isNull(raw) || len(trim(raw)) EQ 0) return {};
  try {
    parsed = deserializeJSON(raw);
  } catch(any e) {
    apiAbort({ OK=false, ERROR="bad_json", MESSAGE="Invalid JSON body" });
  }
  if (!isStruct(parsed)) return {};
  return parsed;
}

data = readJsonBody();

if (!structKeyExists(data, "BeaconID") || !isNumeric(data.BeaconID) || int(data.BeaconID) LTE 0) {
  apiAbort({ OK=false, ERROR="missing_beacon_id", MESSAGE="BeaconID is required" });
}

beaconId = int(data.BeaconID);
</cfscript>

<!--- Get beacon info first --->
<cfquery name="qBeacon" datasource="payfrit">
  SELECT ID, Name, UUID, BusinessID
  FROM Beacons
  WHERE ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#beaconId#">
    AND IsActive = 1
  LIMIT 1
</cfquery>

<cfif qBeacon.recordCount EQ 0>
  <cfoutput>#serializeJSON({ OK=false, ERROR="not_found", MESSAGE="Beacon not found or inactive" })#</cfoutput>
  <cfabort>
</cfif>

<!--- Get all businesses that have assignments to this beacon (via service points or join table) --->
<cfquery name="qAssignments" datasource="payfrit">
  SELECT
    sp.BusinessID AS BusinessID,
    sp.ID AS ServicePointID,
    biz.Name AS BusinessName,
    biz.ParentBusinessID AS BusinessParentBusinessID,
    sp.Name AS ServicePointName
  FROM ServicePoints sp
  INNER JOIN Businesses biz ON biz.ID = sp.BusinessID
  WHERE sp.BeaconID = <cfqueryparam cfsqltype="cf_sql_integer" value="#beaconId#">
    AND sp.IsActive = 1

  UNION

  SELECT
    lt.BusinessID,
    0 AS ServicePointID,
    biz.Name AS BusinessName,
    biz.ParentBusinessID AS BusinessParentBusinessID,
    '' AS ServicePointName
  FROM lt_BeaconsID_BusinessesID lt
  INNER JOIN Businesses biz ON biz.ID = lt.BusinessID
  WHERE lt.BeaconID = <cfqueryparam cfsqltype="cf_sql_integer" value="#beaconId#">
    AND lt.BusinessID NOT IN (
      SELECT sp2.BusinessID FROM ServicePoints sp2
      WHERE sp2.BeaconID = <cfqueryparam cfsqltype="cf_sql_integer" value="#beaconId#"> AND sp2.IsActive = 1
    )

  ORDER BY BusinessParentBusinessID IS NULL DESC, BusinessName ASC
</cfquery>

<!--- Check if any assigned business is a parent (has children) --->
<cfset parentBusinessID = 0>
<cfloop query="qAssignments">
  <!--- Check if this business has children --->
  <cfquery name="qChildren" datasource="payfrit">
    SELECT COUNT(*) as cnt FROM Businesses
    WHERE ParentBusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#qAssignments.BusinessID#">
  </cfquery>
  <cfif qChildren.cnt GT 0>
    <cfset parentBusinessID = qAssignments.BusinessID>
    <cfbreak>
  </cfif>
</cfloop>

<!--- Build response with array of businesses --->
<cfset businesses = []>

<!--- If beacon is assigned to a parent, return the child businesses instead --->
<cfif parentBusinessID GT 0>
  <!--- Get parent business info for header image --->
  <cfquery name="qParent" datasource="payfrit">
    SELECT Name AS BusinessName, HeaderImageExtension AS BusinessHeaderImageExtension
    FROM Businesses
    WHERE ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#parentBusinessID#">
  </cfquery>
  <cfquery name="qChildBusinesses" datasource="payfrit">
    SELECT
      ID,
      Name AS BusinessName,
      ParentBusinessID AS BusinessParentBusinessID,
      HeaderImageExtension AS BusinessHeaderImageExtension
    FROM Businesses
    WHERE ParentBusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#parentBusinessID#">
    ORDER BY Name ASC
  </cfquery>
  <cfloop query="qChildBusinesses">
    <cfset arrayAppend(businesses, {
      "BusinessID" = qChildBusinesses.ID,
      "Name" = qChildBusinesses.BusinessName,
      "ServicePointID" = qAssignments.ServicePointID,
      "ServicePointName" = qAssignments.ServicePointName,
      "IsParent" = false,
      "ParentBusinessID" = parentBusinessID
    })>
  </cfloop>
<cfelse>
  <!--- Normal case: return directly assigned businesses --->
  <cfloop query="qAssignments">
    <cfset arrayAppend(businesses, {
      "BusinessID" = qAssignments.BusinessID,
      "Name" = qAssignments.BusinessName,
      "ServicePointID" = qAssignments.ServicePointID,
      "ServicePointName" = qAssignments.ServicePointName,
      "IsParent" = isNull(qAssignments.ParentBusinessID) OR qAssignments.ParentBusinessID EQ 0
    })>
  </cfloop>
</cfif>

<cfset response = {
  "OK" = true,
  "ERROR" = "",
  "BEACON" = {
    "BeaconID" = qBeacon.ID,
    "Name" = qBeacon.Name,
    "UUID" = qBeacon.UUID
  },
  "BUSINESSES" = businesses,
  "BUSINESS" = arrayLen(businesses) GT 0 ? businesses[1] : {},
  "SERVICEPOINT" = arrayLen(businesses) GT 0 ? {
    "ServicePointID" = businesses[1].ServicePointID,
    "Name" = businesses[1].ServicePointName,
    "IsActive" = true
  } : {}
}>

<!--- Add parent info if this is a parent-child scenario --->
<cfif parentBusinessID GT 0>
  <cfset response["PARENT"] = {
    "BusinessID" = parentBusinessID,
    "Name" = qParent.BusinessName,
    "HeaderImageExtension" = len(trim(qParent.BusinessHeaderImageExtension)) ? qParent.BusinessHeaderImageExtension : ""
  }>
</cfif>

<cfscript>try{logPerf(0);}catch(any e){}</cfscript>
<cfoutput>#serializeJSON(response)#</cfoutput>
