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

<cfscript>
// Customer initiates a chat with staff
// Input: BusinessID, ServicePointID, OrderID (optional), Message (optional initial message)
// Output: { OK: true, TaskID: ... }

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);
    initialMessage = trim(structKeyExists(data, "Message") ? data.Message : "");
    userID = val(structKeyExists(data, "UserID") ? data.UserID : 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 ServicePointName FROM ServicePoints WHERE ServicePointID = :spID
    ", { spID: { value: servicePointID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });

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

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

    // Create task title
    taskTitle = "Chat - " & tableName;
    if (len(userName)) {
        taskTitle = "Chat - " & userName & " (" & tableName & ")";
    }

    taskDetails = "Customer initiated chat";
    if (len(initialMessage)) {
        taskDetails = initialMessage;
    }

    // Look up or create a "Chat" category for this business
    catQuery = queryExecute("
        SELECT TaskCategoryID FROM TaskCategories
        WHERE TaskCategoryBusinessID = :businessID AND TaskCategoryName = 'Chat'
        LIMIT 1
    ", { businessID: { value: businessID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });

    if (catQuery.recordCount == 0) {
        // Create the category (blue color for chat)
        queryExecute("
            INSERT INTO TaskCategories (TaskCategoryBusinessID, TaskCategoryName, TaskCategoryColor)
            VALUES (:businessID, 'Chat', '##2196F3')
        ", { 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.TaskCategoryID;
    }

    // Insert task with TaskTypeID = 2 (Chat)
    queryExecute("
        INSERT INTO Tasks (
            TaskBusinessID,
            TaskCategoryID,
            TaskOrderID,
            TaskTypeID,
            TaskTitle,
            TaskDetails,
            TaskClaimedByUserID,
            TaskSourceType,
            TaskSourceID,
            TaskAddedOn
        ) VALUES (
            :businessID,
            :categoryID,
            :orderID,
            2,
            :title,
            :details,
            0,
            'servicepoint',
            :servicePointID,
            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 },
        title: { value: taskTitle, cfsqltype: "cf_sql_varchar" },
        details: { value: taskDetails, cfsqltype: "cf_sql_varchar" },
        servicePointID: { value: servicePointID, cfsqltype: "cf_sql_integer" }
    }, { datasource: "payfrit" });

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

    // If there's an initial message, save it
    if (len(initialMessage) && userID > 0) {
        queryExecute("
            INSERT INTO ChatMessages (TaskID, SenderUserID, SenderType, MessageText)
            VALUES (:taskID, :userID, 'customer', :message)
        ", {
            taskID: { value: taskID, cfsqltype: "cf_sql_integer" },
            userID: { value: userID, cfsqltype: "cf_sql_integer" },
            message: { value: initialMessage, cfsqltype: "cf_sql_varchar" }
        }, { datasource: "payfrit" });
    }

    apiAbort({
        "OK": true,
        "TaskID": taskID,
        "MESSAGE": "Chat started"
    });

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