<cfscript>
// Save menu data from the builder UI
// Input: BusinessID, Menu (JSON structure)
// Output: { OK: true }
//
// Supports both old schema (Categories table) and new unified schema (Categories as Items)

response = { "OK": false };

try {
    requestBody = toString(getHttpRequestData().content);
    if (!len(requestBody)) {
        throw("Request body is required");
    }

    jsonData = deserializeJSON(requestBody);
    businessID = val(jsonData.BusinessID ?: 0);
    menu = jsonData.Menu ?: {};

    if (businessID == 0) {
        throw("BusinessID is required");
    }

    if (!structKeyExists(menu, "categories") || !isArray(menu.categories)) {
        throw("Menu categories are required");
    }

    // Check if new schema is active (ItemBusinessID column exists and has data)
    newSchemaActive = false;
    try {
        qCheck = queryExecute("
            SELECT COUNT(*) as cnt FROM Items
            WHERE ItemBusinessID = :businessID AND ItemBusinessID > 0
        ", { businessID: businessID });
        newSchemaActive = (qCheck.cnt > 0);
    } catch (any e) {
        newSchemaActive = false;
    }

    // Process each category
    for (cat in menu.categories) {
        categoryID = 0;
        categoryDbId = structKeyExists(cat, "dbId") ? val(cat.dbId) : 0;

        if (newSchemaActive) {
            // NEW SCHEMA: Categories are Items with ParentID=0 and Template=0
            if (categoryDbId > 0) {
                categoryID = categoryDbId;
                // Update existing category Item
                queryExecute("
                    UPDATE Items
                    SET ItemName = :name,
                        ItemSortOrder = :sortOrder
                    WHERE ItemID = :categoryID
                      AND ItemBusinessID = :businessID
                ", {
                    categoryID: categoryID,
                    businessID: businessID,
                    name: cat.name,
                    sortOrder: val(cat.sortOrder ?: 0)
                });
            } else {
                // Insert new category as Item
                queryExecute("
                    INSERT INTO Items (
                        ItemBusinessID, ItemName, ItemDescription,
                        ItemParentItemID, ItemPrice, ItemIsActive,
                        ItemSortOrder, ItemIsModifierTemplate, ItemAddedOn
                    ) VALUES (
                        :businessID, :name, '',
                        0, 0, 1,
                        :sortOrder, 0, NOW()
                    )
                ", {
                    businessID: businessID,
                    name: cat.name,
                    sortOrder: val(cat.sortOrder ?: 0)
                });

                result = queryExecute("SELECT LAST_INSERT_ID() as newID");
                categoryID = result.newID;
            }
        } else {
            // OLD SCHEMA: Use Categories table
            if (categoryDbId > 0) {
                categoryID = categoryDbId;
                queryExecute("
                    UPDATE Categories
                    SET CategoryName = :name,
                        CategoryDescription = :description,
                        CategorySortOrder = :sortOrder
                    WHERE CategoryID = :categoryID
                ", {
                    categoryID: categoryID,
                    name: cat.name,
                    description: cat.description ?: "",
                    sortOrder: val(cat.sortOrder ?: 0)
                });
            } else {
                queryExecute("
                    INSERT INTO Categories (CategoryBusinessID, CategoryName, CategoryDescription, CategorySortOrder)
                    VALUES (:businessID, :name, :description, :sortOrder)
                ", {
                    businessID: businessID,
                    name: cat.name,
                    description: cat.description ?: "",
                    sortOrder: val(cat.sortOrder ?: 0)
                });

                result = queryExecute("SELECT LAST_INSERT_ID() as newID");
                categoryID = result.newID;
            }
        }

        // Process items in this category
        if (structKeyExists(cat, "items") && isArray(cat.items)) {
            for (item in cat.items) {
                itemID = 0;
                itemDbId = structKeyExists(item, "dbId") ? val(item.dbId) : 0;

                if (itemDbId > 0) {
                    itemID = itemDbId;

                    if (newSchemaActive) {
                        // Update existing item - set parent to category Item
                        queryExecute("
                            UPDATE Items
                            SET ItemName = :name,
                                ItemDescription = :description,
                                ItemPrice = :price,
                                ItemParentItemID = :categoryID,
                                ItemSortOrder = :sortOrder
                            WHERE ItemID = :itemID
                        ", {
                            itemID: itemID,
                            name: item.name,
                            description: item.description ?: "",
                            price: val(item.price ?: 0),
                            categoryID: categoryID,
                            sortOrder: val(item.sortOrder ?: 0)
                        });
                    } else {
                        // Update existing item - old schema with CategoryID
                        queryExecute("
                            UPDATE Items
                            SET ItemName = :name,
                                ItemDescription = :description,
                                ItemPrice = :price,
                                ItemCategoryID = :categoryID,
                                ItemSortOrder = :sortOrder
                            WHERE ItemID = :itemID
                        ", {
                            itemID: itemID,
                            name: item.name,
                            description: item.description ?: "",
                            price: val(item.price ?: 0),
                            categoryID: categoryID,
                            sortOrder: val(item.sortOrder ?: 0)
                        });
                    }
                } else {
                    // Insert new item
                    if (newSchemaActive) {
                        queryExecute("
                            INSERT INTO Items (
                                ItemBusinessID, ItemParentItemID, ItemName, ItemDescription,
                                ItemPrice, ItemSortOrder, ItemIsActive, ItemAddedOn
                            ) VALUES (
                                :businessID, :categoryID, :name, :description,
                                :price, :sortOrder, 1, NOW()
                            )
                        ", {
                            businessID: businessID,
                            categoryID: categoryID,
                            name: item.name,
                            description: item.description ?: "",
                            price: val(item.price ?: 0),
                            sortOrder: val(item.sortOrder ?: 0)
                        });
                    } else {
                        queryExecute("
                            INSERT INTO Items (
                                ItemBusinessID, ItemCategoryID, ItemName, ItemDescription,
                                ItemPrice, ItemSortOrder, ItemIsActive, ItemParentItemID
                            ) VALUES (
                                :businessID, :categoryID, :name, :description,
                                :price, :sortOrder, 1, 0
                            )
                        ", {
                            businessID: businessID,
                            categoryID: categoryID,
                            name: item.name,
                            description: item.description ?: "",
                            price: val(item.price ?: 0),
                            sortOrder: val(item.sortOrder ?: 0)
                        });
                    }

                    result = queryExecute("SELECT LAST_INSERT_ID() as newID");
                    itemID = result.newID;
                }

                // Handle template links for modifiers
                if (structKeyExists(item, "modifiers") && isArray(item.modifiers)) {
                    // Clear existing template links for this item
                    queryExecute("
                        DELETE FROM ItemTemplateLinks WHERE ItemID = :itemID
                    ", { itemID: itemID });

                    modSortOrder = 0;
                    for (mod in item.modifiers) {
                        modDbId = structKeyExists(mod, "dbId") ? val(mod.dbId) : 0;

                        // Get selection rules (for modifier groups)
                        requiresSelection = (structKeyExists(mod, "requiresSelection") && mod.requiresSelection) ? 1 : 0;
                        maxSelections = structKeyExists(mod, "maxSelections") ? val(mod.maxSelections) : 0;

                        // Check if this is a template reference
                        if (structKeyExists(mod, "isTemplate") && mod.isTemplate && modDbId > 0) {
                            // Create template link
                            queryExecute("
                                INSERT INTO ItemTemplateLinks (ItemID, TemplateItemID, SortOrder)
                                VALUES (:itemID, :templateID, :sortOrder)
                                ON DUPLICATE KEY UPDATE SortOrder = :sortOrder
                            ", {
                                itemID: itemID,
                                templateID: modDbId,
                                sortOrder: modSortOrder
                            });

                            // Also update the template's selection rules
                            queryExecute("
                                UPDATE Items
                                SET ItemRequiresChildSelection = :requiresSelection,
                                    ItemMaxNumSelectionReq = :maxSelections
                                WHERE ItemID = :modID
                            ", {
                                modID: modDbId,
                                requiresSelection: requiresSelection,
                                maxSelections: maxSelections
                            });
                        } else if (modDbId > 0) {
                            // Update existing direct modifier
                            queryExecute("
                                UPDATE Items
                                SET ItemName = :name,
                                    ItemPrice = :price,
                                    ItemIsCheckedByDefault = :isDefault,
                                    ItemSortOrder = :sortOrder,
                                    ItemRequiresChildSelection = :requiresSelection,
                                    ItemMaxNumSelectionReq = :maxSelections
                                WHERE ItemID = :modID
                            ", {
                                modID: modDbId,
                                name: mod.name,
                                price: val(mod.price ?: 0),
                                isDefault: (mod.isDefault ?: false) ? 1 : 0,
                                sortOrder: modSortOrder,
                                requiresSelection: requiresSelection,
                                maxSelections: maxSelections
                            });
                        } else {
                            // Insert new direct modifier (non-template)
                            queryExecute("
                                INSERT INTO Items (
                                    ItemBusinessID, ItemParentItemID, ItemName, ItemPrice,
                                    ItemIsCheckedByDefault, ItemSortOrder, ItemIsActive, ItemAddedOn,
                                    ItemRequiresChildSelection, ItemMaxNumSelectionReq
                                ) VALUES (
                                    :businessID, :parentID, :name, :price,
                                    :isDefault, :sortOrder, 1, NOW(),
                                    :requiresSelection, :maxSelections
                                )
                            ", {
                                businessID: businessID,
                                parentID: itemID,
                                name: mod.name,
                                price: val(mod.price ?: 0),
                                isDefault: (mod.isDefault ?: false) ? 1 : 0,
                                sortOrder: modSortOrder,
                                requiresSelection: requiresSelection,
                                maxSelections: maxSelections
                            });
                        }
                        modSortOrder++;
                    }
                }
            }
        }
    }

    response = { "OK": true, "SCHEMA": newSchemaActive ? "unified" : "legacy" };

} catch (any e) {
    response = {
        "OK": false,
        "ERROR": e.message,
        "DETAIL": e.detail ?: "",
        "TYPE": e.type ?: ""
    };
}

cfheader(name="Content-Type", value="application/json");
writeOutput(serializeJSON(response));
</cfscript>
