<cfsetting showdebugoutput="false">
<cfsetting enablecfoutputonly="true">
<cfcontent type="application/json; charset=utf-8" reset="true">

<cfscript>
// Customer calls server to their table
// Input: BusinessID, ServicePointID, OrderID (optional), Message (optional)
// Output: { OK: true, TASK_ID: ... }

function apiAbort(required struct payload) {
    writeOutput(serializeJSON(payload));
    abort;
}

function readJsonBody() {
    var raw = getHttpRequestData().content;
    if (isNull(raw)) raw = "";
    if (!len(trim(raw))) return {};
    try {
        var data = deserializeJSON(raw);
        if (isStruct(data)) return data;
    } catch (any e) {}
    return {};
}

try {
    data = readJsonBody();
    businessID = val(structKeyExists(data, "BusinessID") ? data.BusinessID : 0);
    servicePointID = val(structKeyExists(data, "ServicePointID") ? data.ServicePointID : 0);
    orderID = val(structKeyExists(data, "OrderID") ? data.OrderID : 0);
    message = trim(structKeyExists(data, "Message") ? data.Message : "");
    userID = val(structKeyExists(data, "UserID") ? data.UserID : 0);
    taskTypeID = val(structKeyExists(data, "TaskTypeID") ? data.TaskTypeID : 0);

    if (businessID == 0) {
        apiAbort({ "OK": false, "ERROR": "missing_params", "MESSAGE": "BusinessID is required" });
    }

    if (servicePointID == 0) {
        apiAbort({ "OK": false, "ERROR": "missing_params", "MESSAGE": "ServicePointID is required" });
    }

    // Get service point info (table name)
    spQuery = queryExecute("
        SELECT Name FROM ServicePoints WHERE ID = :spID
    ", { spID: { value: servicePointID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });

    tableName = spQuery.recordCount ? spQuery.Name : "Table ##" & servicePointID;

    // Get user name if available
    userName = "";
    if (userID > 0) {
        userQuery = queryExecute("
            SELECT FirstName FROM Users WHERE ID = :userID
        ", { userID: { value: userID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
        if (userQuery.recordCount && len(trim(userQuery.FirstName))) {
            userName = userQuery.FirstName;
        }
    }

    // Get task type info if TaskTypeID provided (name + category)
    taskTypeName = "";
    taskTypeCategoryID = 0;
    if (taskTypeID > 0) {
        typeQuery = queryExecute("
            SELECT Name, TaskCategoryID FROM tt_TaskTypes WHERE tt_TaskTypeID = :typeID
        ", { typeID: { value: taskTypeID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
        if (typeQuery.recordCount) {
            if (len(trim(typeQuery.Name))) {
                taskTypeName = typeQuery.Name;
            }
            if (!isNull(typeQuery.TaskCategoryID) && isNumeric(typeQuery.TaskCategoryID) && typeQuery.TaskCategoryID > 0) {
                taskTypeCategoryID = typeQuery.TaskCategoryID;
            }
        }
    }

    // Create task title and details - use task type name if available
    if (len(taskTypeName)) {
        taskTitle = taskTypeName & " - " & tableName;
    } else {
        taskTitle = "Service Request - " & tableName;
    }

    taskDetails = "";
    if (len(taskTypeName)) {
        taskDetails &= "Task: " & taskTypeName & chr(10);
    }
    if (len(userName)) {
        taskDetails &= "Customer: " & userName & chr(10);
    }
    taskDetails &= "Location: " & tableName & chr(10);
    if (len(message)) {
        taskDetails &= "Request: " & message;
    } else {
        taskDetails &= "Customer is requesting assistance";
    }

    // Determine category: use task type's category if set, otherwise fallback to "Service" category
    categoryID = 0;

    if (taskTypeCategoryID > 0) {
        // Use the task type's assigned category
        categoryID = taskTypeCategoryID;
    } else {
        // Fallback: look up or create a "Service" category for this business
        catQuery = queryExecute("
            SELECT ID FROM TaskCategories
            WHERE BusinessID = :businessID AND Name = 'Service'
            LIMIT 1
        ", { businessID: { value: businessID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });

        if (catQuery.recordCount == 0) {
            // Create the category
            queryExecute("
                INSERT INTO TaskCategories (BusinessID, Name, Color)
                VALUES (:businessID, 'Service', '##FF9800')
            ", { businessID: { value: businessID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });

            catResult = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" });
            categoryID = catResult.newID;
        } else {
            categoryID = catQuery.ID;
        }
    }

    // Insert task
    queryExecute("
        INSERT INTO Tasks (
            BusinessID,
            CategoryID,
            OrderID,
            TaskTypeID,
            Title,
            Details,
            ClaimedByUserID,
            CreatedOn
        ) VALUES (
            :businessID,
            :categoryID,
            :orderID,
            :taskTypeID,
            :title,
            :details,
            0,
            NOW()
        )
    ", {
        businessID: { value: businessID, cfsqltype: "cf_sql_integer" },
        categoryID: { value: categoryID, cfsqltype: "cf_sql_integer" },
        orderID: { value: orderID > 0 ? orderID : javaCast("null", ""), cfsqltype: "cf_sql_integer", null: orderID == 0 },
        taskTypeID: { value: taskTypeID > 0 ? taskTypeID : javaCast("null", ""), cfsqltype: "cf_sql_integer", null: taskTypeID == 0 },
        title: { value: taskTitle, cfsqltype: "cf_sql_varchar" },
        details: { value: taskDetails, cfsqltype: "cf_sql_varchar" }
    }, { datasource: "payfrit" });

    // Get the new task ID
    result = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" });
    taskID = result.newID;

    apiAbort({
        "OK": true,
        "TASK_ID": taskID,
        "MESSAGE": "Server has been notified"
    });

} catch (any e) {
    apiAbort({
        "OK": false,
        "ERROR": "server_error",
        "MESSAGE": e.message
    });
}
</cfscript>
