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

<cffunction name="apiAbort" access="public" returntype="void" output="true">
  <cfargument name="payload" type="struct" required="true">
  <cfcontent type="application/json; charset=utf-8">
  <cfoutput>#serializeJSON(arguments.payload)#</cfoutput>
  <cfabort>
</cffunction>

<cffunction name="readJsonBody" access="public" returntype="struct" output="false">
  <cfset var raw = getHttpRequestData().content>
  <cfif isNull(raw) OR len(trim(raw)) EQ 0>
    <cfreturn {}>
  </cfif>
  <cftry>
    <cfset var data = deserializeJSON(raw)>
    <cfif isStruct(data)>
      <cfreturn data>
    <cfelse>
      <cfreturn {}>
    </cfif>
    <cfcatch>
      <cfreturn {}>
    </cfcatch>
  </cftry>
</cffunction>

<cfset data = readJsonBody()>
<cfset BusinessID = val( structKeyExists(data,"BusinessID") ? data.BusinessID : 0 )>
<cfset ServicePointID = val( structKeyExists(data,"ServicePointID") ? data.ServicePointID : 0 )>
<cfset StationID = val( structKeyExists(data,"StationID") ? data.StationID : 0 )>

<cfif BusinessID LTE 0>
  <cfset apiAbort({ "OK": false, "ERROR": "missing_params", "MESSAGE": "BusinessID is required.", "DETAIL": "" })>
</cfif>

<cftry>
  <!--- Build WHERE clause for filtering --->
  <cfset whereClauses = ["o.BusinessID = ?"]>
  <cfset params = [ { value = BusinessID, cfsqltype = "cf_sql_integer" } ]>

  <!--- Filter by service point if provided --->
  <cfif ServicePointID GT 0>
    <cfset arrayAppend(whereClauses, "o.ServicePointID = ?")>
    <cfset arrayAppend(params, { value = ServicePointID, cfsqltype = "cf_sql_integer" })>
  </cfif>

  <!--- Only show submitted orders (StatusID >= 1) --->
  <cfset arrayAppend(whereClauses, "o.StatusID >= 1")>

  <!--- Don't show completed orders (assuming StatusID 4 is completed) --->
  <cfset arrayAppend(whereClauses, "o.StatusID < 4")>

  <cfset whereSQL = arrayToList(whereClauses, " AND ")>

  <!--- If filtering by station, only get orders that have items for that station --->
  <cfif StationID GT 0>
    <cfset stationParams = duplicate(params)>
    <cfset arrayAppend(stationParams, { value = StationID, cfsqltype = "cf_sql_integer" })>
    <cfset qOrders = queryExecute("
      SELECT DISTINCT
        o.ID,
        o.UUID,
        o.UserID,
        o.BusinessID,
        o.OrderTypeID,
        o.StatusID,
        o.ServicePointID,
        o.Remarks,
        o.SubmittedOn,
        o.LastEditedOn,
        sp.Name AS Name,
        u.FirstName,
        u.LastName
      FROM Orders o
      LEFT JOIN ServicePoints sp ON sp.ID = o.ServicePointID
      LEFT JOIN Users u ON u.ID = o.UserID
      INNER JOIN OrderLineItems oli ON oli.OrderID = o.ID
      INNER JOIN Items i ON i.ID = oli.ItemID
      WHERE #whereSQL#
        AND i.StationID = ?
        AND oli.IsDeleted = b'0'
      ORDER BY o.SubmittedOn ASC, o.ID ASC
    ", stationParams, { datasource = "payfrit" })>
  <cfelse>
    <cfset qOrders = queryExecute("
      SELECT
        o.ID,
        o.UUID,
        o.UserID,
        o.BusinessID,
        o.OrderTypeID,
        o.StatusID,
        o.ServicePointID,
        o.Remarks,
        o.SubmittedOn,
        o.LastEditedOn,
        sp.Name AS Name,
        u.FirstName,
        u.LastName
      FROM Orders o
      LEFT JOIN ServicePoints sp ON sp.ID = o.ServicePointID
      LEFT JOIN Users u ON u.ID = o.UserID
      WHERE #whereSQL#
      ORDER BY o.SubmittedOn ASC, o.ID ASC
    ", params, { datasource = "payfrit" })>
  </cfif>

  <cfset orders = []>

  <cfloop query="qOrders">
    <!--- Get line items for this order --->
    <!--- If filtering by station, only show items for that station (plus modifiers) --->
    <cfif StationID GT 0>
      <cfset qLineItems = queryExecute("
        SELECT
          oli.ID,
          oli.ParentOrderLineItemID,
          oli.ItemID,
          oli.Price,
          oli.Quantity,
          oli.Remark,
          oli.IsDeleted,
          i.Name,
          i.ParentItemID,
          i.IsCheckedByDefault,
          i.StationID,
          parent.Name AS ItemParentName
        FROM OrderLineItems oli
        INNER JOIN Items i ON i.ID = oli.ItemID
        LEFT JOIN Items parent ON parent.ID = i.ParentItemID
        WHERE oli.OrderID = ?
          AND oli.IsDeleted = b'0'
          AND (i.StationID = ? OR i.StationID = 0 OR i.StationID IS NULL OR oli.ParentOrderLineItemID > 0)
        ORDER BY oli.ID
      ", [
        { value = qOrders.ID, cfsqltype = "cf_sql_integer" },
        { value = StationID, cfsqltype = "cf_sql_integer" }
      ], { datasource = "payfrit" })>
    <cfelse>
      <cfset qLineItems = queryExecute("
        SELECT
          oli.ID,
          oli.ParentOrderLineItemID,
          oli.ItemID,
          oli.Price,
          oli.Quantity,
          oli.Remark,
          oli.IsDeleted,
          i.Name,
          i.ParentItemID,
          i.IsCheckedByDefault,
          i.StationID,
          parent.Name AS ItemParentName
        FROM OrderLineItems oli
        INNER JOIN Items i ON i.ID = oli.ItemID
        LEFT JOIN Items parent ON parent.ID = i.ParentItemID
        WHERE oli.OrderID = ?
          AND oli.IsDeleted = b'0'
        ORDER BY oli.ID
      ", [ { value = qOrders.ID, cfsqltype = "cf_sql_integer" } ], { datasource = "payfrit" })>
    </cfif>

    <cfset lineItems = []>
    <cfloop query="qLineItems">
      <cfset arrayAppend(lineItems, {
        "OrderLineItemID": qLineItems.ID,
        "ParentOrderLineItemID": qLineItems.ParentOrderLineItemID,
        "ItemID": qLineItems.ID,
        "Price": qLineItems.Price,
        "Quantity": qLineItems.Quantity,
        "Remark": qLineItems.Remark,
        "Name": qLineItems.Name,
        "ParentItemID": qLineItems.ParentItemID,
        "ItemParentName": qLineItems.ItemParentName,
        "IsCheckedByDefault": qLineItems.IsCheckedByDefault,
        "StationID": qLineItems.StationID
      })>
    </cfloop>

    <!--- Determine order type name --->
    <cfset orderTypeName = "">
    <cfswitch expression="#qOrders.OrderTypeID#">
      <cfcase value="1"><cfset orderTypeName = "Dine-In"></cfcase>
      <cfcase value="2"><cfset orderTypeName = "Takeaway"></cfcase>
      <cfcase value="3"><cfset orderTypeName = "Delivery"></cfcase>
      <cfdefaultcase><cfset orderTypeName = ""></cfdefaultcase>
    </cfswitch>

    <cfset arrayAppend(orders, {
      "OrderID": qOrders.ID,
      "UUID": qOrders.UUID,
      "UserID": qOrders.UserID,
      "BusinessID": qOrders.BusinessID,
      "OrderTypeID": qOrders.OrderTypeID,
      "OrderTypeName": orderTypeName,
      "StatusID": qOrders.StatusID,
      "ServicePointID": qOrders.ServicePointID,
      "Remarks": qOrders.Remarks,
      "SubmittedOn": qOrders.SubmittedOn,
      "LastEditedOn": qOrders.LastEditedOn,
      "Name": qOrders.Name,
      "FirstName": qOrders.FirstName,
      "LastName": qOrders.LastName,
      "LineItems": lineItems
    })>
  </cfloop>

  <cfset apiAbort({
    "OK": true,
    "ERROR": "",
    "ORDERS": orders,
    "STATION_FILTER": StationID
  })>

  <cfcatch>
    <cfset apiAbort({
      "OK": false,
      "ERROR": "server_error",
      "MESSAGE": "DB error loading orders for KDS",
      "DETAIL": cfcatch.message
    })>
  </cfcatch>
</cftry>